

















@@ -87,6 +87,10 @@ import {
8787} from "../tokens.js";
8888import type { GetReplyOptions, ReplyPayload } from "../types.js";
8989import { resolveRunAuthProfile } from "./agent-runner-auth-profile.js";
90+import {
91+GENERIC_EXTERNAL_RUN_FAILURE_TEXT,
92+HEARTBEAT_EXTERNAL_RUN_FAILURE_TEXT,
93+} from "./agent-runner-failure-copy.js";
9094import {
9195buildEmbeddedRunExecutionParams,
9296resolveQueuedReplyRuntimeConfig,
@@ -480,8 +484,6 @@ function collapseRepeatedFailureDetail(message: string): string {
480484const SAFE_MISSING_API_KEY_PROVIDERS = new Set(["anthropic", "google", "openai", "openai-codex"]);
481485const EXTERNAL_RUN_FAILURE_DETAIL_MAX_CHARS = 900;
482486const AGENT_FAILED_BEFORE_REPLY_TEXT = "Agent failed before reply:";
483-const GENERIC_EXTERNAL_RUN_FAILURE_TEXT =
484-"⚠️ Something went wrong while processing your request. Please try again, or use /new to start a fresh session.";
485487486488type ExternalRunFailureReply = {
487489text: string;
@@ -581,15 +583,9 @@ function formatForwardedExternalRunFailureText(message: string): string {
581583582584function buildExternalRunFailureReply(
583585message: string,
584-options?: { includeDetails?: boolean },
586+options?: { includeDetails?: boolean; isHeartbeat?: boolean },
585587): ExternalRunFailureReply {
586588const normalizedMessage = collapseRepeatedFailureDetail(message);
587-if (isToolResultTurnMismatchError(normalizedMessage)) {
588-return {
589-text: "⚠️ Session history got out of sync. Please try again, or use /new to start a fresh session.",
590-isGenericRunnerFailure: false,
591-};
592-}
593589const missingApiKeyFailure = buildMissingApiKeyFailureText(normalizedMessage);
594590if (missingApiKeyFailure) {
595591return { text: missingApiKeyFailure, isGenericRunnerFailure: false };
@@ -608,6 +604,15 @@ function buildExternalRunFailureReply(
608604isGenericRunnerFailure: false,
609605};
610606}
607+if (options?.isHeartbeat) {
608+return { text: HEARTBEAT_EXTERNAL_RUN_FAILURE_TEXT, isGenericRunnerFailure: false };
609+}
610+if (isToolResultTurnMismatchError(normalizedMessage)) {
611+return {
612+text: "⚠️ Session history got out of sync. Please try again, or use /new to start a fresh session.",
613+isGenericRunnerFailure: false,
614+};
615+}
611616const cliBackendTimeoutFailure = buildCliBackendTimeoutFailureText(normalizedMessage);
612617if (cliBackendTimeoutFailure) {
613618return { text: cliBackendTimeoutFailure, isGenericRunnerFailure: false };
@@ -2590,8 +2595,12 @@ export async function runAgentTurnWithFallback(params: {
25902595!shouldSurfaceToControlUi
25912596 ? buildExternalRunFailureReply(message, {
25922597includeDetails: isVerboseFailureDetailEnabled(params.resolvedVerboseLevel),
2598+isHeartbeat: params.isHeartbeat,
25932599})
25942600 : undefined;
2601+const genericFallbackText = params.isHeartbeat
2602+ ? HEARTBEAT_EXTERNAL_RUN_FAILURE_TEXT
2603+ : GENERIC_EXTERNAL_RUN_FAILURE_TEXT;
25952604const fallbackText = isBilling
25962605 ? BILLING_ERROR_USER_MESSAGE
25972606 : isRateLimit && !isOverloadedErrorMessage(message)
@@ -2604,7 +2613,7 @@ export async function runAgentTurnWithFallback(params: {
26042613 ? "⚠️ Message ordering conflict - please try again. If this persists, use /new to start a fresh session."
26052614 : shouldSurfaceToControlUi
26062615 ? `⚠️ Agent failed before reply: ${trimmedMessage}.\nLogs: openclaw logs --follow`
2607- : (externalRunFailureReply?.text ?? GENERIC_EXTERNAL_RUN_FAILURE_TEXT);
2616+ : (externalRunFailureReply?.text ?? genericFallbackText);
26082617const userVisibleFallbackText = resolveExternalRunFailureTextForConversation({
26092618text: fallbackText,
26102619sessionCtx: params.sessionCtx,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。