Skip to content

feat(portal): show WebSocket messages in the HAR network viewer - #1581

Open
Naveen Chatlapalli (1aifanatic) wants to merge 1 commit into
microsoft:mainfrom
1aifanatic:feat/999-har-websocket-messages
Open

Naveen Chatlapalli (1aifanatic) wants to merge 1 commit into
microsoft:mainfrom
1aifanatic:feat/999-har-websocket-messages

Conversation

@1aifanatic

Copy link
Copy Markdown

Summary

Fixes #999.

The gateway records each WebSocket connection as a single HAR entry. Following the Chrome DevTools convention, that entry is the 101 upgrade handshake plus a _webSocketMessages array of {type, time, opcode, data} frames (see docs/architecture/gateway-websocket.md). The Portal's Network tab ignored that array, so for gpt-5.x runs, whose /responses traffic is entirely WebSocket frames, all you could see was an empty 101 row.

What changes in the Network tab

  • WebSocket entries are recognized by _resourceType: "websocket", a 101 status, or a _webSocketMessages array.
    • Their Type column reads ws.
    • The summary bar adds "N WebSocket messages".
  • A new Messages tab opens by default when you select a WebSocket entry. It lists every frame with:
    • direction (↑ Sent / ↓ Received)
    • offset from the first frame (+1.250 s)
    • payload size, and the payload itself, pretty-printed when it's JSON
    • a All / Sent / Received filter at the top
  • Binary frames (opcode 2) are decoded as UTF-8 when they're valid text. Otherwise they're shown as base64 and labelled binary · base64.
  • Malformed frames are dropped instead of breaking the viewer.
  • HTTP entries are unchanged: no Messages tab. If you switch from a WebSocket entry with Messages selected, the panel falls back to Headers.

Files

  • apps/portal/src/lib/har-websocket.ts (new): pure helpers to read, decode, summarize and format frames.
  • apps/portal/src/components/HarWebSocketMessages.tsx (new): the Messages tab.
  • apps/portal/src/components/HarNetworkViewer.tsx: WebSocket detection, the ws type, the message count, and the tab wiring.

Tests

  • har-websocket.test.ts (10 tests):
    • HTTP vs. WebSocket entries, and malformed items being dropped
    • direction normalization and time offsets
    • UTF-8 byte sizes
    • binary frames: valid UTF-8, non-text, and invalid base64
    • summary totals and JSON pretty-printing
  • HarWebSocketMessages.test.tsx (6 tests):
    • frame list rendering, the direction filter, and the empty state
    • with useHarData mocked, HarNetworkViewer marks the ws row, counts messages, opens a WebSocket entry on Messages, and shows no Messages tab for HTTP entries

All 16 pass, and tsc --noEmit for apps/portal is clean. The full portal suite gives the same result with and without this change: the same 6 files fail on main locally (localStorage unavailable under Node v26 + happy-dom), and nothing new fails.

Storybook

  • HarNetworkViewer.stories.tsx: new WithWebSocket story, a mixed HAR with one gateway-shaped WebSocket connection that includes text and binary frames.
  • HarWebSocketMessages.stories.tsx (new): Default and Empty, both with play tests.

I haven't viewed this in a running Portal or Storybook, only through the tests above. A quick look at the WithWebSocket story would be worthwhile.

Docs

docs/architecture/gateway-websocket.md gets a new "Downstream consumers (Portal Network tab)" section next to the existing judge-consumer section.

🤖 Generated with Claude Code

The gateway records each WebSocket connection as one HAR entry with a
_webSocketMessages array, but the Network tab only showed the 101 upgrade
handshake. WebSocket entries now read "ws" in the Type column and open a
Messages tab listing every frame with direction, timing, size and a
pretty-printed payload, filterable by direction. Binary frames decode as
UTF-8 when valid and fall back to base64.

Fixes microsoft#999

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Portal's HAR viewer should support web socket exchanges in HAR's _webSocketMessages field

1 participant