fix: stabilize code queue judge networking
This commit is contained in:
@@ -106,7 +106,7 @@ egress proxy 的长期边界是“统一 provider 通道,不引入第二控制
|
||||
|
||||
egress tunnel 必须有生命周期边界:provider-gateway 发出 `egress_tcp_open` 后如果主 server 未在 `openTimeoutMs` 内返回 `egress_tcp_opened` 或 close,必须主动关闭本地 client 并向 core 发送 `egress_tcp_close`;provider-gateway 与 backend-core 都必须对长时间无数据的 relay 执行 idle 清理,避免 provider WebSocket 抖动、TCP connect 卡住或上游未关闭时留下 stale tunnel。排障时如果 `activeTunnels` 持续增长、`pendingTunnels` 非零或 `oldestTunnelAgeMs` 明显超过业务请求耗时,应先看 provider-gateway 与 backend-core egress 清理日志,再判断 Code Queue、PostgreSQL 或 OA Event Flow 本身是否慢。
|
||||
|
||||
故障语义必须显式,不允许静默 fallback。provider-gateway 到 backend-core 的 WebSocket 未连接时,本地 proxy 必须返回 503;执行容器不能自动绕过到 D601 本地直连公网、外部公共代理或主 server 公网 HTTP 端口。`NO_PROXY` 只用于 PostgreSQL、OA Event Flow、ClaudeQQ、frontend/backend-core 内网代理、provider-gateway health 等明确内网链路,不能把 GitHub、模型 API、npm registry 等外部目标加入绕过列表。`hyueapi.com` 是明确的模型 API 例外:该上游会拒绝 provider-gateway egress proxy 出口,Code Queue 必须用 `CODE_QUEUE_EGRESS_PROXY_NO_PROXY` / `NO_PROXY` 将 `hyueapi.com,.hyueapi.com` 配成直连,其它模型 API 仍不得默认绕过 proxy。验收必须同时证明 provider-gateway labels、业务服务 `/health` 和执行容器内 `curl -I https://...` 都走同一 proxy path,hyueapi 例外则以 Code Queue `/health.egressProxy.noProxy` 和目标任务成功完成作为证据。
|
||||
故障语义必须显式,不允许静默 fallback。provider-gateway 到 backend-core 的 WebSocket 未连接时,本地 proxy 必须返回 503;执行容器不能自动绕过到 D601 本地直连公网、外部公共代理或主 server 公网 HTTP 端口。`NO_PROXY` 只用于 PostgreSQL、OA Event Flow、ClaudeQQ、frontend/backend-core 内网代理、provider-gateway health 等明确内网链路,不能把 GitHub、npm registry 等外部目标加入绕过列表。`hyueapi.com` 与 MiniMax judge 上游 `api.minimaxi.com` 是明确的模型 API 例外:前者会拒绝 provider-gateway egress proxy 出口,后者在 judge 高频短请求上容易受 provider egress 抖动影响导致任务误重试;Code Queue 必须用 `CODE_QUEUE_EGRESS_PROXY_NO_PROXY` / `NO_PROXY` 将 `hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com` 配成直连,其它模型 API 仍不得默认绕过 proxy。验收必须同时证明 provider-gateway labels、业务服务 `/health` 和执行容器内 `curl -I https://...` 都走同一 proxy path,hyueapi/MiniMax 例外则以 Code Queue `/health.egressProxy.noProxy`、MiniMax judge 探测和目标任务成功完成作为证据。
|
||||
|
||||
## Gateway Version Metadata
|
||||
|
||||
|
||||
@@ -50,15 +50,15 @@ services:
|
||||
CODE_QUEUE_DEV_CONTAINER_WORKDIR: "${CODE_QUEUE_DEV_CONTAINER_WORKDIR:-/home/ubuntu}"
|
||||
CODE_QUEUE_EGRESS_PROXY_ENABLED: "${CODE_QUEUE_EGRESS_PROXY_ENABLED:-true}"
|
||||
CODE_QUEUE_EGRESS_PROXY_URL: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
CODE_QUEUE_EGRESS_PROXY_NO_PROXY: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com}"
|
||||
CODE_QUEUE_EGRESS_PROXY_NO_PROXY: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com}"
|
||||
HTTP_PROXY: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
HTTPS_PROXY: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
ALL_PROXY: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
http_proxy: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
https_proxy: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
all_proxy: "${CODE_QUEUE_EGRESS_PROXY_URL:-http://unidesk-provider-gateway-D601:18789}"
|
||||
NO_PROXY: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com}"
|
||||
no_proxy: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com}"
|
||||
NO_PROXY: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com}"
|
||||
no_proxy: "${CODE_QUEUE_EGRESS_PROXY_NO_PROXY:-localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,unidesk-provider-gateway-D601,74.48.78.17,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com}"
|
||||
CODE_QUEUE_WINDOWS_NATIVE_CODEX_DEFAULT_WORKDIR: "${CODE_QUEUE_WINDOWS_NATIVE_CODEX_DEFAULT_WORKDIR:-/mnt/f/Work/ConStart}"
|
||||
CODE_QUEUE_WINDOWS_NATIVE_CODEX_BRIDGE_DIR: "${CODE_QUEUE_WINDOWS_NATIVE_CODEX_BRIDGE_DIR:-/home/ubuntu/.unidesk/code-queue/windows-native-codex}"
|
||||
CODE_QUEUE_WINDOWS_NATIVE_CODEX_COMMAND: "${CODE_QUEUE_WINDOWS_NATIVE_CODEX_COMMAND:-codex app-server --listen stdio://}"
|
||||
|
||||
@@ -51,7 +51,7 @@ function appServerCwdForTask(task: QueueTask): string {
|
||||
}
|
||||
|
||||
const codexProxyEnvKeys = ["HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"];
|
||||
const defaultCodexDirectHosts = ["hyueapi.com", ".hyueapi.com"];
|
||||
const defaultCodexDirectHosts = ["hyueapi.com", ".hyueapi.com", "api.minimaxi.com", ".minimaxi.com"];
|
||||
|
||||
function splitEnvList(value: string | undefined, fallback: string[]): string[] {
|
||||
const raw = value === undefined || value.trim().length === 0 ? fallback : value.split(",");
|
||||
|
||||
@@ -210,10 +210,10 @@ let sqlRotationInFlight: Promise<void> | null = null;
|
||||
|
||||
function createSqlClient(): SqlClient {
|
||||
return postgres(config.databaseUrl, {
|
||||
max: config.databasePoolMax,
|
||||
idle_timeout: 20,
|
||||
connect_timeout: 10,
|
||||
connection: { application_name: "unidesk-code-queue" },
|
||||
max: config.databasePoolMax,
|
||||
idle_timeout: 20,
|
||||
connect_timeout: 10,
|
||||
connection: { application_name: "unidesk-code-queue" },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -426,6 +426,8 @@ function readConfig(): RuntimeConfig {
|
||||
"database",
|
||||
"hyueapi.com",
|
||||
".hyueapi.com",
|
||||
"api.minimaxi.com",
|
||||
".minimaxi.com",
|
||||
].join(",")),
|
||||
devContainerMasterHost,
|
||||
devContainerDefaultProviderId,
|
||||
@@ -919,6 +921,14 @@ function fallbackJudgeRetryCount(task: QueueTask): number {
|
||||
return Math.max(attemptCount, outputCount);
|
||||
}
|
||||
|
||||
function fallbackJudgeIsProviderTransient(judge: JudgeResult | null | undefined): boolean {
|
||||
if (judge?.source !== "fallback" || judge.decision !== "retry") return false;
|
||||
const details = judge.failureDetails;
|
||||
if (details === null || details === undefined) return false;
|
||||
return details.provider === "minimax"
|
||||
&& (details.stage === "request" || details.stage === "unknown" || details.timedOut);
|
||||
}
|
||||
|
||||
function pruneTaskHotState(task: QueueTask): void {
|
||||
if (config.maxInMemoryOutputRecords > 0 && task.output.length > config.maxInMemoryOutputRecords) {
|
||||
task.output.splice(0, task.output.length - config.maxInMemoryOutputRecords);
|
||||
@@ -2778,7 +2788,7 @@ configureNotifications({
|
||||
queueIdOf,
|
||||
safePreview,
|
||||
shutdownRequested: () => shutdownRequested,
|
||||
sql,
|
||||
sql: () => sql,
|
||||
taskTimestamp,
|
||||
tasks: () => state.tasks,
|
||||
timestampMs,
|
||||
@@ -2816,7 +2826,7 @@ configureQueueApi({
|
||||
runGarbageCollection,
|
||||
safeQueueId,
|
||||
safeQueueName,
|
||||
sql,
|
||||
sql: () => sql,
|
||||
taskQueueEnteredAt,
|
||||
traceStatsForTasks: readOaTraceStatsForTasks,
|
||||
tasks: () => state.tasks,
|
||||
@@ -3318,6 +3328,11 @@ function retryBackoffMs(completedAttempts: number): number {
|
||||
return Math.min(retryBackoffMaxMs, retryBackoffBaseMs * (2 ** exponent));
|
||||
}
|
||||
|
||||
function judgeProviderBackoffMs(task: QueueTask): number {
|
||||
const fallbackCount = Math.max(1, fallbackJudgeRetryCount(task));
|
||||
return Math.min(5 * 60_000, Math.max(30_000, retryBackoffMs(fallbackCount)));
|
||||
}
|
||||
|
||||
async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
const timeout = new Promise<never>((_, reject) => {
|
||||
@@ -3501,7 +3516,13 @@ function failTaskForFallbackRetryLimit(task: QueueTask, judge: JudgeResult | nul
|
||||
async function runTask(task: QueueTask): Promise<void> {
|
||||
const claimQueueId = queueIdOf(task);
|
||||
logger("info", "task_processor_start", { taskId: task.id, queueId: claimQueueId, providerId: task.providerId, executionMode: task.executionMode, cwd: task.cwd, maxAttempts: task.maxAttempts, model: task.model, agentPort: codeAgentPortForModel(task.model), promptPreview: safePreview(task.prompt, 240) });
|
||||
if (task.status === "retry_wait" && task.lastJudge?.source === "fallback" && task.lastJudge.decision === "retry" && fallbackJudgeRetryCount(task) >= fallbackJudgeRetryLimit) {
|
||||
if (
|
||||
task.status === "retry_wait"
|
||||
&& task.lastJudge?.source === "fallback"
|
||||
&& task.lastJudge.decision === "retry"
|
||||
&& !fallbackJudgeIsProviderTransient(task.lastJudge)
|
||||
&& fallbackJudgeRetryCount(task) >= fallbackJudgeRetryLimit
|
||||
) {
|
||||
failTaskForFallbackRetryLimit(task, task.lastJudge);
|
||||
return;
|
||||
}
|
||||
@@ -3632,6 +3653,27 @@ async function runTask(task: QueueTask): Promise<void> {
|
||||
void notifyTaskTerminal(task);
|
||||
return;
|
||||
}
|
||||
if (fallbackJudgeIsProviderTransient(judge)) {
|
||||
task.status = "retry_wait";
|
||||
task.finishedAt = null;
|
||||
task.readAt = null;
|
||||
task.nextPrompt = retryPrompt(task, judge);
|
||||
task.nextMode = "retry";
|
||||
setAttemptFeedbackPrompt(latestAttempt, task.nextPrompt, "judge-provider-transient-retry", task.attempts.length + 1);
|
||||
task.updatedAt = nowIso();
|
||||
const delayMs = judgeProviderBackoffMs(task);
|
||||
appendOutput(task, "system", `judge provider transient failure; retry backoff ${Math.round(delayMs / 1000)}s before continuing existing session\n`, "queue");
|
||||
persistTaskState(task);
|
||||
await flushDirtyTasksToDatabase(true);
|
||||
logger("warn", "task_judge_provider_transient_retry", {
|
||||
taskId: task.id,
|
||||
fallbackRetryCount: fallbackJudgeRetryCount(task),
|
||||
delayMs,
|
||||
reason: safePreview(judge.reason, 500),
|
||||
});
|
||||
await sleepForRetryBackoff(task, delayMs);
|
||||
continue;
|
||||
}
|
||||
if (judge.source === "fallback" && fallbackJudgeRetryCount(task) >= fallbackJudgeRetryLimit) {
|
||||
failTaskForFallbackRetryLimit(task, judge);
|
||||
return;
|
||||
|
||||
@@ -24,7 +24,7 @@ export interface NotificationsContext {
|
||||
queueIdOf: (task: QueueTask) => string;
|
||||
safePreview: (value: string, max?: number) => string;
|
||||
shutdownRequested: () => boolean;
|
||||
sql: postgres.Sql;
|
||||
sql: () => postgres.Sql;
|
||||
taskTimestamp: (value: string | null) => string | null;
|
||||
tasks: () => QueueTask[];
|
||||
timestampMs: (value: string | null | undefined) => number | null;
|
||||
@@ -94,7 +94,7 @@ function notificationItemFromRow(row: ClaudeQqNotificationRow): ClaudeQqNotifica
|
||||
};
|
||||
}
|
||||
|
||||
async function loadClaudeQqNotificationOutboxFromDatabase(client: SqlExecutor = ctx().sql): Promise<void> {
|
||||
async function loadClaudeQqNotificationOutboxFromDatabase(client: SqlExecutor = ctx().sql()): Promise<void> {
|
||||
const rows = await client<ClaudeQqNotificationRow[]>`
|
||||
SELECT id, kind, dedup_key, target, message, created_at, updated_at, attempts, next_attempt_at, last_error, sent_at
|
||||
FROM unidesk_code_queue_notifications
|
||||
@@ -153,7 +153,7 @@ async function persistClaudeQqNotificationItem(item: ClaudeQqNotificationItem):
|
||||
claudeQqNotificationOutbox.updatedAt = ctx().nowIso();
|
||||
const deletedIds = pruneClaudeQqNotificationOutbox();
|
||||
const stillPresent = claudeQqNotificationOutbox.items.some((candidate) => candidate.id === item.id);
|
||||
await ctx().sql.begin(async (client) => {
|
||||
await ctx().sql().begin(async (client) => {
|
||||
if (stillPresent) await upsertClaudeQqNotificationToDatabase(client, item);
|
||||
for (const id of deletedIds) await client`DELETE FROM unidesk_code_queue_notifications WHERE id = ${id}`;
|
||||
});
|
||||
@@ -167,7 +167,7 @@ async function persistClaudeQqNotificationOutbox(): Promise<void> {
|
||||
if (!ctx().databaseReady()) throw new Error("PostgreSQL is not ready for ClaudeQQ notification outbox");
|
||||
claudeQqNotificationOutbox.updatedAt = ctx().nowIso();
|
||||
const deletedIds = pruneClaudeQqNotificationOutbox();
|
||||
await ctx().sql.begin(async (client) => {
|
||||
await ctx().sql().begin(async (client) => {
|
||||
for (const item of claudeQqNotificationOutbox.items) await upsertClaudeQqNotificationToDatabase(client, item);
|
||||
for (const id of deletedIds) await client`DELETE FROM unidesk_code_queue_notifications WHERE id = ${id}`;
|
||||
});
|
||||
|
||||
@@ -43,7 +43,7 @@ export interface QueueApiContext {
|
||||
runGarbageCollection: () => void;
|
||||
safeQueueId: (value: unknown) => string;
|
||||
safeQueueName: (value: unknown, queueId: string) => string;
|
||||
sql: postgres.Sql;
|
||||
sql: () => postgres.Sql;
|
||||
taskQueueEnteredAt: (task: QueueTask) => string;
|
||||
traceStatsForTasks: (taskIds: string[]) => Promise<Map<string, OaTraceStats>>;
|
||||
tasks: () => QueueTask[];
|
||||
@@ -530,7 +530,7 @@ async function queueSummaryForHealth(includeDevReady = true): Promise<JsonValue>
|
||||
if (!ctx().databaseReady()) return summary;
|
||||
let aggregateRows: QueueSummaryAggregateRow[];
|
||||
try {
|
||||
aggregateRows = await ctx().sql<QueueSummaryAggregateRow[]>`
|
||||
aggregateRows = await ctx().sql()<QueueSummaryAggregateRow[]>`
|
||||
SELECT
|
||||
(SELECT COUNT(*) FROM unidesk_code_queue_tasks) AS total,
|
||||
COALESCE((
|
||||
@@ -868,14 +868,14 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
}
|
||||
const [executedRows, completedRows, retryRows] = queueId === null
|
||||
? await Promise.all([
|
||||
ctx().sql<DailyCountRow[]>`
|
||||
ctx().sql()<DailyCountRow[]>`
|
||||
SELECT to_char(started_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date, COUNT(*) AS count
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE started_at >= ${range.startAt}
|
||||
AND started_at < ${range.endAt}
|
||||
GROUP BY date
|
||||
`,
|
||||
ctx().sql<DailyCompletedRow[]>`
|
||||
ctx().sql()<DailyCompletedRow[]>`
|
||||
SELECT
|
||||
to_char(COALESCE(finished_at, updated_at) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
|
||||
status,
|
||||
@@ -888,7 +888,7 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
AND COALESCE(finished_at, updated_at) < ${range.endAt}
|
||||
GROUP BY date, status
|
||||
`,
|
||||
ctx().sql<DailyCountRow[]>`
|
||||
ctx().sql()<DailyCountRow[]>`
|
||||
SELECT
|
||||
to_char(updated_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
|
||||
SUM(GREATEST(current_attempt - 1, attempt_count - 1, 0)) AS count
|
||||
@@ -900,7 +900,7 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
`,
|
||||
])
|
||||
: await Promise.all([
|
||||
ctx().sql<DailyCountRow[]>`
|
||||
ctx().sql()<DailyCountRow[]>`
|
||||
SELECT to_char(started_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date, COUNT(*) AS count
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE queue_id = ${queueId}
|
||||
@@ -908,7 +908,7 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
AND started_at < ${range.endAt}
|
||||
GROUP BY date
|
||||
`,
|
||||
ctx().sql<DailyCompletedRow[]>`
|
||||
ctx().sql()<DailyCompletedRow[]>`
|
||||
SELECT
|
||||
to_char(COALESCE(finished_at, updated_at) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
|
||||
status,
|
||||
@@ -922,7 +922,7 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
AND COALESCE(finished_at, updated_at) < ${range.endAt}
|
||||
GROUP BY date, status
|
||||
`,
|
||||
ctx().sql<DailyCountRow[]>`
|
||||
ctx().sql()<DailyCountRow[]>`
|
||||
SELECT
|
||||
to_char(updated_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
|
||||
SUM(GREATEST(current_attempt - 1, attempt_count - 1, 0)) AS count
|
||||
@@ -1000,14 +1000,14 @@ async function databaseTaskStatisticsSummary(queueId: string | null, url: URL):
|
||||
|
||||
async function databaseTaskTotal(queueId: string | null): Promise<number> {
|
||||
const rows = queueId === null
|
||||
? await ctx().sql<CountRow[]>`SELECT COUNT(*) AS count FROM unidesk_code_queue_tasks`
|
||||
: await ctx().sql<CountRow[]>`SELECT COUNT(*) AS count FROM unidesk_code_queue_tasks WHERE queue_id = ${queueId}`;
|
||||
? await ctx().sql()<CountRow[]>`SELECT COUNT(*) AS count FROM unidesk_code_queue_tasks`
|
||||
: await ctx().sql()<CountRow[]>`SELECT COUNT(*) AS count FROM unidesk_code_queue_tasks WHERE queue_id = ${queueId}`;
|
||||
return Number(rows[0]?.count ?? 0);
|
||||
}
|
||||
|
||||
async function databaseCursor(beforeId: string | null): Promise<TaskIdRow | null> {
|
||||
if (beforeId === null || beforeId.length === 0) return null;
|
||||
const rows = await ctx().sql<TaskIdRow[]>`
|
||||
const rows = await ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id, created_at
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE id = ${beforeId}
|
||||
@@ -1026,14 +1026,14 @@ async function databasePageTaskIds(queueId: string | null, beforeId: string | nu
|
||||
const fetchLimit = limit + 1;
|
||||
let rows: TaskIdRow[];
|
||||
if (cursor === null && queueId === null) {
|
||||
rows = await ctx().sql<TaskIdRow[]>`
|
||||
rows = await ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
ORDER BY created_at DESC, id DESC
|
||||
LIMIT ${fetchLimit}
|
||||
`;
|
||||
} else if (cursor === null) {
|
||||
rows = await ctx().sql<TaskIdRow[]>`
|
||||
rows = await ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE queue_id = ${queueId}
|
||||
@@ -1041,7 +1041,7 @@ async function databasePageTaskIds(queueId: string | null, beforeId: string | nu
|
||||
LIMIT ${fetchLimit}
|
||||
`;
|
||||
} else if (queueId === null) {
|
||||
rows = await ctx().sql<TaskIdRow[]>`
|
||||
rows = await ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE (created_at, id) < (${cursor.created_at ?? new Date(0)}, ${cursor.id})
|
||||
@@ -1049,7 +1049,7 @@ async function databasePageTaskIds(queueId: string | null, beforeId: string | nu
|
||||
LIMIT ${fetchLimit}
|
||||
`;
|
||||
} else {
|
||||
rows = await ctx().sql<TaskIdRow[]>`
|
||||
rows = await ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE queue_id = ${queueId}
|
||||
@@ -1071,7 +1071,7 @@ async function databasePageTaskIds(queueId: string | null, beforeId: string | nu
|
||||
async function databasePriorityTaskIds(queueId: string | null, limit: number): Promise<string[]> {
|
||||
const [unreadRows, activeRows] = queueId === null
|
||||
? await Promise.all([
|
||||
ctx().sql<TaskIdRow[]>`
|
||||
ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE status IN ('succeeded', 'failed', 'canceled')
|
||||
@@ -1079,7 +1079,7 @@ async function databasePriorityTaskIds(queueId: string | null, limit: number): P
|
||||
ORDER BY updated_at DESC, id DESC
|
||||
LIMIT ${limit}
|
||||
`,
|
||||
ctx().sql<TaskIdRow[]>`
|
||||
ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE status IN ('running', 'judging', 'retry_wait')
|
||||
@@ -1088,7 +1088,7 @@ async function databasePriorityTaskIds(queueId: string | null, limit: number): P
|
||||
`,
|
||||
])
|
||||
: await Promise.all([
|
||||
ctx().sql<TaskIdRow[]>`
|
||||
ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE queue_id = ${queueId}
|
||||
@@ -1097,7 +1097,7 @@ async function databasePriorityTaskIds(queueId: string | null, limit: number): P
|
||||
ORDER BY updated_at DESC, id DESC
|
||||
LIMIT ${limit}
|
||||
`,
|
||||
ctx().sql<TaskIdRow[]>`
|
||||
ctx().sql()<TaskIdRow[]>`
|
||||
SELECT id
|
||||
FROM unidesk_code_queue_tasks
|
||||
WHERE queue_id = ${queueId}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ spec:
|
||||
- name: CODE_QUEUE_EGRESS_PROXY_URL
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: CODE_QUEUE_EGRESS_PROXY_NO_PROXY
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com"
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com"
|
||||
- name: HTTP_PROXY
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: HTTPS_PROXY
|
||||
@@ -1070,9 +1070,9 @@ spec:
|
||||
- name: all_proxy
|
||||
value: "http://d601-provider-egress-proxy.unidesk.svc.cluster.local:18789"
|
||||
- name: NO_PROXY
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com"
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com"
|
||||
- name: no_proxy
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com"
|
||||
value: "localhost,127.0.0.1,::1,host.docker.internal,claudeqq,claudeqq.unidesk,claudeqq.unidesk.svc,claudeqq.unidesk.svc.cluster.local,d601-provider-egress-proxy,d601-provider-egress-proxy.unidesk,d601-provider-egress-proxy.unidesk.svc,d601-provider-egress-proxy.unidesk.svc.cluster.local,d601-tcp-egress-gateway,d601-tcp-egress-gateway.unidesk,d601-tcp-egress-gateway.unidesk.svc,d601-tcp-egress-gateway.unidesk.svc.cluster.local,172.25.0.3,unidesk-provider-gateway-D601,backend-core,oa-event-flow,database,hyueapi.com,.hyueapi.com,api.minimaxi.com,.minimaxi.com"
|
||||
- name: OA_EVENT_FLOW_BASE_URL
|
||||
value: "http://d601-tcp-egress-gateway.unidesk.svc.cluster.local:4255"
|
||||
- name: CODE_QUEUE_NOTIFY_CLAUDEQQ_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user