feat: add omx orchestration backend selection

This commit is contained in:
kris
2026-04-03 03:17:12 +08:00
parent 60f5e2d7d6
commit ec45bed59f
18 changed files with 1993 additions and 20 deletions

View File

@@ -3,7 +3,13 @@ import {
OMX_TEAM_BACKEND,
type OmxTeamBackendSelectionState,
} from "@/lib/execution/backends/omx-team-backend";
import type { OrchestrationBackend } from "@/lib/execution/orchestration-backend";
import {
labelForOrchestrationBackend,
normalizeOrchestrationBackendId,
type OrchestrationBackend,
type OrchestrationBackendChoiceView,
type OrchestrationBackendSelectionState,
} from "@/lib/execution/orchestration-backend";
export interface OrchestrationBackendSelectionInput {
requestedBackendId?: string;
@@ -24,10 +30,27 @@ function isReadyBackend(
return true;
}
function getRequestedBackendId(input: OrchestrationBackendSelectionInput) {
return normalizeOrchestrationBackendId(input.requestedBackendId);
}
function isSelectableBackend(
backendId: string,
input: OrchestrationBackendSelectionInput,
) {
if (backendId === OMX_TEAM_BACKEND.backendId) {
return input.omx?.selectable ?? false;
}
return true;
}
export async function selectOrchestrationBackend(
input: OrchestrationBackendSelectionInput = {},
): Promise<OrchestrationBackendChoice> {
return (await listOrchestrationBackendChoices(input))[0] ?? BOSS_NATIVE_ORCHESTRATOR;
const resolution = await resolveOrchestrationBackendSelection(input);
return resolution.currentBackendId === OMX_TEAM_BACKEND.backendId
? OMX_TEAM_BACKEND
: BOSS_NATIVE_ORCHESTRATOR;
}
export async function listOrchestrationBackendChoices(
@@ -60,4 +83,45 @@ export async function listOrchestrationBackendChoices(
return ordered;
}
export async function listOrchestrationBackendChoiceViews(
input: OrchestrationBackendSelectionInput = {},
): Promise<OrchestrationBackendChoiceView[]> {
const requestedBackendId = getRequestedBackendId(input);
const omxSelectable = isSelectableBackend(OMX_TEAM_BACKEND.backendId, input);
const choices = await listOrchestrationBackendChoices(input);
return choices.map((backend) => ({
backendId: backend.backendId,
label: labelForOrchestrationBackend(backend.backendId),
selectable: backend.backendId === OMX_TEAM_BACKEND.backendId ? omxSelectable : true,
current: backend.backendId === requestedBackendId && (!omxSelectable || backend.backendId === requestedBackendId)
? true
: backend.backendId === BOSS_NATIVE_ORCHESTRATOR.backendId && requestedBackendId !== OMX_TEAM_BACKEND.backendId,
}));
}
export async function resolveOrchestrationBackendSelection(
input: OrchestrationBackendSelectionInput = {},
): Promise<OrchestrationBackendSelectionState> {
const requestedBackendId = getRequestedBackendId(input);
const omxAvailability = input.omx?.availability;
const omxSelectable = input.omx?.selectable ?? false;
const omxRequested = requestedBackendId === OMX_TEAM_BACKEND.backendId;
const currentBackendId =
omxRequested && omxSelectable ? OMX_TEAM_BACKEND.backendId : BOSS_NATIVE_ORCHESTRATOR.backendId;
return {
requestedBackendId,
currentBackendId,
resolvedAt: new Date().toISOString(),
...(omxAvailability ? { omxAvailability } : {}),
...(omxRequested && !omxSelectable
? {
fallbackReason: "omx-team unavailable",
fallbackReasonLabel:
omxAvailability?.reasonLabel ??
"OMX Team Runtime 当前不可用,已自动回退到 Boss Native Orchestrator。",
}
: {}),
};
}
export const selectOrchestrationBackendForTesting = selectOrchestrationBackend;

View File

@@ -1,4 +1,34 @@
import type { OmxTeamBackendAvailability } from "@/lib/execution/backends/omx-team-config";
export type OrchestrationBackendId = "boss-native-orchestrator" | "omx-team";
export interface OrchestrationBackend {
backendId: string;
describe(): Promise<{ backendId: string; label: string }>;
backendId: OrchestrationBackendId;
describe(): Promise<{ backendId: OrchestrationBackendId; label: string }>;
}
export interface OrchestrationBackendChoiceView {
backendId: OrchestrationBackendId;
label: string;
selectable: boolean;
current: boolean;
}
export interface OrchestrationBackendSelectionState {
requestedBackendId: OrchestrationBackendId;
currentBackendId: OrchestrationBackendId;
resolvedAt: string;
fallbackReason?: string;
fallbackReasonLabel?: string;
omxAvailability?: OmxTeamBackendAvailability;
}
export function normalizeOrchestrationBackendId(
backendId?: string | null,
): OrchestrationBackendId {
return backendId?.trim() === "omx-team" ? "omx-team" : "boss-native-orchestrator";
}
export function labelForOrchestrationBackend(backendId: OrchestrationBackendId) {
return backendId === "omx-team" ? "OMX Team Runtime" : "Boss Native Orchestrator";
}