(init: RequestInit | undefined)
| 275 | * open, which carries no JSON-RPC request and is read-only by HTTP |
| 276 | * semantics. Everything else — `tools/call` above all — fails closed. */ |
| 277 | const isReplaySafeRequest = (init: RequestInit | undefined): boolean => { |
| 278 | const body = init?.body; |
| 279 | if (body == null) return httpMethodFrom(init?.method) === "GET"; |
| 280 | // Both remote SDK transports send JSON-RPC bodies as `JSON.stringify` |
| 281 | // strings. Any other body shape cannot be verified read-only here. |
| 282 | if (typeof body !== "string") return false; |
| 283 | return Option.match(decodeJsonRpcMethods(body), { |
| 284 | onNone: () => false, |
| 285 | onSome: (parsed) => { |
| 286 | const messages = Array.isArray(parsed) ? parsed : [parsed]; |
| 287 | return ( |
| 288 | messages.length > 0 && |
| 289 | messages.every((message) => REPLAYABLE_JSONRPC_METHODS.has(message.method)) |
| 290 | ); |
| 291 | }, |
| 292 | }); |
| 293 | }; |
| 294 | |
| 295 | const fetchFromHttpClientLayer = ( |
| 296 | httpClientLayer: Layer.Layer<HttpClient.HttpClient>, |
no test coverage detected