| ... | @@ -0,0 +1,75 @@ |
| 1 | import { EventId, TurnId, type OrchestrationThreadActivity } from "@t3tools/contracts"; |
| 2 | import { describe, expect, it } from "vite-plus/test"; |
| 3 | |
| 4 | import { deriveWorkLogEntries } from "./session-logic"; |
| 5 | import { workEntryDisplayLabel } from "./components/chat/MessagesTimeline.logic"; |
| 6 | |
| 7 | // These are the already-truncated fields emitted by ProviderRuntimeIngestion |
| 8 | // for the malformed-skill diagnostic reported in issue 1084. |
| 9 | const retainedMessage = |
| 10 | "2026-03-14T16:11:12.550224Z ERROR codex_core::codex: failed to load skill /home/sebherrerabe/repos/devsuite/.agent/skills/monorepo-scaffolding/SKILL.md: invalid YAML: mapping va..."; |
| 11 | const warningSummary = |
| 12 | "2026-03-14T16:11:12.550224Z ERROR codex_core::codex: failed to load skill /home/sebherrerabe/repos/devsuite/.agent/sk..."; |
| 13 | |
| 14 | function makeActivity( |
| 15 | overrides: Partial<OrchestrationThreadActivity> = {}, |
| 16 | ): OrchestrationThreadActivity { |
| 17 | return { |
| 18 | id: EventId.make("diagnostic"), |
| 19 | createdAt: "2026-09-05T00:00:00.000Z", |
| 20 | kind: "runtime.error", |
| 21 | tone: "error", |
| 22 | summary: "Runtime error", |
| 23 | payload: { message: retainedMessage }, |
| 24 | turnId: TurnId.make("turn-1"), |
| 25 | ...overrides, |
| 26 | }; |
| 27 | } |
| 28 | |
| 29 | describe("runtime diagnostics in the work log", () => { |
| 30 | it("shows the retained error message in place of its generic row label", () => { |
| 31 | const [entry] = deriveWorkLogEntries([makeActivity()]); |
| 32 | |
| 33 | expect(entry).toMatchObject({ label: "Runtime error", detail: retainedMessage }); |
| 34 | expect(entry && workEntryDisplayLabel(entry, undefined)).toBe(retainedMessage); |
| 35 | }); |
| 36 | |
| 37 | it("shows the retained warning message beyond its truncated label", () => { |
| 38 | const [entry] = deriveWorkLogEntries([ |
| 39 | makeActivity({ kind: "runtime.warning", tone: "info", summary: warningSummary }), |
| 40 | ]); |
| 41 | |
| 42 | expect(entry).toMatchObject({ label: warningSummary, detail: retainedMessage }); |
| 43 | expect(entry && workEntryDisplayLabel(entry, undefined)).toBe(retainedMessage); |
| 44 | }); |
| 45 | |
| 46 | it("keeps an existing diagnostic detail when one is provided", () => { |
| 47 | const [entry] = deriveWorkLogEntries([ |
| 48 | makeActivity({ payload: { message: retainedMessage, detail: "Run claude auth login." } }), |
| 49 | ]); |
| 50 | |
| 51 | expect(entry?.detail).toBe("Run claude auth login."); |
| 52 | }); |
| 53 | |
| 54 | it("does not repeat a short warning already visible in the label", () => { |
| 55 | const [entry] = deriveWorkLogEntries([ |
| 56 | makeActivity({ |
| 57 | kind: "runtime.warning", |
| 58 | tone: "info", |
| 59 | summary: "Reconnecting... 2/5", |
| 60 | payload: { message: "Reconnecting... 2/5" }, |
| 61 | }), |
| 62 | ]); |
| 63 | |
| 64 | expect(entry?.label).toBe("Reconnecting... 2/5"); |
| 65 | expect(entry?.detail).toBeUndefined(); |
| 66 | }); |
| 67 | |
| 68 | it("does not interpret an unrelated activity message as a runtime diagnostic", () => { |
| 69 | const [entry] = deriveWorkLogEntries([ |
| 70 | makeActivity({ kind: "tool.completed", tone: "tool", summary: "Read file" }), |
| 71 | ]); |
| 72 | |
| 73 | expect(entry?.detail).toBeUndefined(); |
| 74 | }); |
| 75 | }); |