History

Merge remote-tracking branch 'origin/codex/effect-lint-cloud-mcp-worker-transport' into codex/effect-lint-integration

Rhys Sullivan committed 6 months ago

Commit 85ff2a72 parents a8c4b45 15b056b1 file · +23 −15Browse files

Unified · Split

apps/cloud/src/services/mcp-worker-transport.ts+23−15
@@ -1,6 +1,6 @@
1import { WorkerTransport, type WorkerTransportOptions } from "agents/mcp";1import { WorkerTransport, type WorkerTransportOptions } from "agents/mcp";
2import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";2import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3import { Data, Effect } from "effect";3import { Data, Effect, Exit } from "effect";
4 4
5export class McpWorkerTransportError extends Data.TaggedError("McpWorkerTransportError")<{5export class McpWorkerTransportError extends Data.TaggedError("McpWorkerTransportError")<{
6 readonly cause: unknown;6 readonly cause: unknown;
@@ -64,19 +64,20 @@ const extractJsonRpcRequestIdKeys = async (request: Request): Promise<ReadonlyAr · 57 unmodified lines
64 const contentType = request.headers.get("content-type") ?? "";64 const contentType = request.headers.get("content-type") ?? "";
65 if (!contentType.includes("application/json")) return [];65 if (!contentType.includes("application/json")) return [];
66 66
67 try {67 const parsed = await Effect.runPromiseExit(
68 const parsed = (await request.clone().json()) as unknown;68 Effect.tryPromise(() => request.clone().json()),
69 const messages = Array.isArray(parsed) ? parsed : [parsed];69 );
70 return messages.flatMap((message) => {70 if (Exit.isFailure(parsed)) {
71 if (!message || typeof message !== "object") return [];
72 const rpc = message as JsonRpcLike;
73 if (typeof rpc.method !== "string") return [];
74 const key = jsonRpcRequestIdKey(rpc.id);
75 return key ? [key] : [];
76 });
77 } catch {
78 return [];71 return [];
79 }72 }
73 const messages = Array.isArray(parsed.value) ? parsed.value : [parsed.value];
74 return messages.flatMap((message) => {
75 if (!message || typeof message !== "object") return [];
76 const rpc = message as JsonRpcLike;
77 if (typeof rpc.method !== "string") return [];
78 const key = jsonRpcRequestIdKey(rpc.id);
79 return key ? [key] : [];
80 });
80};81};
81 82
82// Hard ceiling on how long a same-id JSON-RPC request will wait for an83// Hard ceiling on how long a same-id JSON-RPC request will wait for an
@@ -109,9 +110,12 @@ export class JsonRpcRequestIdQueue { · 26 unmodified lines
109 this.inFlight.set(id, current);110 this.inFlight.set(id, current);
110 }111 }
111 112
113 // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: promise queue must release in-flight ids after callback completion
112 try {114 try {
113 if (previous.length > 0) {115 if (previous.length > 0) {
114 const settled = Promise.all(previous.map((p) => p.catch(() => undefined)));116 const settled = Promise.all(
117 previous.map((p) => Effect.runPromise(Effect.ignore(Effect.tryPromise(() => p)))),
118 );
115 const timeout = new Promise<"timeout">((resolve) =>119 const timeout = new Promise<"timeout">((resolve) =>
116 setTimeout(() => resolve("timeout"), this.previousTimeoutMs),120 setTimeout(() => resolve("timeout"), this.previousTimeoutMs),
117 );121 );
@@ -183,9 +187,13 @@ export const makeMcpWorkerTransport = ( · 65 unmodified lines
183 return result.response;187 return result.response;
184 }),188 }),
185 close: () =>189 close: () =>
186 Effect.promise(() => transport.close().catch(() => undefined)).pipe(190 Effect.ignore(
191 Effect.tryPromise({
192 try: () => transport.close(),
193 catch: (cause) => new McpWorkerTransportError({ cause }),
194 }),
195 ).pipe(
187 Effect.withSpan("mcp.worker_transport.close"),196 Effect.withSpan("mcp.worker_transport.close"),
188 Effect.orDie,
189 ),197 ),
190 } satisfies McpWorkerTransport;198 } satisfies McpWorkerTransport;
191 }).pipe(Effect.withSpan("mcp.worker_transport.make"));199 }).pipe(Effect.withSpan("mcp.worker_transport.make"));