fix: address Copilot review round 2 on #2318

- fetchTracking: media types and HTTP methods compare case-insensitively;
  a `Request` input's own method is honoured; the SSE line scanner
  accepts LF, CRLF and a bare CR, holding a trailing CR until the next
  chunk decides whether it is half of a CRLF.
- MessageTrackingTransport does not report a send failure for a request
  the caller aborted through `requestSignal`, and InspectorClient keeps a
  request whose send failed with a request timeout — both are sent,
  unanswered requests, which is the state to keep reporting.
- createTransportNode builds a fetch tracker when any tracking callback
  is supplied, not only `onFetchRequest`.
- RemoteClientTransport's relay wait expires with the SDK's own timeout
  shape, so the web client's relay timeout is annotated like every other.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01APKSYHGxXBUpnR7ErFiLJn
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-13 22:27:54 -04:00
commit c565b56fcd

View file

@ -273,6 +273,7 @@ import {
import { SdkError, SdkErrorCode } from "@modelcontextprotocol/client";
import {
annotateRequestTimeout,
isRequestTimeoutError,
type ConnectionDiagnostics,
type LastResponse,
type NotificationStreamState,
@ -1131,11 +1132,16 @@ export class InspectorClient extends InspectorClientEventTarget {
};
this.dispatchTypedEvent("message", entry);
},
trackSendFailure: (message: JSONRPCRequest) => {
// The frame never reached the wire, so it is not awaiting a response.
// Leaving it would report a request the server never saw as
// unanswered, in every timeout message and Connection Info row, until
// the session resets (#2318).
trackSendFailure: (message: JSONRPCRequest, error: unknown) => {
// A send that failed because the request timed out is not a send
// that failed: the browser's remote transport awaits the response
// inside `send`, so its relay timeout surfaces here — the request
// reached the server and went unanswered, which is the state to
// keep reporting. Every other failure means the frame never reached
// the wire, and leaving it would report a request the server never
// saw as unanswered, in every timeout message and Connection Info
// row, until the session resets (#2318).
if (isRequestTimeoutError(error)) return;
if (this.outstandingRequests.delete(message.id)) {
this.dispatchConnectionDiagnosticsChange();
}