fix(code-queue): run hyueapi codex app server direct
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
// 重构前 index.ts 只读参考:commit 6a04144d3f5103014f75b637d7e6bc2f45bf007f,blob 56e590c1a6b5ca7ad128bf2c992f60e46c355a58;可用 `git show 6a04144d3f5103014f75b637d7e6bc2f45bf007f:src/components/microservices/code-queue/src/index.ts` 查看。
|
||||
|
||||
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import * as readline from "node:readline";
|
||||
import type { AppServerExit, CodexEventSummary, CodexRunResult, JsonValue, QueueTask, RuntimeConfig, SessionCommandOutput, TerminalStatus } from "../types";
|
||||
import type { ActiveRun, CodeAgentClient } from "./common";
|
||||
import { extractRecord, extractString, terminalStatus, textInput } from "./common";
|
||||
|
||||
export interface CodexPortContext {
|
||||
config: Pick<RuntimeConfig, "approvalPolicy" | "codexHome" | "defaultWorkdir" | "sandbox" | "turnNoActivityTimeoutMs">;
|
||||
config: Pick<RuntimeConfig, "approvalPolicy" | "codexHome" | "defaultWorkdir" | "sandbox" | "sourceCodexConfig" | "turnNoActivityTimeoutMs">;
|
||||
activeRuns: Map<string, ActiveRun>;
|
||||
appendOutput: (task: QueueTask, channel: "system" | "assistant" | "reasoning" | "command" | "diff" | "tool" | "error", text: string, method?: string, itemId?: string, append?: boolean) => unknown;
|
||||
addEvent: (task: QueueTask, event: CodexEventSummary) => void;
|
||||
@@ -49,6 +50,62 @@ function appServerCwdForTask(task: QueueTask): string {
|
||||
return task.executionMode === "windows-native" ? windowsPathFromWslMount(task.cwd) : task.cwd;
|
||||
}
|
||||
|
||||
const codexProxyEnvKeys = ["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"];
|
||||
const defaultCodexDirectHosts = ["hyueapi.com", ".hyueapi.com"];
|
||||
|
||||
function splitEnvList(value: string | undefined, fallback: string[]): string[] {
|
||||
const raw = value === undefined || value.trim().length === 0 ? fallback : value.split(",");
|
||||
return Array.from(new Set(raw.map((item) => item.trim().toLowerCase()).filter(Boolean)));
|
||||
}
|
||||
|
||||
function directHostNeedle(host: string): string {
|
||||
return host.replace(/^\./u, "").toLowerCase();
|
||||
}
|
||||
|
||||
function readTextIfPresent(path: string): string {
|
||||
try {
|
||||
return existsSync(path) ? readFileSync(path, "utf8") : "";
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function codexNetworkConfigText(): string {
|
||||
return [
|
||||
"OPENAI_BASE_URL",
|
||||
"OPENAI_API_BASE",
|
||||
"OPENAI_RESPONSES_URL",
|
||||
"CODEX_OPENAI_BASE_URL",
|
||||
"CODEX_BASE_URL",
|
||||
].map((key) => process.env[key] ?? "").concat([
|
||||
readTextIfPresent(`${ctx().config.codexHome.replace(/\/+$/u, "")}/config.toml`),
|
||||
readTextIfPresent(ctx().config.sourceCodexConfig),
|
||||
]).join("\n").toLowerCase();
|
||||
}
|
||||
|
||||
function shouldRunCodexDirect(): boolean {
|
||||
const configText = codexNetworkConfigText();
|
||||
if (configText.length === 0) return false;
|
||||
return splitEnvList(process.env.CODE_QUEUE_CODEX_DIRECT_HOSTS, defaultCodexDirectHosts)
|
||||
.some((host) => configText.includes(directHostNeedle(host)));
|
||||
}
|
||||
|
||||
function codexAppServerEnv(task: QueueTask): NodeJS.ProcessEnv {
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
CODEX_HOME: ctx().config.codexHome,
|
||||
CODEX_INTERNAL_ORIGINATOR_OVERRIDE: "unidesk_code_queue",
|
||||
};
|
||||
if (!shouldRunCodexDirect()) return env;
|
||||
for (const key of codexProxyEnvKeys) delete env[key];
|
||||
const directHosts = splitEnvList(process.env.CODE_QUEUE_CODEX_DIRECT_HOSTS, defaultCodexDirectHosts).join(",");
|
||||
env.NO_PROXY = [env.NO_PROXY, directHosts].filter((part) => part !== undefined && part.length > 0).join(",");
|
||||
env.no_proxy = [env.no_proxy, directHosts].filter((part) => part !== undefined && part.length > 0).join(",");
|
||||
ctx().appendOutput(task, "system", `codex app-server direct network enabled for ${directHosts}\n`, "codex/network");
|
||||
ctx().logger("info", "codex_app_server_direct_network", { taskId: task.id, directHosts });
|
||||
return env;
|
||||
}
|
||||
|
||||
class AppServerClient {
|
||||
private child: ChildProcessWithoutNullStreams;
|
||||
private nextId = 1;
|
||||
@@ -67,7 +124,7 @@ class AppServerClient {
|
||||
this.child = ctx().providerIsMain(task.providerId)
|
||||
? spawn("codex", ["app-server", "--listen", "stdio://"], {
|
||||
cwd: task.cwd,
|
||||
env: { ...process.env, CODEX_HOME: ctx().config.codexHome, CODEX_INTERNAL_ORIGINATOR_OVERRIDE: "unidesk_code_queue" },
|
||||
env: codexAppServerEnv(task),
|
||||
stdio: "pipe",
|
||||
})
|
||||
: spawn("bun", ["scripts/cli.ts", "ssh", task.providerId, remoteCommand], {
|
||||
|
||||
Reference in New Issue
Block a user