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

Method promptTaskForRequiredCompletionTool

src/node/services/taskService.ts:7406–7526  ·  view source on GitHub ↗
(
    workspaceId: string,
    options?: {
      reason?: "startup" | "stream_end" | "error";
      error?: Pick<ErrorEvent, "error" | "errorType">;
    }
  )

Source from the content-addressed store, hash-verified

7404 }
7405
7406 private async promptTaskForRequiredCompletionTool(
7407 workspaceId: string,
7408 options?: {
7409 reason?: "startup" | "stream_end" | "error";
7410 error?: Pick<ErrorEvent, "error" | "errorType">;
7411 }
7412 ): Promise<boolean> {
7413 assert(
7414 workspaceId.length > 0,
7415 "promptTaskForRequiredCompletionTool: workspaceId must be non-empty"
7416 );
7417
7418 const cfg = this.config.loadConfigOrDefault();
7419 const entry = findWorkspaceEntry(cfg, workspaceId);
7420 if (!entry?.workspace.parentWorkspaceId) {
7421 return false;
7422 }
7423 if (entry.workspace.taskStatus !== "awaiting_report") {
7424 return false;
7425 }
7426 const taskIndex = this.buildAgentTaskIndex(cfg);
7427 if (
7428 await this.interruptTaskRecoveryForInactiveWorkflowOwner(
7429 workspaceId,
7430 cfg,
7431 `completion-tool-${options?.reason ?? "unknown"}`,
7432 taskIndex
7433 )
7434 ) {
7435 return false;
7436 }
7437 if (await this.hasActiveTaskOwnedWork(workspaceId, taskIndex)) {
7438 return false;
7439 }
7440 if (this.aiService.isStreaming(workspaceId)) {
7441 return true;
7442 }
7443
7444 const isPlanLike = await this.isPlanLikeTaskWorkspace(entry);
7445 const completionToolName = isPlanLike ? "propose_plan" : "agent_report";
7446
7447 // Persisted circuit breaker: a task that keeps consuming recovery prompts
7448 // without ever completing is stuck (repeated empty output, repeated
7449 // length-truncated turns, or a model that never calls its completion
7450 // tool). Interrupt it with a descriptive error instead of prompting
7451 // forever. The counter lives on the workspace entry so restart loops stay
7452 // bounded too; finalizeAgentTaskReport clears it on success.
7453 const recoveryAttempts = entry.workspace.taskRecoveryAttempts ?? 0;
7454 if (recoveryAttempts >= MAX_TASK_RECOVERY_ATTEMPTS) {
7455 const lastError = options?.error
7456 ? ` Last error (${options.error.errorType ?? "unknown"}): ${options.error.error}`
7457 : "";
7458 log.error("Task exceeded its recovery attempt budget; interrupting task", {
7459 workspaceId,
7460 taskName: entry.workspace.name,
7461 recoveryAttempts,
7462 limit: MAX_TASK_RECOVERY_ATTEMPTS,
7463 reason: options?.reason,

Callers 6

initializeMethod · 0.95
waitForAgentReportMethod · 0.95
handleStreamEndMethod · 0.95
handleTaskStreamErrorMethod · 0.95

Calls 13

buildAgentTaskIndexMethod · 0.95
editWorkspaceEntryMethod · 0.95
findWorkspaceEntryFunction · 0.90
loadConfigOrDefaultMethod · 0.80
sendMessageMethod · 0.65
assertFunction · 0.50

Tested by

no test coverage detected