Skip to content

feat: add tower apps cancel command to cancel running runs#215

Open
socksy wants to merge 1 commit intodevelopfrom
feature/cancel-runs-on-cli
Open

feat: add tower apps cancel command to cancel running runs#215
socksy wants to merge 1 commit intodevelopfrom
feature/cancel-runs-on-cli

Conversation

@socksy
Copy link
Contributor

@socksy socksy commented Feb 27, 2026

Expose the existing cancel_run API endpoint through the CLI and MCP server. Adds tower apps cancel <app_name> <run_number> as a subcommand under apps (consistent with existing apps show, apps logs, etc.) and a corresponding tower_apps_cancel MCP tool.

Summary by CodeRabbit

  • New Features
    • Added cancel command to terminate running app runs. Users can now cancel specific application runs by providing the app name and run number, improving control over long-running processes without requiring manual intervention or waiting for natural completion.

Expose the existing cancel_run API endpoint through the CLI and MCP
server. Adds `tower apps cancel <app_name> <run_number>` as a subcommand
under apps (consistent with existing `apps show`, `apps logs`, etc.)
and a corresponding `tower_apps_cancel` MCP tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/cancel-runs-on-cli

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/mock-api-server/main.py`:
- Around line 347-352: The cancellation loop in tests/mock-api-server/main.py
currently cancels any matched run; change it to only cancel runs whose run_data
indicates they are active (e.g., check run_data["status_group"] == "running" or
that run_data["status"] is not in terminal states). In the loop that iterates
mock_runs_db items (referencing mock_runs_db, run_data, name, seq, now_iso), add
a guard to skip non-active runs before setting run_data["status"],
run_data["status_group"], and run_data["cancelled_at"], and only return the
modified run when the run was actually running.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3c58d47 and 28782d6.

📒 Files selected for processing (6)
  • crates/tower-cmd/src/api.rs
  • crates/tower-cmd/src/apps.rs
  • crates/tower-cmd/src/lib.rs
  • crates/tower-cmd/src/mcp.rs
  • tests/integration/features/cli_runs.feature
  • tests/mock-api-server/main.py

Comment on lines +347 to +352
for run_id, run_data in mock_runs_db.items():
if run_data["app_name"] == name and run_data["number"] == seq:
run_data["status"] = "cancelled"
run_data["status_group"] = "successful"
run_data["cancelled_at"] = now_iso()
return {"run": run_data}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restrict cancellation to active runs only.

The handler currently marks any matched run as cancelled. This can incorrectly allow cancelling already terminal runs and drifts from the “cancel running runs” behavior.

💡 Proposed fix
-    for run_id, run_data in mock_runs_db.items():
+    for run_id, run_data in mock_runs_db.items():
         if run_data["app_name"] == name and run_data["number"] == seq:
+            if run_data["status"] not in {"running", "pending", "scheduled"}:
+                raise HTTPException(
+                    status_code=409,
+                    detail=f"Run sequence {seq} for app '{name}' is not cancellable from status '{run_data['status']}'",
+                )
             run_data["status"] = "cancelled"
             run_data["status_group"] = "successful"
             run_data["cancelled_at"] = now_iso()
             return {"run": run_data}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/mock-api-server/main.py` around lines 347 - 352, The cancellation loop
in tests/mock-api-server/main.py currently cancels any matched run; change it to
only cancel runs whose run_data indicates they are active (e.g., check
run_data["status_group"] == "running" or that run_data["status"] is not in
terminal states). In the loop that iterates mock_runs_db items (referencing
mock_runs_db, run_data, name, seq, now_iso), add a guard to skip non-active runs
before setting run_data["status"], run_data["status_group"], and
run_data["cancelled_at"], and only return the modified run when the run was
actually running.

Comment on lines +79 to +95
.subcommand(
Command::new("cancel")
.arg(
Arg::new("app_name")
.value_parser(value_parser!(String))
.index(1)
.required(true)
.help("Name of the app"),
)
.arg(
Arg::new("run_number")
.value_parser(value_parser!(i64))
.index(2)
.required(true)
.help("Run number to cancel"),
)
.about("Cancel a running app run"),
Copy link
Member

Choose a reason for hiding this comment

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

Do we want the interface to be cancel {app_name} {seq} or cancel --app-name {name} --seq {seq}?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants