first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Conversation renaming
|
||||
## Summary
|
||||
Warp should let users manually rename the currently selected AI conversation with a `/rename-conversation` slash command. For server-backed conversations, Warp should apply the rename locally immediately, refresh every local surface that displays that title, and asynchronously sync the rename to the server. If server sync fails, Warp should show an error toast and revert that failed local rename.
|
||||
## Problem
|
||||
Auto-generated AI conversation titles can be generic, duplicated, or misleading after a conversation evolves. Users need a small, reliable way to give an active conversation a human-readable name that is reflected everywhere Warp shows that conversation.
|
||||
## Goals / Non-goals
|
||||
Goals:
|
||||
- Add a first-pass `/rename-conversation <title>` command for the currently selected conversation.
|
||||
- Treat the renamed value as the conversation's canonical title, not as a separate display-only alias.
|
||||
- Keep all title-bearing local surfaces in sync immediately after the local rename is accepted.
|
||||
- Revert the local rename if the server rejects or fails to persist it.
|
||||
- Ensure a manually renamed title wins over future generated titles until the user renames the conversation again.
|
||||
- Use the same conversation permission model as existing conversation endpoints for server-side persistence, requiring edit access for rename.
|
||||
Non-goals:
|
||||
- No sidebar, details-panel, command-palette, or inline edit UI in this first pass.
|
||||
- No conversation-id argument or ability to rename historical conversations that are not currently selected.
|
||||
- No reset-to-generated-title behavior in this first pass.
|
||||
## Figma
|
||||
Figma: none provided. This first pass reuses existing slash-command and toast patterns.
|
||||
## Behavior
|
||||
1. When the user has an active AI conversation selected, they can run `/rename-conversation <title>` from the input surfaces that support active-conversation slash commands.
|
||||
2. `/rename-conversation` operates only on the currently selected active conversation. It never renames an arbitrary conversation by id, token, title match, or search result.
|
||||
3. The command requires a title argument. If the user runs `/rename-conversation` with no argument, or with an argument that becomes empty after trimming leading and trailing whitespace, Warp shows an error toast and does not send a server request.
|
||||
4. The title stored for the conversation is the argument after trimming leading and trailing whitespace. Internal repeated whitespace is preserved.
|
||||
5. Titles have a maximum accepted length of 500 Unicode scalar values. If the trimmed title is longer than the limit, Warp shows an error toast and does not send a server request.
|
||||
6. After validation succeeds for a server-backed active conversation, Warp immediately updates the local conversation's canonical title before waiting for the server rename request to complete.
|
||||
7. The local update refreshes every open local surface backed by that title. This includes pane title, tab title, vertical tabs summaries, conversation list/search results, conversation details, and the conversation management panel.
|
||||
8. Warp asynchronously sends the server rename request after applying the local title. The command uses existing non-blocking slash-command behavior while that request is in flight, and the user can continue using Warp.
|
||||
9. On server success, Warp treats the rename as persisted and shows a success toast: `Conversation renamed to <title>`. If the server returns a normalized title different from the locally applied trimmed title, Warp updates the local canonical title to that returned title and refreshes title-bearing surfaces again.
|
||||
10. On server failure, permission denial, or offline/network failure, Warp shows an error toast and reverts the local title to the title that was visible before that rename request was applied.
|
||||
11. If a rename is already in progress for the selected conversation, another `/rename-conversation` request for that conversation is rejected early. Warp shows an error toast, does not change the local title, and does not send another server request.
|
||||
12. If there is no active selected conversation, Warp shows an error toast, does not change any local title, and does not send a server request.
|
||||
13. If the active conversation exists only locally and cannot be mapped to a server conversation yet, Warp shows an error toast that tells the user to send another message and retry. Warp does not change the title in this first pass. If the same conversation later receives a server identity, the user can retry.
|
||||
14. Renaming is allowed while an agent response is in progress as long as the conversation already has a server identity and no rename is already pending for that conversation. If the server accepts the rename while a response is still streaming, the renamed title remains the conversation title after that response finishes.
|
||||
15. A locally accepted title remains sticky across future generated-title writes, follow-ups, auto-resume flows, run completion, cloud reloads, and app restarts unless the server sync for that rename fails and Warp reverts it. Generated title logic must not overwrite the user-facing conversation title while server sync is in flight.
|
||||
16. After a rename succeeds or fails and its in-flight state clears, the user can run `/rename-conversation` again on the same conversation.
|
||||
17. Server-backed surfaces that store or display the same conversation title should converge on the renamed title after the server rename succeeds. This includes conversation metadata surfaces and agent run/task management surfaces associated with the conversation.
|
||||
18. If the same conversation is visible in another client or session, that other client is not required to update in real time, but after refresh, restore, or refetch it should show the renamed title once server sync has succeeded.
|
||||
19. Search and filtering that use conversation titles should match the renamed title immediately after the local update. If the server sync fails and Warp reverts the title, search and filtering should match the reverted title. The original initial query remains available wherever initial-query search already exists.
|
||||
20. Existing permissions apply on the server. The server checks the same conversation object permissions used by other conversation endpoints, but the required action is edit access. A user who can view but not edit a shared conversation sees the local title update first, then receives a server-sync failure toast and Warp reverts the local title.
|
||||
21. If the conversation has no cloud-stored transcript/task data, the server still accepts the rename after metadata permission checks pass. In that case the server updates metadata and task title surfaces and skips only the cloud `ConversationData` update.
|
||||
22. Forking or handing off a renamed conversation uses the current local conversation title as the source conversation's title unless a more specific fork or handoff title override is supplied. If server sync fails before the fork or handoff starts, the reverted title is used.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Conversation renaming client spec
|
||||
## Context
|
||||
This spec covers the `warp-4` client side of GitHub issue #8642. User-facing behavior is defined in `PRODUCT.md`. The server-side rename API, metadata persistence, `title_is_user_provided`, generated-title guards, task-title sync, and stored `ConversationData` updates are documented in `../warp-server-4/specs/gh-8642/TECH.md`.
|
||||
On the client, a Warp-native conversation title is derived from the root task description. The client should keep that model: an accepted rename updates the local root task description rather than creating a parallel display-title override. The local update should happen before the server rename request completes. If that server request fails, the client should revert the local title to the previous title for that failed request.
|
||||
Relevant client code:
|
||||
- `app/src/search/slash_command_menu/static_commands/commands.rs` registers static slash commands.
|
||||
- `app/src/terminal/input/slash_commands/mod.rs` handles slash command execution and toasts.
|
||||
- `app/src/server/server_api/ai.rs` owns the `AIClient` public API plumbing.
|
||||
- `app/src/ai/agent/conversation.rs` derives conversation titles from root task descriptions.
|
||||
- `app/src/ai/blocklist/history_model.rs` owns local conversation mutation, SQLite persistence, generic metadata updates, and the title-specific `UpdatedConversationTitle` event.
|
||||
- `app/src/terminal/view.rs`, `app/src/ai/agent_conversations_model.rs`, and `app/src/workspace/view/conversation_list/view_model.rs` refresh title-bearing surfaces.
|
||||
## Proposed changes
|
||||
1. Add `/rename-conversation <title>`:
|
||||
- Active only when Agent View, AI, and an active conversation are available.
|
||||
- Required title argument with existing slash-command UI patterns.
|
||||
- Trim leading/trailing whitespace, preserve internal whitespace, and reject empty or over-500-character titles before network.
|
||||
2. Add server API plumbing:
|
||||
- `RenameConversationRequest` and `RenameConversationResponse`.
|
||||
- `build_rename_conversation_url`.
|
||||
- `AIClient::rename_conversation`.
|
||||
- Implement using `post_public_api` against `POST /agent/conversations/{conversation_id}/rename`.
|
||||
3. Execute rename as an optimistic local mutation with server rollback:
|
||||
- Resolve the selected conversation id.
|
||||
- Require a server conversation token/id before accepting the command in this first pass; if missing, show an error toast, do not update the local title, and do not call the server.
|
||||
- Reject the command early if the selected conversation already has an in-flight rename. Show an error toast, do not update the local title, and do not send another server request.
|
||||
- Capture the current local title before applying the rename.
|
||||
- Apply the validated trimmed title to local state immediately.
|
||||
- Spawn the server request after the local mutation.
|
||||
- On server success, show the success toast. If the response contains a normalized title that differs from the locally applied title, apply that returned title locally.
|
||||
- On server error, show an error toast and revert to the captured previous title.
|
||||
- Clear the in-flight rename state on success, normalization, or error.
|
||||
4. Update local canonical title through rename-specific history-model helpers:
|
||||
- Replace the current success-only helper with `begin_conversation_rename`, `complete_conversation_rename`, `fail_conversation_rename`, and a local title application helper.
|
||||
- Track in-flight rename state in shared conversation state keyed by `AIConversationId`, not only in one input view, so a second input surface cannot start another rename for the same conversation.
|
||||
- Store the previous title and attempted title in the in-flight state until the server request resolves.
|
||||
- Update the selected conversation's root task description.
|
||||
- Persist the updated task list via existing multi-agent conversation persistence.
|
||||
- Update cached conversation/server metadata titles.
|
||||
- Emit `UpdatedConversationTitle` for rename-specific UI refreshes. Keep `UpdatedConversationMetadata` for non-title metadata/capability changes such as server tokens and permissions.
|
||||
- Do not add or persist a separate client-side title override field.
|
||||
5. Refresh all title-bearing client surfaces:
|
||||
- Pane title and tab title refresh through `TerminalView` handling of `UpdatedConversationTitle`.
|
||||
- Vertical tabs and workspace chrome refresh from the title-specific history event.
|
||||
- Command palette and conversation search read fresh `ConversationNavigationData`.
|
||||
- `AgentConversationsModel` maps `UpdatedConversationTitle` to `ConversationUpdateKind::TitleChanged`.
|
||||
- Conversation list and management panel rebuild on `ConversationUpdateKind::TitleChanged` for renames, while still using `ConversationUpdateKind::MetadataChanged` for non-title metadata changes.
|
||||
- Task-backed rows in `AgentConversationsModel` update cached `AmbientAgentTask.title` from the title event for the renamed conversation so list and management surfaces do not wait for a poll.
|
||||
6. Preserve fork/handoff semantics:
|
||||
- Forks naturally inherit the renamed root task description.
|
||||
- Explicit fork or handoff title overrides still take precedence where supplied.
|
||||
## Testing and validation
|
||||
Client tests should cover:
|
||||
1. Slash command registration and availability.
|
||||
2. Title validation through command-level coverage if added: trim, empty rejection, Unicode scalar limit. Do not keep helper-only unit tests just to cover extracted validation.
|
||||
3. Rename command acceptance updates the local root task description before the server future resolves.
|
||||
4. Server success with a matching title leaves the already-applied local title in place.
|
||||
5. Server success with a different normalized title reapplies the returned title locally.
|
||||
6. Server failure shows an error toast and reverts the local title to the title captured before the attempted rename.
|
||||
7. A second rename while the first is in flight is rejected early, leaves the local title unchanged, and does not send a server request.
|
||||
8. A missing active conversation or missing server conversation identity leaves the local title unchanged and does not send a server request.
|
||||
9. Local persistence/restoration derives the renamed title from root task description.
|
||||
10. Conversation list and management panel refresh cached task-backed titles on `UpdatedConversationTitle` / `ConversationUpdateKind::TitleChanged`.
|
||||
11. Pane title refreshes immediately after `UpdatedConversationTitle`.
|
||||
Validation commands:
|
||||
- `./script/format`.
|
||||
- `cargo check -p warp`.
|
||||
- `cargo check -p warp --tests`.
|
||||
- `cargo clippy -p warp --tests -- -D warnings`.
|
||||
- `git diff --check`.
|
||||
Do not run nextest or presubmit for this client validation pass.
|
||||
Reference in New Issue
Block a user