MCPcopy Index your code
hub / github.com/coder/mux / interruptStream

Method interruptStream

src/node/services/workspaceService.ts:7526–7598  ·  view source on GitHub ↗
(
    workspaceId: string,
    options?: { soft?: boolean; abandonPartial?: boolean; sendQueuedImmediately?: boolean }
  )

Source from the content-addressed store, hash-verified

7524 }
7525
7526 async interruptStream(
7527 workspaceId: string,
7528 options?: { soft?: boolean; abandonPartial?: boolean; sendQueuedImmediately?: boolean }
7529 ): Promise<Result<void>> {
7530 try {
7531 this.taskService?.resetAutoResumeCount(workspaceId);
7532 if (!options?.soft) {
7533 // Mark before attempting the session interrupt to close races where a child
7534 // could report between stop initiation and descendant cascade termination.
7535 this.taskService?.markParentWorkspaceInterrupted(workspaceId);
7536 }
7537
7538 const session = this.getOrCreateSession(workspaceId);
7539 const stopResult = await session.interruptStream(options);
7540 if (!stopResult.success) {
7541 // Interrupt failed, so clear hard-interrupt suppression we set above.
7542 if (!options?.soft) {
7543 this.taskService?.resetAutoResumeCount(workspaceId);
7544 }
7545 log.error("Failed to stop stream:", stopResult.error);
7546 return Err(stopResult.error);
7547 }
7548
7549 // For hard interrupts, delete partial immediately. For soft interrupts,
7550 // defer to stream-abort handler (stream is still running and may recreate partial).
7551 if (options?.abandonPartial && !options?.soft) {
7552 log.debug("Abandoning partial for workspace:", workspaceId);
7553 await this.historyService.deletePartial(workspaceId);
7554 }
7555
7556 // Rationale: user-initiated hard interrupts should stop the entire task tree so
7557 // descendant sub-agents cannot finish later and auto-resume this workspace.
7558 if (!options?.soft) {
7559 try {
7560 const interruptedTaskIds =
7561 await this.taskService?.terminateAllDescendantAgentTasks?.(workspaceId);
7562 if (interruptedTaskIds && interruptedTaskIds.length > 0) {
7563 log.debug("Cascade-interrupted descendant tasks on interrupt", {
7564 workspaceId,
7565 interruptedTaskIds,
7566 });
7567 }
7568 } catch (error: unknown) {
7569 log.error("Failed to cascade-interrupt descendant tasks on interrupt", {
7570 workspaceId,
7571 error,
7572 });
7573 }
7574 }
7575
7576 // Handle queued messages based on option
7577 if (options?.sendQueuedImmediately) {
7578 // `sendQueuedMessages()` routes through AgentSession directly, so explicitly
7579 // clear hard-interrupt suppression first (it won't flow through sendMessage()).
7580 this.taskService?.resetAutoResumeCount(workspaceId);
7581 // Send queued messages immediately instead of restoring to input
7582 session.sendQueuedMessages();
7583 } else {

Callers 2

createCoreServicesFunction · 0.95

Calls 11

getOrCreateSessionMethod · 0.95
ErrFunction · 0.90
OkFunction · 0.90
getErrorMessageFunction · 0.90
resetAutoResumeCountMethod · 0.80
debugMethod · 0.80
deletePartialMethod · 0.80
sendQueuedMessagesMethod · 0.80
restoreQueueToInputMethod · 0.80

Tested by

no test coverage detected