import { createInterface, type Interface as ReadlineInterface } from "node:readline"; import { embeddedAgentLog, OPENCLAW_VERSION } from "openclaw/plugin-sdk/agent-harness-runtime"; import { resolveCodexAppServerRuntimeOptions, type CodexAppServerStartOptions } from "./config.js"; import {
type CodexAppServerRequestMethod,
type CodexAppServerRequestParams,
type CodexAppServerRequestResult,
type CodexInitializeParams,
type CodexInitializeResponse,
isRpcResponse,
type CodexServerNotification,
type JsonValue,
type RpcMessage,
type RpcRequest,
type RpcResponse,
} from "./protocol.js"; import { createStdioTransport } from "./transport-stdio.js"; import { createWebSocketTransport } from "./transport-websocket.js"; import { closeCodexAppServerTransport, type CodexAppServerTransport } from "./transport.js";
private rejectPendingRequests(error: Error): void { for (const pending of this.pending.values()) {
pending.cleanup();
pending.reject(error);
} this.pending.clear(); for (const handler of this.closeHandlers) {
handler(this);
}
}
}
export function defaultServerRequestResponse(
request: Required<Pick<RpcRequest, "id" | "method">> & { params?: JsonValue },
): JsonValue { if (request.method === "item/tool/call") { return {
contentItems: [
{
type: "inputText",
text: "OpenClaw did not register a handler for this app-server tool call.",
},
],
success: false,
};
} if (
request.method === "item/commandExecution/requestApproval" ||
request.method === "item/fileChange/requestApproval"
) { return { decision: "decline" };
} if (request.method === "item/permissions/requestApproval") { return { permissions: {}, scope: "turn" };
} if (isCodexAppServerApprovalRequest(request.method)) { return {
decision: "decline",
reason: "OpenClaw codex app-server bridge does not grant native approvals yet.",
};
} if (request.method === "item/tool/requestUserInput") { return {
answers: {},
};
} if (request.method === "mcpServer/elicitation/request") { return {
action: "decline",
};
} return {};
}
function assertSupportedCodexAppServerVersion(response: CodexInitializeResponse): void { const detectedVersion = readCodexVersionFromUserAgent(response.userAgent); if (!detectedVersion) { thrownew Error(
`Codex app-server ${MIN_CODEX_APP_SERVER_VERSION} or newer is required, but OpenClaw could not determine the running Codex version. Upgrade Codex CLI and retry.`,
);
} if (compareVersions(detectedVersion, MIN_CODEX_APP_SERVER_VERSION) < 0) { thrownew Error(
`Codex app-server ${MIN_CODEX_APP_SERVER_VERSION} or newer is required, but detected ${detectedVersion}. Upgrade Codex CLI and retry.`,
);
}
}
export function readCodexVersionFromUserAgent(userAgent: string | undefined): string | undefined { // Codex returns `<originator>/<codex-version> ...`; the originator can be // OpenClaw, Codex Desktop, or an env override, so only the slash-delimited // version in the leading product field is stable. const match = userAgent?.match(
/^[^/]+\/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)(?:[\s(]|$)/,
); return match?.[1];
}
function compareVersions(left: string, right: string): number { const leftParts = numericVersionParts(left); const rightParts = numericVersionParts(right); for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) { const leftPart = leftParts[index] ?? 0; const rightPart = rightParts[index] ?? 0; if (leftPart !== rightPart) { return leftPart < rightPart ? -1 : 1;
}
} return0;
}
function numericVersionParts(version: string): number[] { // Pre-release/build tags do not affect our minimum gate; 0.118.0-dev should // satisfy the same protocol floor as 0.118.0. return version
.split(/[+-]/, 1)[0]
.split(".")
.map((part) => Number.parseInt(part, 10))
.map((part) => (Number.isFinite(part) ? part : 0));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.