feat: discover codex app-server capabilities

This commit is contained in:
AI Bot
2026-05-31 03:44:02 +08:00
parent 4800352e22
commit f333676c36
16 changed files with 662 additions and 5 deletions

View File

@@ -8,6 +8,7 @@ import { delimiter, isAbsolute, join, resolve } from "node:path";
import { discoverCodexProjectCandidatesInWorker } from "./codex-session-discovery.mjs";
import { prepareCodexTaskExecution } from "./codex-task-runner.mjs";
import {
discoverCodexAppServerCapabilities,
executeCodexAppServerTask,
getCodexAppServerRunnerConfig,
shouldUseCodexAppServerTaskRunner,
@@ -132,6 +133,12 @@ async function postHeartbeat(config, runtime, heartbeatProjects) {
const codexAppServerRuntime = getCodexAppServerRunnerConfig(process.env, config);
const computerUseConnected = await resolveComputerUseCapabilityConnected(config, computerUseRuntime);
const codexAppServerConnected = await resolveCodexAppServerCapabilityConnected(codexAppServerRuntime);
const codexAppServerMetadata = await resolveCodexAppServerCapabilityMetadata(
config,
runtime,
codexAppServerRuntime,
codexAppServerConnected,
);
const guiConnected =
config.guiConnected === true ||
(config.guiConnected !== false && heartbeatProjects.guiConnected === true);
@@ -173,6 +180,7 @@ async function postHeartbeat(config, runtime, heartbeatProjects) {
connected: codexAppServerConnected,
lastSeenAt: now,
lastActiveProjectId: "",
metadata: codexAppServerMetadata,
},
},
preferredExecutionMode,
@@ -261,6 +269,40 @@ async function resolveCodexAppServerCapabilityConnected(codexAppServerRuntime) {
return canExecuteCommand(codexAppServerRuntime.command, codexAppServerRuntime.cwd || process.cwd());
}
async function resolveCodexAppServerCapabilityMetadata(config, runtime, codexAppServerRuntime, connected) {
if (!connected || !codexAppServerRuntime?.enabled || codexAppServerRuntime.discoveryEnabled === false) {
return undefined;
}
const now = Date.now();
const ttlMs = codexAppServerRuntime.discoveryTtlMs ?? 300_000;
if (
runtime.codexAppServerCapabilityMetadata &&
runtime.codexAppServerCapabilityMetadataAtMs &&
now - runtime.codexAppServerCapabilityMetadataAtMs < ttlMs
) {
return runtime.codexAppServerCapabilityMetadata;
}
try {
const metadata = await discoverCodexAppServerCapabilities(codexAppServerRuntime);
runtime.codexAppServerCapabilityMetadata = metadata;
runtime.codexAppServerCapabilityMetadataAtMs = now;
runtime.codexAppServerCapabilityMetadataError = "";
return metadata;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
runtime.codexAppServerCapabilityMetadataError = message;
await postAppLog(config, runtime, {
level: "warn",
category: "local_agent.codex_app_server_capability_discovery_failed",
message: "Codex App Server 能力清单发现失败,设备心跳继续上报连接状态。",
detail: message,
mirrorToMaster: false,
});
return runtime.codexAppServerCapabilityMetadata;
}
}
function deviceTokenHeaders(config, runtime) {
const token = runtime.issuedToken ?? config.token;
return token ? { "x-boss-device-token": token } : {};