feat: render all rpc-messages.jsonl message types in gateway preview step summary#22427
feat: render all rpc-messages.jsonl message types in gateway preview step summary#22427
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/3ea26947-eade-4fa3-82a0-8c31a58d544b
…step summary Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/gh-aw/sessions/3ea26947-eade-4fa3-82a0-8c31a58d544b
There was a problem hiding this comment.
Pull request overview
Updates the MCP gateway preview-step log parser to support the unified rpc-messages.jsonl format (mcpg v0.2.0+), so the step summary can surface more than just DIFC-filtered events.
Changes:
- Added parsing/categorization of
rpc-messages.jsonlinto{requests, responses, other}(excludingDIFC_FILTERED, which is still handled separately). - Added summary rendering for MCP activity (tool/method request table) and “other” message type counts, plus reusing the existing DIFC-filtered section.
- Added unit tests covering the new parsing/labeling/summary helpers and updated exports/imports.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| actions/setup/js/parse_mcp_gateway_log.cjs | Adds JSONL parsing + summary rendering for unified rpc-messages logging and integrates it into main() when gateway.md is absent. |
| actions/setup/js/parse_mcp_gateway_log.test.cjs | Adds/updates tests for the new exported parsing and rendering helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const time = req.timestamp ? req.timestamp.replace("T", " ").replace(/\.\d+Z$/, "Z") : "-"; | ||
| const server = req.server_id || "-"; | ||
| const label = getRpcRequestLabel(req); | ||
| callLines.push(`| ${time} | ${server} | \`${label}\` |`); | ||
| } |
There was a problem hiding this comment.
Values interpolated into the markdown table for REQUESTs (server_id, and the label from getRpcRequestLabel) are not escaped for table-breaking characters like | or newlines. generateDifcFilteredSummary already escapes reason for |, so it would be more robust to similarly escape server_id (and optionally the label) before writing table rows.
| const rpcSummary = generateRpcMessagesSummary(rpcEntries, difcFilteredEvents); | ||
| if (rpcSummary.length > 0) { | ||
| core.summary.addRaw(rpcSummary).write(); | ||
| } | ||
| } else { | ||
| core.info("rpc-messages.jsonl is present but contains no renderable messages"); | ||
| } | ||
| return; |
There was a problem hiding this comment.
core.summary.addRaw(rpcSummary).write() is not awaited. Since main() returns immediately afterward, the step summary write can be dropped/flaky depending on event loop timing. Please await core.summary.addRaw(rpcSummary).write(); (and keep summary writes consistent across branches).
| * Generates a markdown step summary for rpc-messages.jsonl entries (mcpg v0.2.0+ format). | ||
| * Shows a table of REQUEST entries (tool calls), a count of RESPONSE entries, any other | ||
| * message types, and the DIFC_FILTERED section if there are blocked events. | ||
| * @param {{requests: Array<Object>, responses: Array<Object>, other: Array<Object>}} entries | ||
| * @param {Array<Object>} difcFilteredEvents - DIFC_FILTERED events parsed separately | ||
| * @returns {string} Markdown summary, or empty string if nothing to show | ||
| */ | ||
| function generateRpcMessagesSummary(entries, difcFilteredEvents) { | ||
| const { requests, responses, other } = entries; | ||
| const blockedCount = difcFilteredEvents ? difcFilteredEvents.length : 0; | ||
| const totalMessages = requests.length + responses.length + other.length + blockedCount; | ||
|
|
||
| if (totalMessages === 0) return ""; | ||
|
|
||
| const parts = []; | ||
|
|
||
| // Tool calls / requests table | ||
| if (requests.length > 0) { | ||
| const blockedNote = blockedCount > 0 ? `, ${blockedCount} blocked` : ""; | ||
| const callLines = []; | ||
| callLines.push("<details>"); | ||
| callLines.push(`<summary>MCP Gateway Activity (${requests.length} request${requests.length !== 1 ? "s" : ""}${blockedNote})</summary>\n`); | ||
| callLines.push(""); | ||
| callLines.push("| Time | Server | Tool / Method |"); | ||
| callLines.push("|------|--------|---------------|"); | ||
|
|
There was a problem hiding this comment.
generateRpcMessagesSummary parses and counts responses, but the rendered step summary never mentions RESPONSE messages (only requests table + other type counts + DIFC section). This seems to conflict with the PR goal/description of rendering REQUEST and RESPONSE message types. Consider including at least a response count in the summary (or a collapsible section), or update the PR description/title if responses are intentionally omitted.
Summary
With mcpg v0.2.0 (merged in #22388), the MCP gateway writes all messages to a single
rpc-messages.jsonlfile instead of separategateway.md/gateway.logstreams. The gateway preview step (parse_mcp_gateway_log.cjs) only extractedDIFC_FILTEREDevents from this file, soREQUESTandRESPONSEmessages were never shown in the step summary.Changes
actions/setup/js/parse_mcp_gateway_log.cjsparseRpcMessagesJsonl(content)— parses all entries fromrpc-messages.jsonl, returning categorized{requests, responses, other}(DIFC_FILTERED excluded as it is handled separately)getRpcRequestLabel(entry)— extracts a human-readable label: tool name fortools/callrequests, method name otherwisegenerateRpcMessagesSummary(entries, difcFilteredEvents)— renders a step summary with:SESSION_START,SESSION_END) if presentmain()— whengateway.mdis absent (v0.2.0) butrpc-messages.jsonlexists, parses all message types and writes the full summary; the existinggateway.log/stderr.loglegacy fallback is preservedactions/setup/js/parse_mcp_gateway_log.test.cjsparseRpcMessagesJsonl,getRpcRequestLabel, andgenerateRpcMessagesSummarySecurity Summary
No security vulnerabilities found or introduced.