feat(copilot): Add folder management tools to CoPilot - #12290
Conversation
Introduce new response types for folder creation, listing, updating, moving, deletion, and agent relocation. This expands the copilot's capabilities for managing file structures.
Introduce a new module `manage_folders.py` containing tools for creating, listing, updating, moving, and deleting folders within the user's library. Also includes a tool to move agents into folders.
Adds tools for creating, listing, updating, moving, and deleting folders, as well as moving agents to folders. This enhances Copilot's ability to manage agent organization.
Allows associating newly created library agents with a specific folder, primarily for the main agent graph. This ensures better organization of user-created agents.
Allow agents to be saved into specific folders within the user's library by introducing a `folder_id` parameter to the agent creation and saving functions.
Allow specifying an optional folder ID when customizing an agent, enabling agents to be saved into specific folders within the user's library.
Assert that `user_id` is not `None` in the `_execute` methods of the folder management tools (`CreateFolderTool`, `ListFoldersTool`, `UpdateFolderTool`, `MoveFolderTool`, `DeleteFolderTool`, `MoveAgentsToFolderTool`). This ensures that these tools are always called with an authenticated user ID, as they are marked with `requires_auth=True`.
Adds a new React component `FolderTool` to the Copilot UI. This component displays the output of folder-related operations performed by the AI agent, including creating, listing, updating, moving, and deleting folders, as well as moving agents between folders. The component uses helper functions to parse and interpret different output types from the backend and displays the information in an accessible and organized manner using accordions, cards, and tree views. Error states and streaming states are also handled visually.
Integrate the FolderTool into the MessagePartRenderer component to handle various folder-related actions within the chat interface.
Updates the FolderTool component to use simpler conditional rendering and refactors helper functions for better readability. Also includes new output types in the OpenAPI spec.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a folder management system: backend library DB folder support and RPC endpoints, new copilot folder tools, agent save/update folder propagation, frontend FolderTool UI and file-tree components, and DatabaseManager exposure for folder operations. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend as Frontend UI
participant Copilot as Copilot Tool
participant DM as DatabaseManager
participant DB as Library DB
User->>Frontend: Request "create folder" or "list folders"
Frontend->>Copilot: Invoke folder tool (create/list/etc.)
Copilot->>DM: RPC call (create_folder / list_folders / bulk_move_agents_to_folder)
DM->>DB: Forward folder operation
DB->>DB: Persist/read folder & agent records, build tree or update agents
DB-->>DM: Return result payload (FolderTreeInfo / FolderInfo / op result)
DM-->>Copilot: Return formatted response
Copilot-->>Frontend: Tool response (FolderListResponse / FolderCreatedResponse / ...)
Frontend->>Frontend: Render FolderTool UI (tree, cards, messages)
Frontend-->>User: Display result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
🔍 PR Overlap DetectionThis check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early. 🔴 Merge Conflicts DetectedThe following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.
🟢 Low Risk — File Overlap OnlyThese PRs touch the same files but different sections (click to expand)
Summary: 2 conflict(s), 0 medium risk, 4 low risk (out of 6 PRs with file overlap) Auto-generated on push. Ignores: |
Use asyncio.gather for parallel creation of library agents, improving performance when creating multiple agents.
The `manage_folders.py` tool now utilizes the `DatabaseManager` for all folder-related database operations. This centralizes database access and improves code organization. Additionally, imports related to database access have been consolidated within `db_manager.py` and `db_accessors.py` for better maintainability.
This commit introduces a new file tree component for visualizing folder structures. It includes the following changes: - Refactored backend folder management tools to import `library_db` from `backend.data.db_accessors`. - Updated frontend `components.json` to include `iconLibrary: "radix"` and a new registry for `@magicui`. - Integrated the new file tree component into the `FolderTool` for copilot functionality. - Added Storybook stories and the `file-tree.tsx
Include an option to list agents within folders and folder trees when browsing. This enhances the folder management tool by providing more context about folder contents.
…to-copilot-agent-creation-tools
Fetch all pages of agents instead of only the first page when retrieving folder agent summaries.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
autogpt_platform/backend/backend/api/features/library/db.py (1)
1510-1517:⚠️ Potential issue | 🟡 Minor
get_folder_agent_summaries()still returns only the first page.Line 1514 still calls
list_library_agents()with its default pagination, so folders with 51+ agents produce a truncatedagentspayload while the folder count stays higher. Page through the full result set here, or add a non-paginated helper before building summaries.Possible fix
async def get_folder_agent_summaries( user_id: str, folder_id: str ) -> list[dict[str, str | None]]: """Get a lightweight list of agents in a folder (id, name, description).""" - resp = await list_library_agents(user_id=user_id, folder_id=folder_id) + agents: list[library_model.LibraryAgent] = [] + page = 1 + while True: + resp = await list_library_agents( + user_id=user_id, + folder_id=folder_id, + page=page, + page_size=200, + ) + agents.extend(resp.agents) + if page >= resp.pagination.total_pages: + break + page += 1 + return [ - {"id": a.id, "name": a.name, "description": a.description} for a in resp.agents + {"id": a.id, "name": a.name, "description": a.description} for a in agents ]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/backend/backend/api/features/library/db.py` around lines 1510 - 1517, get_folder_agent_summaries currently calls list_library_agents once and only returns the first page; update get_folder_agent_summaries to page through the full result set (or call a non-paginated helper) and accumulate all resp.agents before mapping to summaries. Specifically, loop calling list_library_agents (using its pagination token/page params from the response) until no more pages, extend a local agents list with each resp.agents, then build and return [{"id": a.id, "name": a.name, "description": a.description} for a in all_agents]; modify get_folder_agent_summaries to use this accumulation logic and preserve types/return shape.autogpt_platform/backend/backend/copilot/tools/manage_folders.py (1)
530-548:⚠️ Potential issue | 🟠 MajorBuild the success payload from the agents that actually moved.
This handler always echoes the requested
agent_ids, butbulk_move_agents_to_folder()only updates the subset the user owns and can access. A partial move currently looks like a full success.Possible fix
try: - await library_db().bulk_move_agents_to_folder( + moved_agents = await library_db().bulk_move_agents_to_folder( agent_ids=agent_ids, folder_id=folder_id, user_id=user_id, ) @@ return AgentsMovedToFolderResponse( - message=f"Moved {len(agent_ids)} agent(s) to {'the folder' if folder_id else 'root level'}.", - agent_ids=agent_ids, + message=f"Moved {len(moved_agents)} agent(s) to {'the folder' if folder_id else 'root level'}.", + agent_ids=[agent.id for agent in moved_agents], folder_id=folder_id, - count=len(agent_ids), + count=len(moved_agents), session_id=session_id, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@autogpt_platform/backend/backend/copilot/tools/manage_folders.py` around lines 530 - 548, The handler currently returns the requested agent_ids instead of the actual subset moved; change it to use the result from library_db().bulk_move_agents_to_folder (e.g., a returned list like moved_agent_ids) to build the success payload: set AgentsMovedToFolderResponse.agent_ids, count, folder_id and message from moved_agent_ids (and treat empty moved_agent_ids as a zero-count/partial-move response); update the code around the try block that calls bulk_move_agents_to_folder to capture and use the returned moved IDs rather than echoing the input agent_ids.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@autogpt_platform/backend/backend/copilot/tools/manage_folders.py`:
- Around line 236-249: The current flow (include_agents check in the folder
listing path that calls collect_tree_ids and then
library_db().get_folder_agents_map) never includes agents with folderId == NULL
(root), so root-level agents are omitted; update the handler to, when
include_agents is true, separately fetch root agents (e.g., a call that queries
agents where folderId IS NULL) in addition to calling
get_folder_agents_map(all_ids), convert them via
_to_agent_summaries_map/_to_agent_summaries, and then include them in the
FolderListResponse either as a dedicated field (e.g., root_agents) or by
injecting a synthetic root node into tree before mapping with _tree_to_info;
ensure delete_folder behavior that moves agents to root is covered by this
additional fetch.
---
Duplicate comments:
In `@autogpt_platform/backend/backend/api/features/library/db.py`:
- Around line 1510-1517: get_folder_agent_summaries currently calls
list_library_agents once and only returns the first page; update
get_folder_agent_summaries to page through the full result set (or call a
non-paginated helper) and accumulate all resp.agents before mapping to
summaries. Specifically, loop calling list_library_agents (using its pagination
token/page params from the response) until no more pages, extend a local agents
list with each resp.agents, then build and return [{"id": a.id, "name": a.name,
"description": a.description} for a in all_agents]; modify
get_folder_agent_summaries to use this accumulation logic and preserve
types/return shape.
In `@autogpt_platform/backend/backend/copilot/tools/manage_folders.py`:
- Around line 530-548: The handler currently returns the requested agent_ids
instead of the actual subset moved; change it to use the result from
library_db().bulk_move_agents_to_folder (e.g., a returned list like
moved_agent_ids) to build the success payload: set
AgentsMovedToFolderResponse.agent_ids, count, folder_id and message from
moved_agent_ids (and treat empty moved_agent_ids as a zero-count/partial-move
response); update the code around the try block that calls
bulk_move_agents_to_folder to capture and use the returned moved IDs rather than
echoing the input agent_ids.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cb3f8a62-12bf-479a-a049-d75b645ef476
📒 Files selected for processing (2)
autogpt_platform/backend/backend/api/features/library/db.pyautogpt_platform/backend/backend/copilot/tools/manage_folders.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: types
- GitHub Check: test (3.11)
- GitHub Check: test (3.13)
- GitHub Check: test (3.12)
- GitHub Check: end-to-end tests
- GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (6)
autogpt_platform/backend/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development
Files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/**/*.{py,txt}
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use
poetry runprefix for all Python commands, including testing, linting, formatting, and migrations
Files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/backend/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
Use Prisma ORM for database operations in PostgreSQL with pgvector for embeddings
Files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Format Python code with
poetry run format
Files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/backend/api/features/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Update routes in '/backend/backend/api/features/' and add/update Pydantic models in the same directory for API development
When modifying API routes, update corresponding Pydantic models in the same directory and write tests alongside the route file
Files:
autogpt_platform/backend/backend/api/features/library/db.py
autogpt_platform/backend/backend/api/**/*.py
📄 CodeRabbit inference engine (autogpt_platform/backend/CLAUDE.md)
autogpt_platform/backend/backend/api/**/*.py: Use FastAPI for building REST and WebSocket endpoints
Use JWT-based authentication with Supabase integration
Files:
autogpt_platform/backend/backend/api/features/library/db.py
🧠 Learnings (6)
📚 Learning: 2026-03-05T00:13:30.465Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/backend/backend/api/features/store/db.py:1206-1221
Timestamp: 2026-03-05T00:13:30.465Z
Learning: In `autogpt_platform/backend/backend/api/features/store/db.py`, the `_approve_sub_agent` helper intentionally does NOT set `ActiveVersion` on the `StoreListing` when auto-approving sub-agents. Sub-agents are created with `isAvailable=False` (see `_create_sub_agent_version_data`), so they do not appear in public store views and do not need an active version connected. Do not flag the absence of `ActiveVersion` assignment in this function as a bug.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-03-04T08:04:35.881Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12273
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:216-220
Timestamp: 2026-03-04T08:04:35.881Z
Learning: In the AutoGPT Copilot backend, ensure that SVG images are not treated as vision image types by excluding 'image/svg+xml' from INLINEABLE_MIME_TYPES and MULTIMODAL_TYPES in tool_adapter.py; the Claude API supports PNG, JPEG, GIF, and WebP for vision. SVGs (XML text) should be handled via the text path instead, not the vision path.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.py
📚 Learning: 2026-03-04T12:19:39.243Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12279
File: autogpt_platform/backend/backend/copilot/tools/base.py:184-188
Timestamp: 2026-03-04T12:19:39.243Z
Learning: In autogpt_platform/backend/backend/copilot/tools/, ensure that anonymous users always pass user_id=None to tool execution methods. The anon_ prefix (e.g., anon_123) is used only for PostHog/analytics distinct_id and must not be used as an actual user_id. Use a simple truthiness check on user_id (e.g., if user_id: ... else: ... or a dedicated is_authenticated flag) to distinguish anonymous from authenticated users, and review all tool execution call sites within this directory to prevent accidentally forwarding an anon_ user_id to tools.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.
Applied to files:
autogpt_platform/backend/backend/copilot/tools/manage_folders.pyautogpt_platform/backend/backend/api/features/library/db.py
📚 Learning: 2026-02-04T16:49:42.490Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-02-04T16:49:42.490Z
Learning: Applies to autogpt_platform/backend/backend/data/**/*.py : All data access in backend requires user ID checks; verify this for any 'data/*.py' changes
Applied to files:
autogpt_platform/backend/backend/api/features/library/db.py
🔇 Additional comments (1)
autogpt_platform/backend/backend/api/features/library/db.py (1)
425-428: Ownership check onfolder_idlooks good.Validating the folder before writing closes the FK-only existence gap and prevents cross-user nesting during agent creation.
The response was returning the original requested `agent_ids` instead of the actual `moved_ids`, which could differ if some agents failed to move or were already in the destination folder.
…to-copilot-agent-creation-tools
|
Fixed all the issues in this comment. ✅ - #12290 (review) |
The previous `folderId` assignment was invalid Prisma syntax. Use proper relationship connection pattern with conditional spread to only set the folder when both `folder_id` exists and we're creating a new graph entry.
Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface. <img width="823" height="356" alt="Screenshot 2026-03-05 at 5 26 30 PM" src="https://github.com/user-attachments/assets/4c55f926-1e71-488f-9eb6-fca87c4ab01b" /> <img width="797" height="150" alt="Screenshot 2026-03-05 at 5 28 40 PM" src="https://github.com/user-attachments/assets/5c9c6f8b-57ac-4122-b17d-b9f091bb7c4e" /> <img width="763" height="196" alt="Screenshot 2026-03-05 at 5 28 36 PM" src="https://github.com/user-attachments/assets/d1b22b5d-921d-44ac-90e8-a5820bb3146d" /> <img width="756" height="199" alt="Screenshot 2026-03-05 at 5 30 17 PM" src="https://github.com/user-attachments/assets/40a59748-f42e-4521-bae0-cc786918a9b5" /> ### Changes **Backend -- 6 new CoPilot tools** (`manage_folders.py`): - `create_folder` -- Create folders with optional parent, icon, and color - `list_folders` -- List folder tree or children of a specific folder, with optional `include_agents` to show agents inside each folder - `update_folder` -- Rename or change icon/color - `move_folder` -- Reparent a folder or move to root - `delete_folder` -- Soft-delete (agents moved to root, not deleted) - `move_agents_to_folder` -- Bulk-move agents into a folder or back to root **Backend -- DatabaseManager RPC registration**: - Registered all 7 folder DB functions (`create_folder`, `list_folders`, `get_folder_tree`, `update_folder`, `move_folder`, `delete_folder`, `bulk_move_agents_to_folder`) in `DatabaseManager` and `DatabaseManagerAsyncClient` so they work via RPC in the CoPilotExecutor process - `manage_folders.py` uses `db_accessors.library_db()` pattern (consistent with all other copilot tools) instead of direct Prisma imports **Backend -- folder_id threading**: - `create_agent` and `customize_agent` tools accept optional `folder_id` to save agents directly into a folder - `save_agent_to_library` -> `create_graph_in_library` -> `create_library_agent` pipeline passes `folder_id` through - `create_library_agent` refactored from `asyncio.gather` to sequential loop to support conditional `folderId` assignment on the main graph only (not sub-graphs) **Backend -- system prompt and models**: - Added folder tool descriptions and usage guidance to Otto's system prompt - Added `FolderAgentSummary` model for lightweight agent info in folder listings - Added 6 `ResponseType` enum values and corresponding Pydantic response models (`FolderInfo`, `FolderTreeInfo`, `FolderCreatedResponse`, etc.) **Frontend -- FolderTool UI component**: - `FolderTool.tsx` -- Renders folder operations in chat using the `file-tree` molecule component for tree view, with `FileIcon` for agents and `FolderIcon` for folders (both `text-neutral-600`) - `helpers.ts` -- Type guards, output parsing, animation text helpers, and `FolderAgentSummary` type - `MessagePartRenderer.tsx` -- Routes 6 folder tool types to `FolderTool` component - Flat folder list view shows agents inside `FolderCard` when `include_agents` is set **Frontend -- file-tree molecule**: - Fixed 3 pre-existing lint errors in `file-tree.tsx` (unused `ref`, `handleSelect`, `className` params) - Updated tree indicator line color from `bg-neutral-100` to `bg-neutral-400` for visibility - Added `file-tree.stories.tsx` with 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicator - Added `ui/scroll-area.tsx` (dependency of file-tree, was missing from non-legacy ui folder) ### Checklist #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Create a folder via copilot chat ("create a folder called Marketing") - [x] List folders ("show me my folders") - [x] List folders with agents ("show me my folders and the agents in them") - [x] Update folder name/icon/color ("rename Marketing folder to Sales") - [x] Move folder to a different parent ("move Sales into the Projects folder") - [x] Delete a folder and verify agents move to root - [x] Move agents into a folder ("put my newsletter agent in the Marketing folder") - [x] Create agent with folder_id ("create a scraper agent and save it in my Tools folder") - [x] Verify FolderTool UI renders loading, success, error, and empty states correctly - [x] Verify folder tree renders nested folders with file-tree component - [x] Verify agents appear as FileIcon nodes in tree view when include_agents is true - [x] Verify file-tree storybook stories render correctly
Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface. <img width="823" height="356" alt="Screenshot 2026-03-05 at 5 26 30 PM" src="https://github.com/user-attachments/assets/4c55f926-1e71-488f-9eb6-fca87c4ab01b" /> <img width="797" height="150" alt="Screenshot 2026-03-05 at 5 28 40 PM" src="https://github.com/user-attachments/assets/5c9c6f8b-57ac-4122-b17d-b9f091bb7c4e" /> <img width="763" height="196" alt="Screenshot 2026-03-05 at 5 28 36 PM" src="https://github.com/user-attachments/assets/d1b22b5d-921d-44ac-90e8-a5820bb3146d" /> <img width="756" height="199" alt="Screenshot 2026-03-05 at 5 30 17 PM" src="https://github.com/user-attachments/assets/40a59748-f42e-4521-bae0-cc786918a9b5" /> ### Changes **Backend -- 6 new CoPilot tools** (`manage_folders.py`): - `create_folder` -- Create folders with optional parent, icon, and color - `list_folders` -- List folder tree or children of a specific folder, with optional `include_agents` to show agents inside each folder - `update_folder` -- Rename or change icon/color - `move_folder` -- Reparent a folder or move to root - `delete_folder` -- Soft-delete (agents moved to root, not deleted) - `move_agents_to_folder` -- Bulk-move agents into a folder or back to root **Backend -- DatabaseManager RPC registration**: - Registered all 7 folder DB functions (`create_folder`, `list_folders`, `get_folder_tree`, `update_folder`, `move_folder`, `delete_folder`, `bulk_move_agents_to_folder`) in `DatabaseManager` and `DatabaseManagerAsyncClient` so they work via RPC in the CoPilotExecutor process - `manage_folders.py` uses `db_accessors.library_db()` pattern (consistent with all other copilot tools) instead of direct Prisma imports **Backend -- folder_id threading**: - `create_agent` and `customize_agent` tools accept optional `folder_id` to save agents directly into a folder - `save_agent_to_library` -> `create_graph_in_library` -> `create_library_agent` pipeline passes `folder_id` through - `create_library_agent` refactored from `asyncio.gather` to sequential loop to support conditional `folderId` assignment on the main graph only (not sub-graphs) **Backend -- system prompt and models**: - Added folder tool descriptions and usage guidance to Otto's system prompt - Added `FolderAgentSummary` model for lightweight agent info in folder listings - Added 6 `ResponseType` enum values and corresponding Pydantic response models (`FolderInfo`, `FolderTreeInfo`, `FolderCreatedResponse`, etc.) **Frontend -- FolderTool UI component**: - `FolderTool.tsx` -- Renders folder operations in chat using the `file-tree` molecule component for tree view, with `FileIcon` for agents and `FolderIcon` for folders (both `text-neutral-600`) - `helpers.ts` -- Type guards, output parsing, animation text helpers, and `FolderAgentSummary` type - `MessagePartRenderer.tsx` -- Routes 6 folder tool types to `FolderTool` component - Flat folder list view shows agents inside `FolderCard` when `include_agents` is set **Frontend -- file-tree molecule**: - Fixed 3 pre-existing lint errors in `file-tree.tsx` (unused `ref`, `handleSelect`, `className` params) - Updated tree indicator line color from `bg-neutral-100` to `bg-neutral-400` for visibility - Added `file-tree.stories.tsx` with 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicator - Added `ui/scroll-area.tsx` (dependency of file-tree, was missing from non-legacy ui folder) ### Checklist #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Create a folder via copilot chat ("create a folder called Marketing") - [x] List folders ("show me my folders") - [x] List folders with agents ("show me my folders and the agents in them") - [x] Update folder name/icon/color ("rename Marketing folder to Sales") - [x] Move folder to a different parent ("move Sales into the Projects folder") - [x] Delete a folder and verify agents move to root - [x] Move agents into a folder ("put my newsletter agent in the Marketing folder") - [x] Create agent with folder_id ("create a scraper agent and save it in my Tools folder") - [x] Verify FolderTool UI renders loading, success, error, and empty states correctly - [x] Verify folder tree renders nested folders with file-tree component - [x] Verify agents appear as FileIcon nodes in tree view when include_agents is true - [x] Verify file-tree storybook stories render correctly
Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface. <img width="823" height="356" alt="Screenshot 2026-03-05 at 5 26 30 PM" src="https://github.com/user-attachments/assets/4c55f926-1e71-488f-9eb6-fca87c4ab01b" /> <img width="797" height="150" alt="Screenshot 2026-03-05 at 5 28 40 PM" src="https://github.com/user-attachments/assets/5c9c6f8b-57ac-4122-b17d-b9f091bb7c4e" /> <img width="763" height="196" alt="Screenshot 2026-03-05 at 5 28 36 PM" src="https://github.com/user-attachments/assets/d1b22b5d-921d-44ac-90e8-a5820bb3146d" /> <img width="756" height="199" alt="Screenshot 2026-03-05 at 5 30 17 PM" src="https://github.com/user-attachments/assets/40a59748-f42e-4521-bae0-cc786918a9b5" /> ### Changes **Backend -- 6 new CoPilot tools** (`manage_folders.py`): - `create_folder` -- Create folders with optional parent, icon, and color - `list_folders` -- List folder tree or children of a specific folder, with optional `include_agents` to show agents inside each folder - `update_folder` -- Rename or change icon/color - `move_folder` -- Reparent a folder or move to root - `delete_folder` -- Soft-delete (agents moved to root, not deleted) - `move_agents_to_folder` -- Bulk-move agents into a folder or back to root **Backend -- DatabaseManager RPC registration**: - Registered all 7 folder DB functions (`create_folder`, `list_folders`, `get_folder_tree`, `update_folder`, `move_folder`, `delete_folder`, `bulk_move_agents_to_folder`) in `DatabaseManager` and `DatabaseManagerAsyncClient` so they work via RPC in the CoPilotExecutor process - `manage_folders.py` uses `db_accessors.library_db()` pattern (consistent with all other copilot tools) instead of direct Prisma imports **Backend -- folder_id threading**: - `create_agent` and `customize_agent` tools accept optional `folder_id` to save agents directly into a folder - `save_agent_to_library` -> `create_graph_in_library` -> `create_library_agent` pipeline passes `folder_id` through - `create_library_agent` refactored from `asyncio.gather` to sequential loop to support conditional `folderId` assignment on the main graph only (not sub-graphs) **Backend -- system prompt and models**: - Added folder tool descriptions and usage guidance to Otto's system prompt - Added `FolderAgentSummary` model for lightweight agent info in folder listings - Added 6 `ResponseType` enum values and corresponding Pydantic response models (`FolderInfo`, `FolderTreeInfo`, `FolderCreatedResponse`, etc.) **Frontend -- FolderTool UI component**: - `FolderTool.tsx` -- Renders folder operations in chat using the `file-tree` molecule component for tree view, with `FileIcon` for agents and `FolderIcon` for folders (both `text-neutral-600`) - `helpers.ts` -- Type guards, output parsing, animation text helpers, and `FolderAgentSummary` type - `MessagePartRenderer.tsx` -- Routes 6 folder tool types to `FolderTool` component - Flat folder list view shows agents inside `FolderCard` when `include_agents` is set **Frontend -- file-tree molecule**: - Fixed 3 pre-existing lint errors in `file-tree.tsx` (unused `ref`, `handleSelect`, `className` params) - Updated tree indicator line color from `bg-neutral-100` to `bg-neutral-400` for visibility - Added `file-tree.stories.tsx` with 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicator - Added `ui/scroll-area.tsx` (dependency of file-tree, was missing from non-legacy ui folder) ### Checklist #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Create a folder via copilot chat ("create a folder called Marketing") - [x] List folders ("show me my folders") - [x] List folders with agents ("show me my folders and the agents in them") - [x] Update folder name/icon/color ("rename Marketing folder to Sales") - [x] Move folder to a different parent ("move Sales into the Projects folder") - [x] Delete a folder and verify agents move to root - [x] Move agents into a folder ("put my newsletter agent in the Marketing folder") - [x] Create agent with folder_id ("create a scraper agent and save it in my Tools folder") - [x] Verify FolderTool UI renders loading, success, error, and empty states correctly - [x] Verify folder tree renders nested folders with file-tree component - [x] Verify agents appear as FileIcon nodes in tree view when include_agents is true - [x] Verify file-tree storybook stories render correctly
…avitas#12290) Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface. <img width="823" height="356" alt="Screenshot 2026-03-05 at 5 26 30 PM" src="https://github.com/user-attachments/assets/4c55f926-1e71-488f-9eb6-fca87c4ab01b" /> <img width="797" height="150" alt="Screenshot 2026-03-05 at 5 28 40 PM" src="https://github.com/user-attachments/assets/5c9c6f8b-57ac-4122-b17d-b9f091bb7c4e" /> <img width="763" height="196" alt="Screenshot 2026-03-05 at 5 28 36 PM" src="https://github.com/user-attachments/assets/d1b22b5d-921d-44ac-90e8-a5820bb3146d" /> <img width="756" height="199" alt="Screenshot 2026-03-05 at 5 30 17 PM" src="https://github.com/user-attachments/assets/40a59748-f42e-4521-bae0-cc786918a9b5" /> ### Changes **Backend -- 6 new CoPilot tools** (`manage_folders.py`): - `create_folder` -- Create folders with optional parent, icon, and color - `list_folders` -- List folder tree or children of a specific folder, with optional `include_agents` to show agents inside each folder - `update_folder` -- Rename or change icon/color - `move_folder` -- Reparent a folder or move to root - `delete_folder` -- Soft-delete (agents moved to root, not deleted) - `move_agents_to_folder` -- Bulk-move agents into a folder or back to root **Backend -- DatabaseManager RPC registration**: - Registered all 7 folder DB functions (`create_folder`, `list_folders`, `get_folder_tree`, `update_folder`, `move_folder`, `delete_folder`, `bulk_move_agents_to_folder`) in `DatabaseManager` and `DatabaseManagerAsyncClient` so they work via RPC in the CoPilotExecutor process - `manage_folders.py` uses `db_accessors.library_db()` pattern (consistent with all other copilot tools) instead of direct Prisma imports **Backend -- folder_id threading**: - `create_agent` and `customize_agent` tools accept optional `folder_id` to save agents directly into a folder - `save_agent_to_library` -> `create_graph_in_library` -> `create_library_agent` pipeline passes `folder_id` through - `create_library_agent` refactored from `asyncio.gather` to sequential loop to support conditional `folderId` assignment on the main graph only (not sub-graphs) **Backend -- system prompt and models**: - Added folder tool descriptions and usage guidance to Otto's system prompt - Added `FolderAgentSummary` model for lightweight agent info in folder listings - Added 6 `ResponseType` enum values and corresponding Pydantic response models (`FolderInfo`, `FolderTreeInfo`, `FolderCreatedResponse`, etc.) **Frontend -- FolderTool UI component**: - `FolderTool.tsx` -- Renders folder operations in chat using the `file-tree` molecule component for tree view, with `FileIcon` for agents and `FolderIcon` for folders (both `text-neutral-600`) - `helpers.ts` -- Type guards, output parsing, animation text helpers, and `FolderAgentSummary` type - `MessagePartRenderer.tsx` -- Routes 6 folder tool types to `FolderTool` component - Flat folder list view shows agents inside `FolderCard` when `include_agents` is set **Frontend -- file-tree molecule**: - Fixed 3 pre-existing lint errors in `file-tree.tsx` (unused `ref`, `handleSelect`, `className` params) - Updated tree indicator line color from `bg-neutral-100` to `bg-neutral-400` for visibility - Added `file-tree.stories.tsx` with 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicator - Added `ui/scroll-area.tsx` (dependency of file-tree, was missing from non-legacy ui folder) ### Checklist #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Create a folder via copilot chat ("create a folder called Marketing") - [x] List folders ("show me my folders") - [x] List folders with agents ("show me my folders and the agents in them") - [x] Update folder name/icon/color ("rename Marketing folder to Sales") - [x] Move folder to a different parent ("move Sales into the Projects folder") - [x] Delete a folder and verify agents move to root - [x] Move agents into a folder ("put my newsletter agent in the Marketing folder") - [x] Create agent with folder_id ("create a scraper agent and save it in my Tools folder") - [x] Verify FolderTool UI renders loading, success, error, and empty states correctly - [x] Verify folder tree renders nested folders with file-tree component - [x] Verify agents appear as FileIcon nodes in tree view when include_agents is true - [x] Verify file-tree storybook stories render correctly
…avitas#12290) Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface. <img width="823" height="356" alt="Screenshot 2026-03-05 at 5 26 30 PM" src="https://github.com/user-attachments/assets/4c55f926-1e71-488f-9eb6-fca87c4ab01b" /> <img width="797" height="150" alt="Screenshot 2026-03-05 at 5 28 40 PM" src="https://github.com/user-attachments/assets/5c9c6f8b-57ac-4122-b17d-b9f091bb7c4e" /> <img width="763" height="196" alt="Screenshot 2026-03-05 at 5 28 36 PM" src="https://github.com/user-attachments/assets/d1b22b5d-921d-44ac-90e8-a5820bb3146d" /> <img width="756" height="199" alt="Screenshot 2026-03-05 at 5 30 17 PM" src="https://github.com/user-attachments/assets/40a59748-f42e-4521-bae0-cc786918a9b5" /> ### Changes **Backend -- 6 new CoPilot tools** (`manage_folders.py`): - `create_folder` -- Create folders with optional parent, icon, and color - `list_folders` -- List folder tree or children of a specific folder, with optional `include_agents` to show agents inside each folder - `update_folder` -- Rename or change icon/color - `move_folder` -- Reparent a folder or move to root - `delete_folder` -- Soft-delete (agents moved to root, not deleted) - `move_agents_to_folder` -- Bulk-move agents into a folder or back to root **Backend -- DatabaseManager RPC registration**: - Registered all 7 folder DB functions (`create_folder`, `list_folders`, `get_folder_tree`, `update_folder`, `move_folder`, `delete_folder`, `bulk_move_agents_to_folder`) in `DatabaseManager` and `DatabaseManagerAsyncClient` so they work via RPC in the CoPilotExecutor process - `manage_folders.py` uses `db_accessors.library_db()` pattern (consistent with all other copilot tools) instead of direct Prisma imports **Backend -- folder_id threading**: - `create_agent` and `customize_agent` tools accept optional `folder_id` to save agents directly into a folder - `save_agent_to_library` -> `create_graph_in_library` -> `create_library_agent` pipeline passes `folder_id` through - `create_library_agent` refactored from `asyncio.gather` to sequential loop to support conditional `folderId` assignment on the main graph only (not sub-graphs) **Backend -- system prompt and models**: - Added folder tool descriptions and usage guidance to Otto's system prompt - Added `FolderAgentSummary` model for lightweight agent info in folder listings - Added 6 `ResponseType` enum values and corresponding Pydantic response models (`FolderInfo`, `FolderTreeInfo`, `FolderCreatedResponse`, etc.) **Frontend -- FolderTool UI component**: - `FolderTool.tsx` -- Renders folder operations in chat using the `file-tree` molecule component for tree view, with `FileIcon` for agents and `FolderIcon` for folders (both `text-neutral-600`) - `helpers.ts` -- Type guards, output parsing, animation text helpers, and `FolderAgentSummary` type - `MessagePartRenderer.tsx` -- Routes 6 folder tool types to `FolderTool` component - Flat folder list view shows agents inside `FolderCard` when `include_agents` is set **Frontend -- file-tree molecule**: - Fixed 3 pre-existing lint errors in `file-tree.tsx` (unused `ref`, `handleSelect`, `className` params) - Updated tree indicator line color from `bg-neutral-100` to `bg-neutral-400` for visibility - Added `file-tree.stories.tsx` with 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicator - Added `ui/scroll-area.tsx` (dependency of file-tree, was missing from non-legacy ui folder) ### Checklist #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Create a folder via copilot chat ("create a folder called Marketing") - [x] List folders ("show me my folders") - [x] List folders with agents ("show me my folders and the agents in them") - [x] Update folder name/icon/color ("rename Marketing folder to Sales") - [x] Move folder to a different parent ("move Sales into the Projects folder") - [x] Delete a folder and verify agents move to root - [x] Move agents into a folder ("put my newsletter agent in the Marketing folder") - [x] Create agent with folder_id ("create a scraper agent and save it in my Tools folder") - [x] Verify FolderTool UI renders loading, success, error, and empty states correctly - [x] Verify folder tree renders nested folders with file-tree component - [x] Verify agents appear as FileIcon nodes in tree view when include_agents is true - [x] Verify file-tree storybook stories render correctly
Adds folder management capabilities to the CoPilot, allowing users to organize agents into folders directly from the chat interface.
Changes
Backend -- 6 new CoPilot tools (
manage_folders.py):create_folder-- Create folders with optional parent, icon, and colorlist_folders-- List folder tree or children of a specific folder, with optionalinclude_agentsto show agents inside each folderupdate_folder-- Rename or change icon/colormove_folder-- Reparent a folder or move to rootdelete_folder-- Soft-delete (agents moved to root, not deleted)move_agents_to_folder-- Bulk-move agents into a folder or back to rootBackend -- DatabaseManager RPC registration:
create_folder,list_folders,get_folder_tree,update_folder,move_folder,delete_folder,bulk_move_agents_to_folder) inDatabaseManagerandDatabaseManagerAsyncClientso they work via RPC in the CoPilotExecutor processmanage_folders.pyusesdb_accessors.library_db()pattern (consistent with all other copilot tools) instead of direct Prisma importsBackend -- folder_id threading:
create_agentandcustomize_agenttools accept optionalfolder_idto save agents directly into a foldersave_agent_to_library->create_graph_in_library->create_library_agentpipeline passesfolder_idthroughcreate_library_agentrefactored fromasyncio.gatherto sequential loop to support conditionalfolderIdassignment on the main graph only (not sub-graphs)Backend -- system prompt and models:
FolderAgentSummarymodel for lightweight agent info in folder listingsResponseTypeenum values and corresponding Pydantic response models (FolderInfo,FolderTreeInfo,FolderCreatedResponse, etc.)Frontend -- FolderTool UI component:
FolderTool.tsx-- Renders folder operations in chat using thefile-treemolecule component for tree view, withFileIconfor agents andFolderIconfor folders (bothtext-neutral-600)helpers.ts-- Type guards, output parsing, animation text helpers, andFolderAgentSummarytypeMessagePartRenderer.tsx-- Routes 6 folder tool types toFolderToolcomponentFolderCardwheninclude_agentsis setFrontend -- file-tree molecule:
file-tree.tsx(unusedref,handleSelect,classNameparams)bg-neutral-100tobg-neutral-400for visibilityfile-tree.stories.tsxwith 5 stories: Default, AllExpanded, FoldersOnly, WithInitialSelection, NoIndicatorui/scroll-area.tsx(dependency of file-tree, was missing from non-legacy ui folder)Checklist
For code changes: