mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix(telegram): avoid leaking failed tool warnings into chat
This commit is contained in:
committed by
openclaw-clownfish[bot]
parent
7a88117f42
commit
67c7face41
@@ -36,6 +36,7 @@ Docs: https://docs.openclaw.ai
|
||||
- CLI/status: fall back to a bounded local `status` RPC when loopback detail probes time out or report unknown capability, so reachable local gateways are no longer marked unreachable by slow read diagnostics. Fixes #73535; refs #48360, #62762, #51357, and #42019. Thanks @RacecarGuy, @justinschille, @DJBlackhawk, @tianyaqpzm, and @0xrsydn.
|
||||
- CLI/gateway: reuse cached paired-device auth during `gateway probe` and report post-connect diagnostic failures as degraded reachability, so healthy local gateways are no longer marked unreachable after loopback auth or read timeouts. Fixes #48360. Thanks @RacecarGuy.
|
||||
- Channels/Discord: give Discord Gateway WebSocket handshakes a 30s timeout so stalled TLS/network transitions emit an error and Carbon can continue its reconnect loop instead of leaving the bot silent until restart. Refs #50046. Thanks @codexGW.
|
||||
- Channels/Telegram: suppress standalone failed edit/write warning payloads when an assistant error reply already covers the turn, while keeping unresolved mutating failures visible behind success-looking replies. Fixes #39631; carries forward #39636 and #39717. Thanks @Bartok9 and @Bortlesboat.
|
||||
- NVIDIA/NIM: persist the `NVIDIA_API_KEY` provider marker and mark bundled NVIDIA Chat Completions models as string-content compatible, so NIM models load from `models.json` and OpenAI-compatible subagent calls send plain text content. Fixes #73013 and #50107; refs #73014. Thanks @bautrey, @iot2edge, @ifearghal, and @futhgar.
|
||||
- Channels/Discord: let text-only configs drop the `GuildVoiceStates` gateway intent and expose a bounded `/gateway/bot` metadata timeout with rate-limited fallback logs, reducing idle CPU and warning floods. Fixes #73709 and #73585. Thanks @sanchezm86 and @trac3r00.
|
||||
- Agents/sessions: mark same-turn `sessions_send` and A2A reply prompts with an inter-session `isUser=false` envelope before they reach the model, so foreign session output no longer lands as bare active user text. Fixes #73702; refs #73698, #73609, #73595, and #73622. Thanks @alvelda.
|
||||
|
||||
@@ -80,6 +80,20 @@ describe("buildEmbeddedRunPayloads", () => {
|
||||
expect(payloads.some((payload) => payload.text === errorJson)).toBe(false);
|
||||
});
|
||||
|
||||
it("suppresses mutating tool warnings when an assistant error reply already covers the turn", () => {
|
||||
const payloads = buildPayloads({
|
||||
assistantTexts: [errorJson],
|
||||
lastAssistant: makeAssistant({}),
|
||||
lastToolError: { toolName: "edit", error: "file missing" },
|
||||
sessionKey: "agent:main:telegram:direct:u123",
|
||||
});
|
||||
|
||||
expectOverloadedFallback(payloads);
|
||||
expect(payloads[0]?.isError).toBe(true);
|
||||
expect(payloads.some((payload) => payload.text?.includes("Edit"))).toBe(false);
|
||||
expect(payloads.some((payload) => payload.text?.includes("missing"))).toBe(false);
|
||||
});
|
||||
|
||||
it("suppresses pretty-printed error JSON that differs from the errorMessage", () => {
|
||||
const payloads = buildPayloads({
|
||||
assistantTexts: [errorJsonPretty],
|
||||
|
||||
@@ -127,6 +127,7 @@ function shouldIncludeToolErrorDetails(params: {
|
||||
function resolveToolErrorWarningPolicy(params: {
|
||||
lastToolError: ToolErrorSummary;
|
||||
hasUserFacingReply: boolean;
|
||||
hasUserFacingErrorReply: boolean;
|
||||
hasUserFacingFailureAcknowledgement: boolean;
|
||||
suppressToolErrors: boolean;
|
||||
suppressToolErrorWarnings?: boolean;
|
||||
@@ -152,7 +153,7 @@ function resolveToolErrorWarningPolicy(params: {
|
||||
params.lastToolError.mutatingAction ?? isLikelyMutatingToolName(params.lastToolError.toolName);
|
||||
if (isMutatingToolError) {
|
||||
return {
|
||||
showWarning: !params.hasUserFacingFailureAcknowledgement,
|
||||
showWarning: !params.hasUserFacingErrorReply && !params.hasUserFacingFailureAcknowledgement,
|
||||
includeDetails,
|
||||
};
|
||||
}
|
||||
@@ -363,6 +364,7 @@ export function buildEmbeddedRunPayloads(params: {
|
||||
).filter((text) => !shouldSuppressRawErrorText(text));
|
||||
|
||||
let hasUserFacingAssistantReply = false;
|
||||
const hasUserFacingErrorReply = replyItems.some((item) => item.isError === true);
|
||||
let hasUserFacingFailureAcknowledgement = false;
|
||||
for (const text of answerTexts) {
|
||||
const {
|
||||
@@ -394,6 +396,7 @@ export function buildEmbeddedRunPayloads(params: {
|
||||
const warningPolicy = resolveToolErrorWarningPolicy({
|
||||
lastToolError: params.lastToolError,
|
||||
hasUserFacingReply: hasUserFacingAssistantReply,
|
||||
hasUserFacingErrorReply,
|
||||
hasUserFacingFailureAcknowledgement,
|
||||
suppressToolErrors: Boolean(params.config?.messages?.suppressToolErrors),
|
||||
suppressToolErrorWarnings: params.suppressToolErrorWarnings,
|
||||
|
||||
Reference in New Issue
Block a user