feat: add decision center service and cli
This commit is contained in:
+28
-17
@@ -51,6 +51,13 @@ type CodexRequestInit = { method?: string; body?: unknown };
|
||||
type CodexResponseFetcher = (path: string, init?: CodexRequestInit) => unknown;
|
||||
type AsyncCodexResponseFetcher = (path: string, init?: CodexRequestInit) => Promise<unknown>;
|
||||
|
||||
const codeQueueProxyPrefix = "/api/microservices/code-queue/proxy";
|
||||
|
||||
function codeQueueProxyPath(path: string): string {
|
||||
if (!path.startsWith("/")) throw new Error("Code Queue proxy path must start with /");
|
||||
return `${codeQueueProxyPrefix}${path}`;
|
||||
}
|
||||
|
||||
function requireTaskId(value: string | undefined, command: string): string {
|
||||
if (value === undefined || value.trim().length === 0) throw new Error(`${command} requires task id`);
|
||||
return value.trim();
|
||||
@@ -105,7 +112,11 @@ function upstreamError(response: unknown): string {
|
||||
if (record === null) return String(response);
|
||||
const body = asRecord(record.body);
|
||||
const bodyError = body?.error;
|
||||
if (typeof bodyError === "string") return bodyError;
|
||||
if (typeof bodyError === "string") {
|
||||
const requestId = typeof body?.requestId === "string" ? ` requestId=${body.requestId}` : "";
|
||||
const providerId = typeof body?.providerId === "string" ? ` providerId=${body.providerId}` : "";
|
||||
return `${bodyError}${providerId}${requestId}`;
|
||||
}
|
||||
const status = typeof record.status === "number" ? `HTTP ${record.status}` : "upstream request failed";
|
||||
return `${status}: ${JSON.stringify(response).slice(0, 1200)}`;
|
||||
}
|
||||
@@ -488,7 +499,7 @@ function queryString(params: Record<string, string | number | boolean | null | u
|
||||
}
|
||||
|
||||
function codexTaskSummary(taskId: string, options: CodexTaskOptions, fetcher: CodexResponseFetcher): unknown {
|
||||
const summaryPath = `/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`;
|
||||
const summaryPath = codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`);
|
||||
const summaryResponse = unwrapCodexResponse(fetcher(summaryPath));
|
||||
const summary = summaryResponse.body.summary;
|
||||
const result: Record<string, unknown> = {
|
||||
@@ -501,8 +512,8 @@ function codexTaskSummary(taskId: string, options: CodexTaskOptions, fetcher: Co
|
||||
if (options.traceMode === "tail") traceParams.tail = 1;
|
||||
if (options.traceMode === "after") traceParams.afterSeq = options.afterSeq;
|
||||
if (options.traceMode === "before") traceParams.beforeSeq = options.beforeSeq;
|
||||
const traceSummaryResponse = unwrapCodexResponse(fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/trace-summary`));
|
||||
const traceResponse = unwrapCodexResponse(fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`));
|
||||
const traceSummaryResponse = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-summary`)));
|
||||
const traceResponse = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`)));
|
||||
result.trace = compactTracePage(traceResponse.body, taskId, options.traceLimit, traceSummaryResponse.body, options);
|
||||
}
|
||||
return result;
|
||||
@@ -548,7 +559,7 @@ function codexTaskOutput(taskId: string, options: CodexOutputOptions, fetcher: C
|
||||
if (options.mode === "tail") params.tail = 1;
|
||||
if (options.mode === "after") params.afterSeq = options.afterSeq;
|
||||
if (options.mode === "before") params.beforeSeq = options.beforeSeq;
|
||||
const response = unwrapCodexResponse(fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`));
|
||||
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`)));
|
||||
return { upstream: response.upstream, outputPage: compactOutputPage(response.body, taskId, options.limit) };
|
||||
}
|
||||
|
||||
@@ -558,7 +569,7 @@ function codexTaskJudge(taskId: string, options: CodexJudgeOptions, fetcher: Cod
|
||||
dryRun: options.dryRun ? 1 : undefined,
|
||||
includePrompt: options.includePrompt ? 1 : undefined,
|
||||
});
|
||||
const response = unwrapCodexResponse(fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/judge${params}`, { method: "POST" }));
|
||||
const response = unwrapCodexResponse(fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/judge${params}`), { method: "POST" }));
|
||||
return { upstream: response.upstream, judgeReplay: response.body };
|
||||
}
|
||||
|
||||
@@ -575,7 +586,7 @@ export function codexJudgeQuery(taskId: string, optionArgs: string[], fetcher: C
|
||||
}
|
||||
|
||||
async function codexTaskSummaryAsync(taskId: string, options: CodexTaskOptions, fetcher: AsyncCodexResponseFetcher): Promise<unknown> {
|
||||
const summaryPath = `/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`;
|
||||
const summaryPath = codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/summary${queryString({ toolLimit: options.toolLimit })}`);
|
||||
const summaryResponse = unwrapCodexResponse(await fetcher(summaryPath));
|
||||
const summary = summaryResponse.body.summary;
|
||||
const result: Record<string, unknown> = {
|
||||
@@ -588,8 +599,8 @@ async function codexTaskSummaryAsync(taskId: string, options: CodexTaskOptions,
|
||||
if (options.traceMode === "tail") traceParams.tail = 1;
|
||||
if (options.traceMode === "after") traceParams.afterSeq = options.afterSeq;
|
||||
if (options.traceMode === "before") traceParams.beforeSeq = options.beforeSeq;
|
||||
const traceSummaryResponse = unwrapCodexResponse(await fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/trace-summary`));
|
||||
const traceResponse = unwrapCodexResponse(await fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`));
|
||||
const traceSummaryResponse = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-summary`)));
|
||||
const traceResponse = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/trace-steps${queryString(traceParams)}`)));
|
||||
result.trace = compactTracePage(traceResponse.body, taskId, options.traceLimit, traceSummaryResponse.body, options);
|
||||
}
|
||||
return result;
|
||||
@@ -604,7 +615,7 @@ async function codexTaskOutputAsync(taskId: string, options: CodexOutputOptions,
|
||||
if (options.mode === "tail") params.tail = 1;
|
||||
if (options.mode === "after") params.afterSeq = options.afterSeq;
|
||||
if (options.mode === "before") params.beforeSeq = options.beforeSeq;
|
||||
const response = unwrapCodexResponse(await fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`));
|
||||
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/output${queryString(params)}`)));
|
||||
return { upstream: response.upstream, outputPage: compactOutputPage(response.body, taskId, options.limit) };
|
||||
}
|
||||
|
||||
@@ -614,7 +625,7 @@ async function codexTaskJudgeAsync(taskId: string, options: CodexJudgeOptions, f
|
||||
dryRun: options.dryRun ? 1 : undefined,
|
||||
includePrompt: options.includePrompt ? 1 : undefined,
|
||||
});
|
||||
const response = unwrapCodexResponse(await fetcher(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/judge${params}`, { method: "POST" }));
|
||||
const response = unwrapCodexResponse(await fetcher(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/judge${params}`), { method: "POST" }));
|
||||
return { upstream: response.upstream, judgeReplay: response.body };
|
||||
}
|
||||
|
||||
@@ -700,19 +711,19 @@ function requireMergeTargetQueueId(args: string[], command: string): string {
|
||||
}
|
||||
|
||||
function codeQueues(): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch("/api/microservices/code-queue/proxy/api/queues"));
|
||||
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/queues")));
|
||||
}
|
||||
|
||||
function codexCreateQueue(queueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch("/api/microservices/code-queue/proxy/api/queues", { method: "POST", body: { queueId } }));
|
||||
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/queues"), { method: "POST", body: { queueId } }));
|
||||
}
|
||||
|
||||
function codexMergeQueue(sourceQueueId: string, targetQueueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch(`/api/microservices/code-queue/proxy/api/queues/${encodeURIComponent(targetQueueId)}/merge`, { method: "POST", body: { sourceQueueId } }));
|
||||
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/queues/${encodeURIComponent(targetQueueId)}/merge`), { method: "POST", body: { sourceQueueId } }));
|
||||
}
|
||||
|
||||
function codexMoveTask(taskId: string, queueId: string): unknown {
|
||||
return unwrapCodexResponse(coreInternalFetch(`/api/microservices/code-queue/proxy/api/tasks/${encodeURIComponent(taskId)}/move`, { method: "POST", body: { queueId } }));
|
||||
return unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/move`), { method: "POST", body: { queueId } }));
|
||||
}
|
||||
|
||||
function promptFromSubmitArgs(args: string[]): string {
|
||||
@@ -845,7 +856,7 @@ function codexSubmitTask(args: string[]): unknown {
|
||||
},
|
||||
};
|
||||
}
|
||||
const response = unwrapCodexResponse(coreInternalFetch("/api/microservices/code-queue/proxy/api/tasks", { method: "POST", body: payload }));
|
||||
const response = unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath("/api/tasks"), { method: "POST", body: payload }));
|
||||
return {
|
||||
upstream: response.upstream,
|
||||
tasks: asArray(response.body.tasks).map(compactTaskMutationResponse),
|
||||
@@ -854,7 +865,7 @@ function codexSubmitTask(args: string[]): unknown {
|
||||
}
|
||||
|
||||
function codexInterruptTask(taskId: string): unknown {
|
||||
const response = unwrapCodexResponse(coreInternalFetch(`/api/microservices/k3sctl-adapter/proxy/api/services/code-queue-scheduler/proxy/api/tasks/${encodeURIComponent(taskId)}/interrupt`, { method: "POST" }));
|
||||
const response = unwrapCodexResponse(coreInternalFetch(codeQueueProxyPath(`/api/tasks/${encodeURIComponent(taskId)}/interrupt`), { method: "POST" }));
|
||||
return {
|
||||
upstream: response.upstream,
|
||||
task: compactTaskMutationResponse(response.body.task),
|
||||
|
||||
Reference in New Issue
Block a user