Warp is an agentic development environment, born out of the terminal. https://warp.dev
  • Rust 98.1%
  • Shell 0.7%
  • Python 0.5%
  • Objective-C 0.2%
  • PowerShell 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Yunfan Yang 1012545632
Shared-session cancel terminates the in-flight agent command (#15906)
## Description

Required for the conversation-steering interrupt e2e (warp-server
warpdotdev/warp-server#16958, session-sharing
warpdotdev/session-sharing#517, follows warpdotdev/warp-internal#27914).

### Staging evidence

With the sharer bypass from #27914, a steering interrupt reaches the
sharer as `ControlActionRequested { action: CancelConversation {
server_conversation_token } }` and the turn is cancelled (no further LLM
requests; `TOOL_RESULT cancel: cancelled` is carried with the next
request). But the agent's in-flight tool command kept running to natural
completion: `echo step-one; sleep 12; echo done-one` finished its full
12 s after the interrupt (`CommandExecutionFinished` ~12–13 s after
start in every run). Product decision: an interrupt must terminate the
running command as well as cancel the turn.

### Local stop vs. shared-session cancel (before this PR)

* **Local stop kills the command.** The pill-bar Stop/Kill
(`pane_group/pane/terminal_pane.rs`) and the second Ctrl-C after a Stop
takeover (`view.rs` `ctrl_c_to_active_block`) both go through
`TerminalView::stop_local_agent_conversation`, which calls
`cancel_conversation_progress(ManuallyCancelled)`, releases an
agent-controlled block via `set_user_control_for_teardown()`, and writes
Ctrl-C (ETX) to the PTY. Rewind does the same.
* **Shared-session cancel did not.** `terminal_view_adaptor.rs` →
`BlocklistAIController::handle_shared_session_cancel_action` →
`cancel_conversation_progress` only. For a running
`RequestCommandOutput`, `ShellCommandExecutor::cancel_execution` just
drops the block-finished / force-refresh oneshot senders so the action
resolves `Cancelled`; nothing touches the PTY, so the child process runs
to completion.

### Change

* `NetworkEvent::ControlActionRequested { CancelConversation }` now
calls a new `TerminalView::handle_shared_session_cancel_action(token)`,
which resolves the token to the live conversation and then calls the
existing `stop_local_agent_conversation`. Viewer-initiated stop and
server-side steering both arrive through this handler, so both get the
same behaviour. The local stop primitive is unchanged.
* `BlocklistAIController::handle_shared_session_cancel_action` becomes
`conversation_for_shared_session_cancel_action`: a pure resolver
returning the live, **not-yet-finished** conversation bound to the
token. This is a small deliberate tightening: a late/duplicate cancel
for a conversation that already reached `Success`/`Error`/`Cancelled` is
now a no-op (previously it only reset the sharer's input mode) instead
of being able to flip the terminal status to `Cancelled` via the stop
primitive.

Expected result on staging: the command block finishes within ~1 s of
the interrupt (exit 130) rather than at natural completion, and the tool
result reports cancellation promptly.

## Linked Issue
- [ ] The linked issue is labeled `ready-to-spec` or
`ready-to-implement`.
- [ ] Where appropriate, screenshots or a short video of the
implementation are included below (especially for user-visible or UI
changes).

## Testing

New unit tests in `app/src/terminal/view_tests.rs`:
* `shared_session_cancel_action_interrupts_running_agent_command` —
agent-requested command running in the active block; cancel writes
exactly one ETX to the PTY and the conversation ends `Cancelled`.
*
`shared_session_cancel_action_releases_agent_controlled_command_before_interrupting`
— CLI-subagent-controlled block (which would otherwise swallow the
Ctrl-C in `write_user_bytes_to_pty`) is handed to the user for teardown,
ETX is written, no auto-resume.
*
`shared_session_cancel_action_ignores_unknown_and_finished_conversations`
— unknown token and already-`Success` conversation: no PTY write, status
preserved.

Commands run:
* `./script/format` then `./script/format --check` — pass
* `cargo clippy -p warp --all-targets --tests -- -D warnings` — pass
* `cargo nextest run -p warp -E 'test(shared_session_cancel_action) |
test(ctrl_c_after_stop_takeover) | test(ctrl_c_after_transfer_takeover)
| test(completed_user_controlled_lrc)'` — 7/7 pass

- [ ] I have manually tested my changes locally with `./script/run` (not
run; needs the steering e2e on staging — see evidence above for the
pre-change baseline)

## Follow-up: run state after interrupt (proposal, not implemented)

Today `LocalAgentTaskSyncModel::map_conversation_status`
(`app/src/ai/blocklist/local_agent_task_sync_model.rs`) maps
`ConversationStatus::Cancelled` → `(AgentTaskState::Cancelled,
"Cancelled by user")` and pushes it to warp-server, which runs
`TransitionTaskToCancelled` (cancels a bound Factory task, notifies
GitHub/Linear/Jira/lifecycle, expires queued follow-ups; the run becomes
non-resumable once the session idles out). For a
shared-session-originated cancel (steering interrupt or viewer stop) the
desired run state is the idle shape a completed turn leaves: report
`AgentTaskState::Succeeded` with status message `"Turn interrupted"`,
while the transcript still shows the exchange as cancelled.

**Why the reason isn't available to the sync model today.** The only
place a `CancellationReason` is recorded is on the exchange, in
`FinishedAIAgentOutput::Cancelled { reason }`, and only when an
in-flight *stream* is cancelled
(`AIConversation::mark_request_cancelled`). In the interrupt case there
is no stream: the turn is mid-tool-call, so the conversation is moved to
`Cancelled` by the controller's `FinishedAction` handler
(`controller.rs`, the "mixed results → Cancelled" branch) and by
`stop_local_agent_conversation`'s direct
`update_conversation_status(Cancelled)` — neither carries a reason. So
the exchange is not a reliable place to look.

**Proposal.**
1. `app/src/ai/agent/mod.rs`: add
`CancellationReason::SharedSessionControl`. `conversation_outcome()` →
`CancellationOutcome::Cancelled`; `Display` → `"shared session control
action"`. (Only these two matches are exhaustive over the enum.)
2. `app/src/ai/agent/conversation.rs`: mirror the existing
`status_error: Option<RenderableAIError>` pattern with
`status_cancellation_reason: Option<CancellationReason>`, set by a new
`update_status_with_cancellation_reason(status, reason, ...)` (cleared
when the status is not `Cancelled`), exposed via
`status_cancellation_reason()`; `BlocklistAIHistoryModel` gets the
matching `update_conversation_status_with_cancellation_reason`. Persist
it alongside `status_error` if that is persisted (check
`conversation_yaml` / the persisted conversation state; a restart
mid-interrupt is an edge case, not a blocker).
3. Plumb the reason:
`TerminalView::stop_local_agent_conversation(conversation_id, reason,
ctx)` takes the `CancellationReason` (local callers pass
`ManuallyCancelled`, the new `handle_shared_session_cancel_action`
passes `SharedSessionControl`) and forwards it to
`cancel_conversation_progress`, to its direct `Cancelled` status write,
and — via `BlocklistAIActionEvent::FinishedAction { cancellation_reason
}` — the controller's `FinishedAction` handler records it when it writes
`Cancelled`. `mark_request_cancelled` already has the reason and should
record it too, so the stream-cancel path is covered for free.
4. `local_agent_task_sync_model.rs`: in `map_conversation_status`,
`ConversationStatus::Cancelled` matches on
`conversation.status_cancellation_reason()`:
`Some(SharedSessionControl)` → `(AgentTaskState::Succeeded,
Some(TaskStatusUpdate::message("Turn interrupted")))`; anything else
keeps `(Cancelled, "Cancelled by user")`. The reason is available where
the update is computed because `on_conversation_status_updated` runs off
`BlocklistAIHistoryEvent::UpdatedConversationStatus` and reads the
conversation from the history model synchronously, after the status (and
reason) have been written.
5. Tests: `local_agent_task_sync_model_tests.rs` —
`map_conversation_status` with `Cancelled` + `SharedSessionControl` →
`Succeeded`/"Turn interrupted", and `Cancelled` +
`ManuallyCancelled`/`None` → unchanged; `view_tests.rs` —
`handle_shared_session_cancel_action` records `SharedSessionControl` on
the conversation while a local Ctrl-C stop records `ManuallyCancelled`.

Caveat to confirm with the server side: reporting `Succeeded` for an
interrupted turn means the run shows as succeeded in lists until the
next turn; if a distinct state is preferred the mapping in step 4 is the
single place to change.

## Agent Mode
- [x] Warp Agent Mode - This PR was created via Warp's AI Agent Mode

CHANGELOG-BUG-FIX: Stopping a shared Agent Mode conversation from a
viewer or via conversation steering now interrupts the agent's running
command instead of letting it run to completion.

---
Conversation:
https://staging.warp.dev/conversation/8eaf5a4f-d303-465a-8498-f6267e0a0347
Run:
https://platform.staging.warp.dev/runs/01a084d0-cfc8-7b67-b960-97c4e2622c47
2026-09-10 21:26:14 -04:00
.agents Update triage taxonomy with agent: primary types and agent:priority-high (#15868) 2026-09-08 22:22:32 -04:00
.cargo Statically compile the CLI and warpctl binaries on Linux. (#12813) 2026-06-29 19:01:00 +00:00
.claude Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.config Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.github fix: bump warpdotdev/oz-agent-action from 1.0.26 to 1.0.32 (#15620) 2026-09-09 16:07:47 -04:00
.vscode Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.warp skills: distinguish GUI vs TUI front-ends and add TUI dev skills (#13562) 2026-07-10 19:23:40 -04:00
agents/specs Synthesize a smooth, eased cursor for Linux computer-use recordings (QUALITY-1169 follow-up) (#14681) 2026-08-04 15:02:57 -07:00
app Shared-session cancel terminates the in-flight agent command (#15906) 2026-09-10 21:26:14 -04:00
command-signatures-v2/js Initial public release of Warp. 2026-04-28 08:43:33 -05:00
crates [QUALITY-2068] Fix macOS computer-use recording output frame rate (#15920) 2026-09-10 17:39:40 -04:00
docker docker/agent-dev: install pgvector via postgresql-16-pgvector (#15241) 2026-08-17 20:06:32 +01:00
images docs: add README badges (#10204) 2026-05-06 01:41:49 +00:00
resources Auto-attach Factory MCP to third-party harness runs (#15827) 2026-09-05 06:06:07 +00:00
script Fix a number of bugs that lead to duplicate requests on shared session load. (#15829) 2026-09-10 11:58:55 -04:00
specs Remove Warp-managed Grok plugin installation (#15914) 2026-09-10 17:57:36 +00:00
.clippy.toml Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.dockerignore Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.gitattributes [Quality-547] add bert_tiny_v2 model and update input classifier (#10756) 2026-05-13 18:27:25 +00:00
.gitignore Support OSC 8 hyperlinks (GH6393) (#9850) 2026-07-16 13:43:26 -07:00
.mcp.json Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.PSScriptAnalyzerSettings.psd1 Initial public release of Warp. 2026-04-28 08:43:33 -05:00
.rustfmt.toml Move workspace crates over to the Rust 2024 edition. (#13990) 2026-07-20 07:06:03 +00:00
.warpindexingignore Initial public release of Warp. 2026-04-28 08:43:33 -05:00
about.hbs Initial public release of Warp. 2026-04-28 08:43:33 -05:00
about.toml Initial public release of Warp. 2026-04-28 08:43:33 -05:00
AGENTS.md Add container/member doc-comment guideline to AGENTS.md (#15285) 2026-08-18 22:28:07 +00:00
Cargo.lock [REMOTE-3146] Discover nested build cache roots (#15844) 2026-09-10 11:07:34 +00:00
Cargo.toml [APP-5776] Bump command-signatures for Rust Fig generators (#15791) 2026-09-04 03:57:12 +00:00
CODE_OF_CONDUCT.md Initial public release of Warp. 2026-04-28 08:43:33 -05:00
CONTRIBUTING.md Rename /oz-review to /warp-agent-review in contributor docs (#15407) 2026-08-24 15:34:25 -07:00
deny.toml Initial public release of Warp. 2026-04-28 08:43:33 -05:00
diesel.toml Initial public release of Warp. 2026-04-28 08:43:33 -05:00
FAQ.md Rename /oz-review to /warp-agent-review in contributor docs (#15407) 2026-08-24 15:34:25 -07:00
flake.lock Add Nix flake for Warp (#9394) 2026-05-13 13:46:16 -07:00
flake.nix Optimize settings schema generation during release process. (#13240) 2026-08-22 21:20:58 -04:00
LICENSE-AGPL Initial public release of Warp. 2026-04-28 08:43:33 -05:00
LICENSE-MIT Initial public release of Warp. 2026-04-28 08:43:33 -05:00
PSScriptAnalyzerCustomRules.psm1 Initial public release of Warp. 2026-04-28 08:43:33 -05:00
README.md Add Warp Factories early access section to README (#15534) 2026-09-02 16:28:17 +00:00
rust-toolchain.toml Add rust-analyzer to rust-toolchain.toml components (#15477) 2026-08-23 14:48:56 -04:00
SECURITY.md [Security] Update WARP.md and SECURITY.md guidence (#12088) 2026-06-03 00:14:27 +00:00
skills-lock.json Update common skills lock for warpdotdev/common-skills#92 (#15761) 2026-09-02 22:30:32 -04:00

Warp Agentic Development Environment product preview  

Built with Warp

Website · Code · Agents · Terminal · Drive · Docs · How Warp Works

Note

OpenAI is the founding sponsor of the new, open-source Warp repository, and the new agentic management workflows are powered by GPT models.

About

Warp is an agentic development environment, born out of the terminal. Use Warp's built-in coding agent, or bring your own CLI agent (Claude Code, Codex, Gemini CLI, and others).

Installation

You can download Warp and read our docs for platform-specific instructions.

Warp Contributions Overview Dashboard

Explore build.warp.dev to:

  • Watch thousands of Warp Factory agents triage issues, write specs, implement changes, and review PRs
  • View top contributors and in-flight features
  • Track your own issues with GitHub sign-in
  • Click into active agent sessions in a web-compiled Warp terminal

Automate development with Warp Factories

This repository is driven by Warp Factories: open, flexible infrastructure for teams to build cloud software factories of their own.

Warp Factories are defined in code and easy to deploy on any model or harness, with evals, benchmarks, and self-improvement built in. Request early access.

Licensing

Warp's UI framework (the warpui_core and warpui crates) are licensed under the MIT license.

The rest of the code in this repository is licensed under the AGPL v3.

Open Source & Contributing

Warp's client codebase is open source and lives in this repository. We welcome community contributions and have designed a lightweight workflow to help new contributors get started. For the full contribution flow, read our CONTRIBUTING.md guide.

Tip

Chat with contributors and the Warp team in the #oss-contributors Slack channel — a good place for ad-hoc questions, design discussion, and pairing with maintainers. New here? Join the Warp Slack community first, then jump into #oss-contributors.

Issue to PR

Before filing, search existing issues for your bug or feature request. If nothing exists, file an issue using our templates. Security vulnerabilities should be reported privately as described in CONTRIBUTING.md.

Once filed, a Warp maintainer reviews the issue and may apply a readiness label: ready-to-spec signals the design is open for contributors to spec out, and ready-to-implement signals the design is settled and code PRs are welcome. Anyone can pick up a labeled issue — mention @oss-maintainers on an issue if you'd like it considered for a readiness label.

Building the Repo Locally

To build and run Warp from source:

./script/bootstrap   # platform-specific setup
./script/run         # build and run Warp
./script/presubmit   # fmt, clippy, and tests

See AGENTS.md for the full engineering guide, including coding style, testing, and platform-specific notes.

Joining the Team

Interested in joining the team? See our open roles.

Support and Questions

  1. See our docs for a comprehensive guide to Warp's features.
  2. Join our Slack Community to connect with other users and get help from the Warp team — contributors hang out in #oss-contributors.
  3. Try our Preview build to test the latest experimental features.
  4. Mention @oss-maintainers on any issue to escalate to the team — for example, if you encounter problems with the automated agents.

Code of Conduct

We ask everyone to be respectful and empathetic. Warp follows the Code of Conduct. To report violations, email warp-coc at warp.dev.

Open Source Dependencies

We'd like to call out a few of the open source dependencies that have helped Warp to get off the ground: