


























@@ -25,6 +25,7 @@ import { MIN_CODEX_APP_SERVER_VERSION } from "./version.js";
25252626export { MIN_CODEX_APP_SERVER_VERSION } from "./version.js";
2727const CODEX_APP_SERVER_PARSE_LOG_MAX = 500;
28+const CODEX_DYNAMIC_TOOL_SERVER_REQUEST_TIMEOUT_MS = 30_000;
28292930type PendingRequest = {
3031method: string;
@@ -251,7 +252,13 @@ export class CodexAppServerClient {
251252if (this.closed) {
252253return;
253254}
254-this.child.stdin.write(`${JSON.stringify(message)}\n`);
255+const id = "id" in message ? message.id : undefined;
256+const method = "method" in message ? message.method : undefined;
257+this.child.stdin.write(`${JSON.stringify(message)}\n`, (error?: Error | null) => {
258+if (error) {
259+embeddedAgentLog.warn("codex app-server write failed", { error, id, method });
260+}
261+});
255262}
256263257264private handleLine(line: string): void {
@@ -311,12 +318,10 @@ export class CodexAppServerClient {
311318request: Required<Pick<RpcRequest, "id" | "method">> & { params?: JsonValue },
312319): Promise<void> {
313320try {
314-for (const handler of this.requestHandlers) {
315-const result = await handler(request);
316-if (result !== undefined) {
317-this.writeMessage({ id: request.id, result });
318-return;
319-}
321+const result = await this.runServerRequestHandlers(request);
322+if (result !== undefined) {
323+this.writeMessage({ id: request.id, result });
324+return;
320325}
321326this.writeMessage({ id: request.id, result: defaultServerRequestResponse(request) });
322327} catch (error) {
@@ -329,6 +334,49 @@ export class CodexAppServerClient {
329334}
330335}
331336337+private async runServerRequestHandlers(
338+request: Required<Pick<RpcRequest, "id" | "method">> & { params?: JsonValue },
339+): Promise<JsonValue | undefined> {
340+const timeoutResponse = timeoutServerRequestResponse(request);
341+if (!timeoutResponse) {
342+return await this.runServerRequestHandlersWithoutTimeout(request);
343+}
344+345+let timeout: ReturnType<typeof setTimeout> | undefined;
346+try {
347+return await Promise.race([
348+this.runServerRequestHandlersWithoutTimeout(request),
349+new Promise<JsonValue>((resolve) => {
350+timeout = setTimeout(() => {
351+embeddedAgentLog.warn("codex app-server server request timed out", {
352+id: request.id,
353+method: request.method,
354+timeoutMs: CODEX_DYNAMIC_TOOL_SERVER_REQUEST_TIMEOUT_MS,
355+});
356+resolve(timeoutResponse);
357+}, CODEX_DYNAMIC_TOOL_SERVER_REQUEST_TIMEOUT_MS);
358+timeout.unref?.();
359+}),
360+]);
361+} finally {
362+if (timeout) {
363+clearTimeout(timeout);
364+}
365+}
366+}
367+368+private async runServerRequestHandlersWithoutTimeout(
369+request: Required<Pick<RpcRequest, "id" | "method">> & { params?: JsonValue },
370+): Promise<JsonValue | undefined> {
371+for (const handler of this.requestHandlers) {
372+const result = await handler(request);
373+if (result !== undefined) {
374+return result;
375+}
376+}
377+return undefined;
378+}
379+332380private handleNotification(notification: CodexServerNotification): void {
333381for (const handler of this.notificationHandlers) {
334382Promise.resolve(handler(notification)).catch((error: unknown) => {
@@ -407,6 +455,23 @@ export function defaultServerRequestResponse(
407455return {};
408456}
409457458+function timeoutServerRequestResponse(
459+request: Required<Pick<RpcRequest, "id" | "method">> & { params?: JsonValue },
460+): JsonValue | undefined {
461+if (request.method !== "item/tool/call") {
462+return undefined;
463+}
464+return {
465+contentItems: [
466+{
467+type: "inputText",
468+text: `OpenClaw dynamic tool call timed out after ${CODEX_DYNAMIC_TOOL_SERVER_REQUEST_TIMEOUT_MS}ms before sending a response to Codex.`,
469+},
470+],
471+success: false,
472+};
473+}
474+410475function assertSupportedCodexAppServerVersion(response: CodexInitializeResponse): void {
411476const detectedVersion = readCodexVersionFromUserAgent(response.userAgent);
412477if (!detectedVersion) {
@@ -505,5 +570,6 @@ function formatExitValue(value: unknown): string {
505570export const __testing = {
506571 closeCodexAppServerTransport,
507572 closeCodexAppServerTransportAndWait,
573+CODEX_DYNAMIC_TOOL_SERVER_REQUEST_TIMEOUT_MS,
508574 redactCodexAppServerLinePreview,
509575} as const;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。