feat: move code queue to d601
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -42,18 +42,18 @@ const ROUTE_REGISTRY = createRouteRegistry(MODULES);
|
||||
const fastCodeQueueService = {
|
||||
id: "code-queue",
|
||||
name: "Code Queue",
|
||||
providerId: "main-server",
|
||||
providerId: "D601",
|
||||
description: "Code Queue",
|
||||
repository: { containerName: "code-queue-backend" },
|
||||
backend: {
|
||||
nodeBaseUrl: "http://code-queue:4222",
|
||||
nodeBindHost: "code-queue",
|
||||
nodeBaseUrl: "http://host.docker.internal:4222",
|
||||
nodeBindHost: "127.0.0.1",
|
||||
nodePort: 4222,
|
||||
public: false,
|
||||
},
|
||||
runtime: {
|
||||
providerStatus: "loading",
|
||||
providerName: "main-server",
|
||||
providerName: "D601",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -29,18 +29,18 @@ const apiBaseUrl = String(clientConfig.apiBaseUrl || "/api");
|
||||
const standaloneCodeQueueService = {
|
||||
id: "code-queue",
|
||||
name: "Code Queue",
|
||||
providerId: "main-server",
|
||||
providerId: "D601",
|
||||
description: "Code Queue 独立入口,使用 summary 首屏和按需全量加载保持信息完整。",
|
||||
repository: { containerName: "code-queue-backend" },
|
||||
backend: {
|
||||
nodeBaseUrl: "http://code-queue:4222",
|
||||
nodeBindHost: "code-queue",
|
||||
nodeBaseUrl: "http://host.docker.internal:4222",
|
||||
nodeBindHost: "127.0.0.1",
|
||||
nodePort: 4222,
|
||||
public: false,
|
||||
},
|
||||
runtime: {
|
||||
providerStatus: "online",
|
||||
providerName: "main-server",
|
||||
providerName: "D601",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1253,11 +1253,11 @@ function codexProviderOptions(queue: any, currentProviderId: string): any[] {
|
||||
kind: String(item?.kind || "").trim(),
|
||||
}))
|
||||
.filter((item: any) => item.id.length > 0);
|
||||
const fallbackMain = String(queue?.mainProviderId || queue?.defaultProviderId || "main-server").trim() || "main-server";
|
||||
const fallbackMain = String(queue?.mainProviderId || queue?.defaultProviderId || "D601").trim() || "D601";
|
||||
const byId = new Map<string, any>();
|
||||
for (const item of [
|
||||
...rows,
|
||||
{ id: fallbackMain, label: `${fallbackMain} (master)`, defaultWorkdir: String(queue?.defaultWorkdir || "/root/unidesk"), supportsWindowsNativeCodex: false, windowsNativeDefaultWorkdir: "", kind: "local" },
|
||||
{ id: fallbackMain, label: `${fallbackMain} (local)`, defaultWorkdir: String(queue?.defaultWorkdir || "/workspace"), supportsWindowsNativeCodex: false, windowsNativeDefaultWorkdir: "", kind: "local" },
|
||||
currentProviderId ? { id: currentProviderId, label: currentProviderId, defaultWorkdir: providerDefaultWorkdir(queue, currentProviderId), supportsWindowsNativeCodex: currentProviderId !== fallbackMain, windowsNativeDefaultWorkdir: String(queue?.windowsNativeCodexDefaultWorkdir || "/mnt/f/Work/ConStart"), kind: "" } : null,
|
||||
].filter(Boolean) as any[]) {
|
||||
if (!byId.has(item.id)) byId.set(item.id, item);
|
||||
@@ -1278,7 +1278,7 @@ function codexExecutionModeOptions(queue: any, currentMode: string): any[] {
|
||||
}))
|
||||
.filter((item: any) => item.id.length > 0);
|
||||
const fallback = [
|
||||
{ id: "default", label: "默认容器/本机", description: "主 server 用本机 Codex;远程 Provider 用执行容器 Codex。", defaultWorkdir: "", requiresProvider: false, requiresWindowsCwd: false },
|
||||
{ id: "default", label: "默认容器/本机", description: "Code Queue 所在节点用本机 Codex;远程 Provider 用执行容器 Codex。", defaultWorkdir: "", requiresProvider: false, requiresWindowsCwd: false },
|
||||
{ id: "windows-native", label: "Windows 原生 Codex", description: "启动执行容器,但容器只做 stdio relay,Codex 运行在 Provider 的 Windows 宿主。", defaultWorkdir: String(queue?.windowsNativeCodexDefaultWorkdir || "/mnt/f/Work/ConStart"), requiresProvider: true, requiresWindowsCwd: true },
|
||||
];
|
||||
const byId = new Map<string, any>();
|
||||
@@ -1301,8 +1301,8 @@ function providerDefaultWorkdir(queue: any, providerId: string): string {
|
||||
if (typeof map[id] === "string" && String(map[id]).trim().length > 0) return String(map[id]).trim();
|
||||
const option = Array.isArray(queue?.executionProviders) ? queue.executionProviders.find((item: any) => String(item?.id || "") === id) : null;
|
||||
if (typeof option?.defaultWorkdir === "string" && option.defaultWorkdir.trim().length > 0) return option.defaultWorkdir.trim();
|
||||
const mainProvider = String(queue?.mainProviderId || queue?.defaultProviderId || "main-server");
|
||||
return id === mainProvider ? String(queue?.defaultWorkdir || "/root/unidesk") : String(queue?.remoteDefaultWorkdir || "/home/ubuntu");
|
||||
const mainProvider = String(queue?.mainProviderId || queue?.defaultProviderId || "D601");
|
||||
return id === mainProvider ? String(queue?.defaultWorkdir || "/workspace") : String(queue?.remoteDefaultWorkdir || "/home/ubuntu");
|
||||
}
|
||||
|
||||
function taskStepCount(task: any): number | null {
|
||||
@@ -1375,7 +1375,7 @@ function TaskCard({ task, selected, onSelect, onCopy, onReference, onMarkRead, c
|
||||
h("strong", null, shortText(taskDisplayPrompt(task), 120) || "空任务"),
|
||||
h("div", { className: "codex-task-meta" },
|
||||
h("span", null, `queue=${taskQueueLabel(task)}`),
|
||||
h("span", null, `provider=${task?.providerId || "main-server"}`),
|
||||
h("span", null, `provider=${task?.providerId || "D601"}`),
|
||||
h("span", null, `mode=${task?.executionMode || "default"}`),
|
||||
h("span", null, task?.model || "--"),
|
||||
h("span", null, taskDurationLabel(task)),
|
||||
@@ -1952,16 +1952,18 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
const [searchTasksData, setSearchTasksData] = useState(null);
|
||||
const [searchLoading, setSearchLoading] = useState(false);
|
||||
const [searchLoadingMoreTasks, setSearchLoadingMoreTasks] = useState(false);
|
||||
const initialQueueConfig = initialTasksData?.queue || {};
|
||||
const initialProviderId = String(initialQueueConfig?.mainProviderId || initialQueueConfig?.defaultProviderId || "D601").trim() || "D601";
|
||||
const [prompt, setPrompt] = useState("");
|
||||
const [referenceTaskId, setReferenceTaskId] = useState("");
|
||||
const [queueId, setQueueId] = useState("default");
|
||||
const [selectedQueueId, setSelectedQueueId] = useState(allQueuesId);
|
||||
const [mergeDialogOpen, setMergeDialogOpen] = useState(false);
|
||||
const [mergeSourceQueueId, setMergeSourceQueueId] = useState("");
|
||||
const [providerId, setProviderId] = useState("main-server");
|
||||
const [providerId, setProviderId] = useState(initialProviderId);
|
||||
const [executionMode, setExecutionMode] = useState("default");
|
||||
const [model, setModel] = useState("gpt-5.5");
|
||||
const [cwd, setCwd] = useState("/root/unidesk");
|
||||
const [cwd, setCwd] = useState(executionModeDefaultWorkdir(initialQueueConfig, "default", initialProviderId) || "/workspace");
|
||||
const [maxAttempts, setMaxAttempts] = useState(99);
|
||||
const [repeatCount, setRepeatCount] = useState(1);
|
||||
const [batchConfirmed, setBatchConfirmed] = useState(false);
|
||||
@@ -2108,7 +2110,7 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
}
|
||||
|
||||
function changeSubmitProvider(nextProviderId: string): void {
|
||||
const next = String(nextProviderId || queue?.mainProviderId || "main-server").trim() || "main-server";
|
||||
const next = String(nextProviderId || queue?.mainProviderId || "D601").trim() || "D601";
|
||||
setProviderId(next);
|
||||
setCwd(executionModeDefaultWorkdir(queue, executionMode, next));
|
||||
}
|
||||
@@ -3383,7 +3385,7 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
h("span", { className: "codex-trace-status-chip queued" }, h("b", null, "排队"), String(overallQueuedCount)),
|
||||
h("span", { className: "codex-trace-status-chip running" }, h("b", null, "运行"), String(overallRunningCount)),
|
||||
h("span", { className: `codex-trace-status-chip unread ${overallUnreadTerminalCount > 0 ? "warn" : ""}` }, h("b", null, "结束未读"), String(overallUnreadTerminalCount)),
|
||||
h("span", { className: "codex-trace-status-chip service" }, h("b", null, "服务"), `${runtime.providerStatus || "unknown"} · ${service?.providerId || "main-server"} · ${backend.public ? "公网暴露" : "仅 UniDesk frontend 代理访问"}`),
|
||||
h("span", { className: "codex-trace-status-chip service" }, h("b", null, "服务"), `${runtime.providerStatus || "unknown"} · ${service?.providerId || "D601"} · ${backend.public ? "公网暴露" : "仅 UniDesk frontend 代理访问"}`),
|
||||
h("span", { className: "codex-trace-status-chip" }, h("b", null, "执行节点"), providerOptions.map((provider: any) => provider.id).join(" / ")),
|
||||
h("span", { className: "codex-trace-status-chip" }, h("b", null, "执行模式"), executionModeRows.map((mode: any) => mode.id).join(" / ")),
|
||||
h("span", { className: "codex-trace-status-chip" }, h("b", null, "模型"), codexModels.join(" / ")),
|
||||
@@ -3393,7 +3395,7 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
|
||||
const sessionPanel = h(Panel, {
|
||||
title: selectedTask ? `Trace ${String(selectedTask.id).slice(0, 22)}` : "Trace 输出",
|
||||
eyebrow: selectedTask ? `${selectedTask.status} / view=${selectedQueueName} / task queue=${taskQueueLabel(selectedTask)} / provider=${selectedTask.providerId || "main-server"} / mode=${selectedTask.executionMode || "default"} / ${selectedTask.model} / agent loop trace` : `Agent loop trace / view=${selectedQueueName}`,
|
||||
eyebrow: selectedTask ? `${selectedTask.status} / view=${selectedQueueName} / task queue=${taskQueueLabel(selectedTask)} / provider=${selectedTask.providerId || "D601"} / mode=${selectedTask.executionMode || "default"} / ${selectedTask.model} / agent loop trace` : `Agent loop trace / view=${selectedQueueName}`,
|
||||
summary: traceStatusSummary,
|
||||
loading: selectedDetailLoading || loadingMoreTasks || searchLoading || searchLoadingMoreTasks || loadStats?.phase === "loading",
|
||||
actions: h("div", { className: "panel-actions" },
|
||||
@@ -3520,7 +3522,7 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
),
|
||||
),
|
||||
h("label", null, "执行 Provider",
|
||||
h("select", { value: providerId, disabled: submitting, onChange: (event: any) => changeSubmitProvider(String(event.target.value || "main-server")), "data-testid": "codex-provider-select" },
|
||||
h("select", { value: providerId, disabled: submitting, onChange: (event: any) => changeSubmitProvider(String(event.target.value || "D601")), "data-testid": "codex-provider-select" },
|
||||
providerOptions.map((provider: any) => h("option", { key: provider.id, value: provider.id }, `${provider.label || provider.id} · ${provider.defaultWorkdir || providerDefaultWorkdir(queue, provider.id)}${provider.supportsWindowsNativeCodex ? " · Windows native" : ""}`)),
|
||||
),
|
||||
),
|
||||
@@ -3529,7 +3531,7 @@ export function CodeQueuePage({ microservices, onRaw, apiBaseUrl = "/api", initi
|
||||
executionModeRows.map((mode: any) => h("option", { key: mode.id, value: mode.id }, `${mode.label || mode.id}${mode.id === "windows-native" ? " · 宿主 Codex" : ""}`)),
|
||||
),
|
||||
),
|
||||
h("label", null, "工作目录", h("input", { value: cwd, disabled: submitting, onChange: (event: any) => setCwd(event.target.value), placeholder: currentProviderDefaultWorkdir || queue?.defaultWorkdir || "/root/unidesk", "data-testid": "codex-cwd-input" })),
|
||||
h("label", null, "工作目录", h("input", { value: cwd, disabled: submitting, onChange: (event: any) => setCwd(event.target.value), placeholder: currentProviderDefaultWorkdir || queue?.defaultWorkdir || "/workspace", "data-testid": "codex-cwd-input" })),
|
||||
h("label", null, "最大尝试", h("input", { type: "number", min: 1, max: 99, value: maxAttempts, disabled: submitting, onChange: (event: any) => setMaxAttempts(Number(event.target.value)), "data-testid": "codex-max-attempts-input" })),
|
||||
h("label", null, "入队份数", h("input", { type: "number", min: 1, max: 50, value: repeatCount, disabled: submitting, onChange: (event: any) => setRepeatCount(Number(event.target.value)), "data-testid": "codex-repeat-count-input" })),
|
||||
),
|
||||
|
||||
@@ -99,7 +99,8 @@ async function refreshCodeQueueOverview(pathWithQuery: string, timeoutMs = 800):
|
||||
async function refreshCodeQueueOverviewUncached(pathWithQuery: string, timeoutMs = 800): Promise<JsonValue | null> {
|
||||
const started = performance.now();
|
||||
try {
|
||||
const response = await fetch(`http://code-queue:4222${pathWithQuery}`, {
|
||||
const upstreamUrl = new URL(`/api/microservices/code-queue/proxy${pathWithQuery}`, config.coreInternalUrl);
|
||||
const response = await fetch(upstreamUrl, {
|
||||
signal: AbortSignal.timeout(timeoutMs),
|
||||
headers: { accept: "application/json" },
|
||||
});
|
||||
@@ -718,7 +719,7 @@ async function proxyCodeQueueDirect(req: Request, url: URL): Promise<Response> {
|
||||
return new Response(cached.text, { headers: { "content-type": "application/json; charset=utf-8" } });
|
||||
}
|
||||
}
|
||||
const upstreamUrl = new URL(`${suffix}${url.search}`, "http://code-queue:4222");
|
||||
const upstreamUrl = new URL(`/api/microservices/code-queue/proxy${suffix}${url.search}`, config.coreInternalUrl);
|
||||
const headers = new Headers(req.headers);
|
||||
headers.delete("host");
|
||||
headers.delete("connection");
|
||||
|
||||
Reference in New Issue
Block a user