feat: add omx orchestration backend selection
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user