feat: adapt codex app-server protocol updates
This commit is contained in:
@@ -249,7 +249,13 @@ async function resolveComputerUseCapabilityConnected(config, computerUseRuntime)
|
||||
}
|
||||
|
||||
async function resolveCodexAppServerCapabilityConnected(codexAppServerRuntime) {
|
||||
if (!codexAppServerRuntime?.enabled || !codexAppServerRuntime.command) {
|
||||
if (!codexAppServerRuntime?.enabled) {
|
||||
return false;
|
||||
}
|
||||
if (codexAppServerRuntime.transport === "ws" || codexAppServerRuntime.transport === "unix") {
|
||||
return Boolean(codexAppServerRuntime.url);
|
||||
}
|
||||
if (!codexAppServerRuntime.command) {
|
||||
return false;
|
||||
}
|
||||
return canExecuteCommand(codexAppServerRuntime.command, codexAppServerRuntime.cwd || process.cwd());
|
||||
@@ -452,6 +458,31 @@ async function completeMasterAgentTask(config, runtime, payload) {
|
||||
};
|
||||
}
|
||||
|
||||
async function postMasterAgentTaskProgress(config, runtime, payload) {
|
||||
const response = await fetch(
|
||||
`${config.controlPlaneUrl.replace(/\/$/, "")}/api/v1/master-agent/tasks/${payload.taskId}/progress`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...deviceTokenHeaders(config, runtime),
|
||||
},
|
||||
body: JSON.stringify({
|
||||
deviceId: config.deviceId,
|
||||
status: payload.status || "running",
|
||||
requestId: payload.requestId,
|
||||
executionProgress: payload.executionProgress,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
return {
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
body: await response.text(),
|
||||
};
|
||||
}
|
||||
|
||||
async function claimSkillLifecycleRequest(config, runtime) {
|
||||
const response = await fetch(
|
||||
`${config.controlPlaneUrl.replace(/\/$/, "")}/api/v1/devices/${config.deviceId}/skill-requests/claim`,
|
||||
@@ -617,6 +648,45 @@ async function collectLocalExecutionProgress(cwd, replyBody) {
|
||||
};
|
||||
}
|
||||
|
||||
function mergeExecutionProgress(primary, secondary) {
|
||||
const first = primary && typeof primary === "object" ? primary : {};
|
||||
const second = secondary && typeof secondary === "object" ? secondary : {};
|
||||
const artifacts = [];
|
||||
const seenArtifacts = new Set();
|
||||
for (const artifact of [...(first.artifacts || []), ...(second.artifacts || [])]) {
|
||||
const label = String(artifact?.label || "").trim();
|
||||
if (!label || seenArtifacts.has(label)) {
|
||||
continue;
|
||||
}
|
||||
seenArtifacts.add(label);
|
||||
artifacts.push(artifact);
|
||||
}
|
||||
const agents = [];
|
||||
const seenAgents = new Set();
|
||||
for (const agent of [...(first.agents || []), ...(second.agents || [])]) {
|
||||
const name = String(agent?.name || "").trim();
|
||||
const key = `${name}:${String(agent?.role || "").trim()}`;
|
||||
if (!name || seenAgents.has(key)) {
|
||||
continue;
|
||||
}
|
||||
seenAgents.add(key);
|
||||
agents.push(agent);
|
||||
}
|
||||
return {
|
||||
...(second || {}),
|
||||
...(first || {}),
|
||||
branch:
|
||||
first.branch || second.branch
|
||||
? {
|
||||
...(second.branch || {}),
|
||||
...(first.branch || {}),
|
||||
}
|
||||
: undefined,
|
||||
artifacts: artifacts.length > 0 ? artifacts : undefined,
|
||||
agents: agents.length > 0 ? agents : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async function runMasterAgentTask(config, runtime, task) {
|
||||
const outputFile = join(os.tmpdir(), `${task.taskId}.reply.txt`);
|
||||
const stderrChunks = [];
|
||||
@@ -678,12 +748,38 @@ async function runMasterAgentTask(config, runtime, task) {
|
||||
|
||||
const codexAppServerRunner = getCodexAppServerRunnerConfig(process.env, config);
|
||||
if (shouldUseCodexAppServerTaskRunner(codexAppServerRunner, task)) {
|
||||
const appServerResult = await executeCodexAppServerTask(codexAppServerRunner, task);
|
||||
const appServerResult = await executeCodexAppServerTask(
|
||||
{
|
||||
...codexAppServerRunner,
|
||||
onProgress: async (executionProgress) => {
|
||||
const progressResult = await postMasterAgentTaskProgress(config, runtime, {
|
||||
taskId: task.taskId,
|
||||
status: "running",
|
||||
executionProgress,
|
||||
});
|
||||
if (!progressResult.ok) {
|
||||
await postAppLog(config, runtime, {
|
||||
projectId: task.projectId,
|
||||
level: "warn",
|
||||
category: "local_agent.codex_app_server_progress_failed",
|
||||
message: "Codex App Server 进度实时回写失败,完成回写仍会携带最终进度。",
|
||||
detail: progressResult.body,
|
||||
mirrorToMaster: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
task,
|
||||
);
|
||||
if (appServerResult.status === "completed") {
|
||||
const executionProgress = await collectLocalExecutionProgress(
|
||||
const localExecutionProgress = await collectLocalExecutionProgress(
|
||||
appServerResult.cwd || task.targetCodexFolderRef || config.masterAgentWorkdir || process.cwd(),
|
||||
appServerResult.replyBody,
|
||||
);
|
||||
const executionProgress = mergeExecutionProgress(
|
||||
appServerResult.executionProgress,
|
||||
localExecutionProgress,
|
||||
);
|
||||
try {
|
||||
if (task.targetCodexThreadRef || task.targetThreadId) {
|
||||
await executeCodexDesktopRefreshBridge(
|
||||
|
||||
Reference in New Issue
Block a user