






















@@ -39,6 +39,8 @@ import {
3939type SessionEntry,
4040updateSessionStore,
4141} from "../../config/sessions.js";
42+import { resolveSilentReplyPolicy } from "../../config/silent-reply.js";
43+import type { OpenClawConfig } from "../../config/types.openclaw.js";
4244import { logVerbose } from "../../globals.js";
4345import { emitAgentEvent, onAgentEvent, registerAgentRunContext } from "../../infra/agent-events.js";
4446import { formatErrorMessage } from "../../infra/errors.js";
@@ -474,13 +476,31 @@ function resolveExternalRunFailureTextForConversation(params: {
474476text: string;
475477sessionCtx: TemplateContext;
476478isGenericRunnerFailure: boolean;
479+cfg?: OpenClawConfig;
477480}): string {
478481if (!isNonDirectConversationContext(params.sessionCtx)) {
479482return params.text;
480483}
481484if (!params.isGenericRunnerFailure && !params.text.includes(AGENT_FAILED_BEFORE_REPLY_TEXT)) {
482485return params.text;
483486}
487+// Honor the documented `agents.defaults.silentReply` /
488+// `surfaces.<id>.silentReply` policy here so failure-fallback respects the
489+// same operator-visible knob that `route-reply.ts` already uses for
490+// `NO_REPLY`-style silent payloads. Defaults preserve the existing
491+// "groups/channels stay quiet on generic runner failure" behavior; opting
492+// into `silentReply.group: "disallow"` (or the per-surface override) lets
493+// the operator surface the failure copy in the chat instead.
494+// See docs/concepts/messages.md ("Silent replies") for the policy contract.
495+const silentPolicy = resolveSilentReplyPolicy({
496+cfg: params.cfg,
497+sessionKey: params.sessionCtx.SessionKey,
498+surface: params.sessionCtx.Surface,
499+conversationType: "group",
500+});
501+if (silentPolicy === "disallow") {
502+return params.text;
503+}
484504return SILENT_REPLY_TOKEN;
485505}
486506@@ -589,6 +609,7 @@ export function buildKnownAgentRunFailureReplyPayload(params: {
589609err: unknown;
590610sessionCtx: TemplateContext;
591611resolvedVerboseLevel: VerboseLevel | undefined;
612+cfg?: OpenClawConfig;
592613}): ReplyPayload | undefined {
593614const message = formatErrorMessage(params.err);
594615const isFallbackSummary = isFallbackSummaryError(params.err);
@@ -601,6 +622,7 @@ export function buildKnownAgentRunFailureReplyPayload(params: {
601622text: BILLING_ERROR_USER_MESSAGE,
602623sessionCtx: params.sessionCtx,
603624isGenericRunnerFailure: false,
625+cfg: params.cfg,
604626}),
605627});
606628}
@@ -620,6 +642,7 @@ export function buildKnownAgentRunFailureReplyPayload(params: {
620642text: buildRateLimitCooldownMessage(params.err),
621643sessionCtx: params.sessionCtx,
622644isGenericRunnerFailure: false,
645+cfg: params.cfg,
623646}),
624647});
625648}
@@ -630,6 +653,7 @@ export function buildKnownAgentRunFailureReplyPayload(params: {
630653text: rateLimitOrOverloadedCopy,
631654sessionCtx: params.sessionCtx,
632655isGenericRunnerFailure: false,
656+cfg: params.cfg,
633657}),
634658});
635659}
@@ -645,6 +669,7 @@ export function buildKnownAgentRunFailureReplyPayload(params: {
645669text: externalRunFailureReply.text,
646670sessionCtx: params.sessionCtx,
647671isGenericRunnerFailure: false,
672+cfg: params.cfg,
648673}),
649674});
650675}
@@ -2112,6 +2137,7 @@ export async function runAgentTurnWithFallback(params: {
21122137text: switchErrorText,
21132138sessionCtx: params.sessionCtx,
21142139isGenericRunnerFailure: !shouldSurfaceToControlUi,
2140+cfg: params.followupRun.run.config,
21152141}),
21162142}),
21172143};
@@ -2318,6 +2344,7 @@ export async function runAgentTurnWithFallback(params: {
23182344text: fallbackText,
23192345sessionCtx: params.sessionCtx,
23202346isGenericRunnerFailure: externalRunFailureReply?.isGenericRunnerFailure ?? false,
2347+cfg: params.followupRun.run.config,
23212348});
2322234923232350params.replyOperation?.fail("run_failed", err);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。