Cancellation and Abort Handling
Relevant source files
The following files were used as context for generating this wiki page:
Cancellation and Abort Handling within this project ensures that long-running operations—such as remote API calls to Morph, file system writes, and complex search iterations—can be terminated gracefully by the host system. This system is critical for maintaining workspace integrity, preventing resource leaks, and providing a responsive user experience. The implementation primarily leverages the AbortSignal and AbortController patterns provided by the environment, integrated into the oh-my-pi extension lifecycle.
The scope of this system covers the fast_edit file modification tool, codebase_warpsearch and github_warpsearch tools, and the automated session history compaction bridge. By racing asynchronous requests against an abort signal, the plugin can reject operations promptly instead of blocking on remote network round-trips.
Architecture and Core Logic
The core logic for cancellation revolves around the throwIfAborted helper and a raceAbort mechanism. These utilities ensure that if a signal is triggered, the execution path immediately stops and throws a ToolAbortError or AbortError, which is then caught and handled by the tool's execution wrapper.
Key Components
| Component | Responsibility |
|---|---|
AbortSignal | Passed by the host to indicate that an operation (tool execution or compaction) should be cancelled. |
raceAbort | A utility that wraps a promise to race it against an AbortSignal, ensuring the promise rejects immediately if the signal is aborted. |
throwIfAborted | A synchronous check that throws an error if the signal's aborted property is true. |
ToolAbortError | A specialized error type used to signal that a tool's execution was terminated by the host. |
Sources: [src/tools/morph-edit.ts:13](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/morph-edit.ts#L13), [src/tools/warpgrep.ts:15](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/warpgrep.ts#L15), [src/compaction.ts:12](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/compaction.ts#L12), [CHANGELOG.md:15-16](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/CHANGELOG.md#L15-L16)
Execution Flow with Cancellation
This diagram illustrates how an operation (like a code search or edit) interacts with the abort signal during its lifecycle.
The system performs checks before starting, during asynchronous network calls, and even during critical file system operations to ensure no partial or unwanted mutations remain in the workspace.
Sources: [src/tools/morph-edit.ts:85-115](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/morph-edit.ts#L85-L115), [src/tools/warpgrep.ts:74-88](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/warpgrep.ts#L74-L88), [test/morph.test.ts:476-508](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/test/morph.test.ts#L476-L508)
Tool-Specific Implementation
Fast Edit (fast_edit)
In fast_edit, cancellation handling is particularly rigorous because it involves file system mutations. If a file is being created and the signal is aborted immediately after the write operation, the tool includes a "rollback" mechanism to delete the newly created file to prevent leaving the workspace in an inconsistent state.
- Pre-flight check: Verifies
signal.abortedbefore reading files or calling the Morph API. - In-flight race: Uses
raceAbort(or equivalent logic) during themorph.fastApply.applyEditcall. - Post-write rollback: If
Bun.writecompletes but the signal was aborted during the process, the tool attempts tounlinkthe file if it was a new file creation.
Sources: [src/tools/morph-edit.ts:91-105](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/morph-edit.ts#L91-L105), [test/morph.test.ts:489-508](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/test/morph.test.ts#L489-L508)
WarpGrep Search Tools
The search tools (codebase_warpsearch and github_warpsearch) handle cancellation across multiple turns of agentic search.
Sources: [src/tools/warpgrep.ts:77-88](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/warpgrep.ts#L77-L88), [test/morph.test.ts:607-619](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/test/morph.test.ts#L607-L619)
Compaction Bridge Cancellation
The session_before_compact hook allows the plugin to override the default host compaction. The bridge ensures that if the host cancels the compaction (e.g., because the user sent a new message), the remote Morph Compact request is also abandoned.
- Iterative History Folding: The bridge folds
previousSummaryandturnPrefixMessagesinto the request. - Prompt Rejection: If the signal is aborted before or during the remote call to
compactClient.compact, the operation rejects immediately. - No Fallback on Abort: Unlike API errors where the system falls back to native compaction, an explicit cancellation re-throws the error to the host to stop the compaction process entirely.
Sources: [src/compaction.ts:167-184](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/compaction.ts#L167-L184), [AGENTS.md:21-25](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/AGENTS.md#L21-L25), [CHANGELOG.md:15-16](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/CHANGELOG.md#L15-L16)
Summary of Cancellation States
The following table summarizes the behavior of different project modules when an abort is triggered:
| Module | Logic during Abort | Outcome |
|---|---|---|
| File Editing | throwIfAborted + file unlink for new files. | Workspace remains clean; no partial files. |
| Code Search | raceAbort on generator and API promises. | Remote search is abandoned; turns cease. |
| Compaction | raceAbort on Morph Compact API call. | Transcript egress stops; no summary generated. |
| GitHub Lookup | raceAbort on repository pre-flight checks. | Prevents unnecessary GitHub API calls. |
Sources: [src/tools/morph-edit.ts:186-193](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/morph-edit.ts#L186-L193), [src/tools/warpgrep.ts:153-159](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/tools/warpgrep.ts#L153-L159), [src/compaction.ts:203-207](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/src/compaction.ts#L203-L207), [test/morph.test.ts:413-426](https://github.com/metaphorics/oh-my-pi-plugin-morph/blob/4f5519f8a47c30598e8f3ff1f1d617d8b63f0464/test/morph.test.ts#L413-L426)
Cancellation and abort handling in this repository is implemented as a proactive defensive layer. By strictly following AbortSignal state and using racing patterns, the project ensures that remote operations do not outlive their relevance and that local mutations are rolled back when execution is interrupted.