feat: add master code queue manager
This commit is contained in:
@@ -80,8 +80,8 @@ function parseMicroserviceConfig(value: unknown, index: number): MicroserviceCon
|
||||
const frontend = asRecord(item.frontend, `${path}.frontend`);
|
||||
const deployment = item.deployment === undefined ? undefined : asRecord(item.deployment, `${path}.deployment`);
|
||||
const deploymentMode = deployment === undefined ? "unidesk-direct" : stringFromRecord(deployment, "mode", `${path}.deployment`);
|
||||
if (deploymentMode !== "unidesk-direct" && deploymentMode !== "k3sctl-managed") {
|
||||
throw new Error(`${path}.deployment.mode must be unidesk-direct or k3sctl-managed`);
|
||||
if (deploymentMode !== "unidesk-direct" && deploymentMode !== "k3sctl-managed" && deploymentMode !== "internal-sidecar") {
|
||||
throw new Error(`${path}.deployment.mode must be unidesk-direct, k3sctl-managed, or internal-sidecar`);
|
||||
}
|
||||
return {
|
||||
id: stringFromRecord(item, "id", path),
|
||||
|
||||
@@ -390,6 +390,17 @@ function codeQueueK3sServiceIdForRequest(method: string, targetPath: string): st
|
||||
return "code-queue-write";
|
||||
}
|
||||
|
||||
function codeQueueMasterControlPath(method: string, targetPath: string): boolean {
|
||||
const normalizedMethod = method.toUpperCase();
|
||||
if (targetPath === "/" || targetPath === "/health" || targetPath === "/live" || targetPath === "/logs") return true;
|
||||
if (targetPath === "/api/queues" || targetPath === "/api/queues/merge") return true;
|
||||
if (/^\/api\/queues\/[^/]+(?:\/merge)?$/u.test(targetPath)) return true;
|
||||
if (targetPath === "/api/tasks" || targetPath === "/api/tasks/batch" || targetPath === "/api/tasks/overview" || targetPath === "/api/tasks/stats" || targetPath === "/api/tasks/read-all") return true;
|
||||
if (/^\/api\/tasks\/[^/]+\/(?:summary|trace-summary|trace-steps|trace-step|transcript|output|prompt|read|retry|move|edit)$/u.test(targetPath)) return true;
|
||||
if (/^\/api\/tasks\/[^/]+$/u.test(targetPath) && normalizedMethod === "GET") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Cache helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -713,6 +724,11 @@ async function fetchMicroserviceUpstreamResponse(
|
||||
bodyText: string,
|
||||
abortSignal?: AbortSignal,
|
||||
): Promise<Response> {
|
||||
if (service.id === "code-queue" && codeQueueMasterControlPath(method, targetPath)) {
|
||||
const mgr = microserviceById("code-queue-mgr");
|
||||
if (mgr !== null) return directMicroserviceResponse(mgr, method, targetPath, proxyOptions, requestHeaders, bodyText, abortSignal);
|
||||
logger("warn", "code_queue_mgr_missing_fallback_to_d601", { method, targetPath });
|
||||
}
|
||||
if (isK3sctlManagedMicroservice(service)) {
|
||||
return k3sctlAdapterMicroserviceResponse(service, method, targetPath, proxyOptions, requestHeaders, bodyText, abortSignal);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface MicroserviceConfig {
|
||||
timeoutMs: number;
|
||||
};
|
||||
deployment: {
|
||||
mode: "unidesk-direct" | "k3sctl-managed";
|
||||
mode: "unidesk-direct" | "k3sctl-managed" | "internal-sidecar";
|
||||
adapterServiceId?: string;
|
||||
k3sServiceId?: string;
|
||||
namespace?: string;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
ARG CODE_QUEUE_MGR_BASE_IMAGE=oven/bun:1-debian
|
||||
FROM ${CODE_QUEUE_MGR_BASE_IMAGE}
|
||||
|
||||
WORKDIR /app/src/components/microservices/code-queue-mgr
|
||||
COPY src/components/microservices/code-queue-mgr/package.json ./package.json
|
||||
RUN bun install --production
|
||||
COPY src/components/microservices/code-queue-mgr/tsconfig.json ./tsconfig.json
|
||||
COPY src/components/shared /app/src/components/shared
|
||||
COPY src/components/microservices/code-queue-mgr/src ./src
|
||||
|
||||
EXPOSE 4278
|
||||
CMD ["bun", "--smol", "run", "src/index.ts"]
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "@unidesk/code-queue-mgr",
|
||||
"dependencies": {
|
||||
"postgres": "3.4.9",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "1.3.14",
|
||||
"@types/node": "24.10.1",
|
||||
"typescript": "6.0.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
||||
|
||||
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
||||
|
||||
"postgres": ["postgres@3.4.9", "", {}, "sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw=="],
|
||||
|
||||
"typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
|
||||
"bun-types/@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
|
||||
|
||||
"bun-types/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@unidesk/code-queue-mgr",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "bun run src/index.ts",
|
||||
"check": "tsc -p tsconfig.json --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"postgres": "3.4.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "1.3.14",
|
||||
"@types/node": "24.10.1",
|
||||
"typescript": "6.0.3"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["bun", "node"],
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "dist",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"references": [{ "path": "../../shared" }]
|
||||
}
|
||||
Reference in New Issue
Block a user