From ff35cf28c7bd8da0dcd77d432db1a241f0062827 Mon Sep 17 00:00:00 2001 From: core-fe Date: Wed, 20 May 2026 14:20:56 -0700 Subject: [PATCH] fix(canvas/chat): point A2A error hints at Activity tab, not phantom "workspace/container logs" (closeout internal#212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 44affbde (2026-05-18) closed the chat-error banner side of internal#212 by replacing the hardcoded opaque "Agent error (Exception) — see workspace logs for details." with the secret-safe ACTIVITY_LOGGED. error_detail and a working "View activity log" button. What 44affbde missed: a sibling hint module (`a2aErrorHint.ts`) used by both the chat Agent Comms panel and the Activity tab still rendered two user-facing strings that pointed at non-existent surfaces: 1. "...Check the workspace's container logs for the traceback..." (agent-error/exception bucket, line 41) 2. "...Check the workspace logs or try restarting." (generic fallback, line 53) Neither "workspace logs" nor "container logs" maps to a UI affordance — that was the original #212 framing. Closeout: both strings now route the user to the Activity tab (the in-product logs surface where the full row carries request body, response body, duration, status, and the secret-safe error_detail). Per memory `feedback_surface_actionable_failure_reason_to_user` (CTO 2026-05-17): user-facing failures must surface actionable next steps. The Activity tab IS the actionable next step. Test: new `a2aErrorHint.test.ts` case pins both the agent-error bucket and the unrecognised-text fallback to mention "Activity tab" and NOT to regress to "workspace logs" / "container logs". Existing generic- fallback case widened to accept the new copy. 19/19 green locally. Refs: internal#212 closeout (44affbde was the primary fix), CTO feedback_surface_actionable_failure_reason_to_user, feedback_upstream _docs_first_before_hypothesizing (no third-party shape involved — pure copy fix). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tabs/chat/__tests__/a2aErrorHint.test.ts | 16 +++++++++++++++- canvas/src/components/tabs/chat/a2aErrorHint.ts | 12 ++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/canvas/src/components/tabs/chat/__tests__/a2aErrorHint.test.ts b/canvas/src/components/tabs/chat/__tests__/a2aErrorHint.test.ts index 8518829ba..0a64aa070 100644 --- a/canvas/src/components/tabs/chat/__tests__/a2aErrorHint.test.ts +++ b/canvas/src/components/tabs/chat/__tests__/a2aErrorHint.test.ts @@ -41,6 +41,19 @@ describe("inferA2AErrorHint", () => { expect(inferA2AErrorHint("RuntimeException in tool call")).toMatch(/runtime threw an exception/); }); + it("points at the Activity tab (the real in-product logs surface), not 'workspace/container logs' (internal#212)", () => { + // Pre-#212 these hints sent users to "workspace logs" / "container + // logs" — neither has a UI affordance in the canvas. Activity tab + // is the in-product surface where the full row lives. Lock the + // copy so a future refactor cannot re-introduce the dangling + // pointer. + expect(inferA2AErrorHint("Agent error: boom")).toMatch(/Activity tab/); + expect(inferA2AErrorHint("some completely novel error nobody has matched yet")).toMatch(/Activity tab/); + // And the two strings together must not regress to the old text. + expect(inferA2AErrorHint("Agent error: boom")).not.toMatch(/container logs/); + expect(inferA2AErrorHint("some novel error")).not.toMatch(/workspace logs/); + }); + it("recognises peer-unreachable cases (Activity-tab originals)", () => { expect(inferA2AErrorHint("workspace not found")).toMatch(/can't be reached/); expect(inferA2AErrorHint("not accessible")).toMatch(/can't be reached/); @@ -53,7 +66,8 @@ describe("inferA2AErrorHint", () => { it("returns a generic fallback for unrecognised text", () => { const hint = inferA2AErrorHint("some completely novel error nobody has matched yet"); - expect(hint).toMatch(/Check the workspace logs|delivery failure/); + // Fallback now sends the user to the Activity tab (post-#212). + expect(hint).toMatch(/Activity tab|delivery failure/); }); it("Claude SDK wedge wins over the more general timeout pattern", () => { diff --git a/canvas/src/components/tabs/chat/a2aErrorHint.ts b/canvas/src/components/tabs/chat/a2aErrorHint.ts index e29e643a6..db9a7069c 100644 --- a/canvas/src/components/tabs/chat/a2aErrorHint.ts +++ b/canvas/src/components/tabs/chat/a2aErrorHint.ts @@ -38,7 +38,11 @@ export function inferA2AErrorHint(detail: string): string { return "The connection to the remote agent dropped before a reply arrived. Usually a transient network blip — retry once. If it repeats, the remote container may have crashed mid-request; check its logs."; } if (t.includes("agent error") || t.includes("exception")) { - return "The remote agent's runtime threw an exception. Check the workspace's container logs for the traceback. Restart usually clears transient runtime crashes."; + // internal#212 closeout: end users have no "container logs" surface + // in the canvas; the Activity tab IS the user-visible logs surface + // (full row carries request/response body + error_detail). Point + // there so the hint is actionable from inside the product. + return "The remote agent's runtime threw an exception. Open the Activity tab for the full row (request body, response, error_detail) — Restart usually clears transient runtime crashes."; } if ( t.includes("not found") || @@ -50,5 +54,9 @@ export function inferA2AErrorHint(detail: string): string { if (detail === "") { return "The remote agent returned no error detail (the underlying httpx exception had an empty message — typically a connection-reset or silent timeout). A workspace restart is the safe first move."; } - return "The remote agent reported a delivery failure. Check the workspace logs or try restarting."; + // internal#212 closeout: "workspace logs" pointed at a tab that does + // not exist — Activity tab is the in-product logs surface. Keep the + // hint generic enough for the unrecognised-detail fallback but point + // the user at a real affordance. + return "The remote agent reported a delivery failure. Open the Activity tab for the full row, or try restarting the workspace."; } -- 2.52.0