@@ -54,6 +54,14 @@ const MCP_CONNECT_TIMEOUT_MS = readPositiveInt(
|
54 | 54 | process.env.OPENCLAW_MCP_CHANNELS_CONNECT_TIMEOUT_MS, |
55 | 55 | 60_000, |
56 | 56 | ); |
| 57 | +const GATEWAY_EVENT_RETAIN_LIMIT = readPositiveInt( |
| 58 | +process.env.OPENCLAW_MCP_CHANNELS_GATEWAY_EVENT_RETAIN_LIMIT, |
| 59 | +2_000, |
| 60 | +); |
| 61 | +const MCP_RAW_MESSAGE_RETAIN_LIMIT = readPositiveInt( |
| 62 | +process.env.OPENCLAW_MCP_CHANNELS_RAW_MESSAGE_RETAIN_LIMIT, |
| 63 | +2_000, |
| 64 | +); |
57 | 65 | |
58 | 66 | export function assert(condition: unknown, message: string): asserts condition { |
59 | 67 | if (!condition) { |
@@ -66,6 +74,13 @@ function readPositiveInt(raw: string | undefined, fallback: number) {
|
66 | 74 | return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback; |
67 | 75 | } |
68 | 76 | |
| 77 | +function pushBounded<T>(items: T[], item: T, limit: number): void { |
| 78 | +items.push(item); |
| 79 | +if (items.length > limit) { |
| 80 | +items.splice(0, items.length - limit); |
| 81 | +} |
| 82 | +} |
| 83 | + |
69 | 84 | export function extractTextFromGatewayPayload( |
70 | 85 | payload: Record<string, unknown> | undefined, |
71 | 86 | ): string | undefined { |
@@ -164,13 +179,17 @@ async function connectGatewayOnce(params: {
|
164 | 179 | error?: { message?: unknown } | null; |
165 | 180 | }; |
166 | 181 | if (typed.type === "event" && typeof typed.event === "string") { |
167 | | -events.push({ |
168 | | -event: typed.event, |
169 | | -payload: |
170 | | -typed.payload && typeof typed.payload === "object" |
171 | | - ? (typed.payload as Record<string, unknown>) |
172 | | - : {}, |
173 | | -}); |
| 182 | +pushBounded( |
| 183 | +events, |
| 184 | +{ |
| 185 | +event: typed.event, |
| 186 | +payload: |
| 187 | +typed.payload && typeof typed.payload === "object" |
| 188 | + ? (typed.payload as Record<string, unknown>) |
| 189 | + : {}, |
| 190 | +}, |
| 191 | +GATEWAY_EVENT_RETAIN_LIMIT, |
| 192 | +); |
174 | 193 | return; |
175 | 194 | } |
176 | 195 | if (typed.type !== "res" || typeof typed.id !== "string") { |
@@ -336,7 +355,7 @@ export async function connectMcpClient(params: {
|
336 | 355 | // runtime, not an EventTarget-style addEventListener API. |
337 | 356 | // oxlint-disable-next-line unicorn/prefer-add-event-listener |
338 | 357 | transport.onmessage = (message) => { |
339 | | -rawMessages.push(message); |
| 358 | +pushBounded(rawMessages, message, MCP_RAW_MESSAGE_RETAIN_LIMIT); |
340 | 359 | }; |
341 | 360 | |
342 | 361 | const client = new Client({ name: "docker-mcp-channels", version: "1.0.0" }); |
|