forked from boos/BoosAPI
fix: stabilize Codex continuation and proxy retry recovery / 修复 Codex 续传与代理重试稳定性 (#257)
* wip: preserve local changes before upstream merge * Improve proxy routing stability and add stable-first strategy * Sync explicit-group routing strategy to eligible source routes * Fix proxy retry and runtime health review issues * fix: make proxy channel retry attempts configurable * fix: harden proxy retry recovery and bookkeeping * fix: address pr 257 review comments --------- Co-authored-by: Cita <juricek.chen@gmail.com>
This commit is contained in:
@@ -24,6 +24,10 @@ import {
|
||||
} from './helpers/routeMissingTokenHints.js';
|
||||
import { buildVisibleRouteList } from './helpers/routeListVisibility.js';
|
||||
import { buildZeroChannelPlaceholderRoutes } from './helpers/zeroChannelRoutes.js';
|
||||
import {
|
||||
getRouteRoutingStrategyLabel,
|
||||
normalizeRouteRoutingStrategyValue,
|
||||
} from './token-routes/routingStrategy.js';
|
||||
|
||||
import type {
|
||||
RouteSortBy,
|
||||
@@ -89,18 +93,6 @@ const EMPTY_ROUTE_FORM: RouteEditorForm = {
|
||||
advancedOpen: false,
|
||||
};
|
||||
|
||||
function normalizeRouteRoutingStrategyValue(value?: RouteRoutingStrategy | null): RouteRoutingStrategy {
|
||||
if (value === 'round_robin' || value === 'stable_first') return value;
|
||||
return 'weighted';
|
||||
}
|
||||
|
||||
function getRouteRoutingStrategyLabel(value?: RouteRoutingStrategy | null): string {
|
||||
const strategy = normalizeRouteRoutingStrategyValue(value);
|
||||
if (strategy === 'round_robin') return tr('轮询');
|
||||
if (strategy === 'stable_first') return tr('稳定优先');
|
||||
return tr('权重随机');
|
||||
}
|
||||
|
||||
function getRouteRoutingStrategySuccessMessage(value: RouteRoutingStrategy): string {
|
||||
if (value === 'round_robin') return '已切换为轮询策略';
|
||||
if (value === 'stable_first') return '已切换为稳定优先策略';
|
||||
|
||||
@@ -28,6 +28,10 @@ import type {
|
||||
} from './types.js';
|
||||
import type { RouteCandidateView, RouteTokenOption } from '../helpers/routeModelCandidatesIndex.js';
|
||||
import { SortableChannelRow } from './SortableChannelRow.js';
|
||||
import {
|
||||
getRouteRoutingStrategyLabel,
|
||||
normalizeRouteRoutingStrategyValue,
|
||||
} from './routingStrategy.js';
|
||||
import {
|
||||
isRouteExactModel,
|
||||
isExplicitGroupRoute,
|
||||
@@ -76,18 +80,6 @@ type RouteCardProps = {
|
||||
onToggleSourceGroup: (groupKey: string) => void;
|
||||
};
|
||||
|
||||
function normalizeRoutingStrategy(value?: RouteRoutingStrategy | null): RouteRoutingStrategy {
|
||||
if (value === 'round_robin' || value === 'stable_first') return value;
|
||||
return 'weighted';
|
||||
}
|
||||
|
||||
function getRoutingStrategyLabel(value?: RouteRoutingStrategy | null): string {
|
||||
const strategy = normalizeRoutingStrategy(value);
|
||||
if (strategy === 'round_robin') return tr('轮询');
|
||||
if (strategy === 'stable_first') return tr('稳定优先');
|
||||
return tr('权重随机');
|
||||
}
|
||||
|
||||
function AnimatedCollapseSection({ open, children }: { open: boolean; children: ReactNode }) {
|
||||
const presence = useAnimatedVisibility(open, 220);
|
||||
if (!presence.shouldRender) return null;
|
||||
@@ -139,7 +131,7 @@ function RouteCardInner({
|
||||
const readOnlyRoute = route.kind === 'zero_channel' || route.readOnly === true || route.isVirtual === true;
|
||||
const channelManagementDisabled = explicitGroupRoute;
|
||||
const title = resolveRouteTitle(route);
|
||||
const routingStrategy = normalizeRoutingStrategy(route.routingStrategy);
|
||||
const routingStrategy = normalizeRouteRoutingStrategyValue(route.routingStrategy);
|
||||
const routingStrategyOptions = [
|
||||
{
|
||||
value: 'weighted',
|
||||
@@ -252,7 +244,7 @@ function RouteCardInner({
|
||||
</span>
|
||||
) : (
|
||||
<span className="badge badge-muted" style={{ fontSize: 10, flexShrink: 0 }}>
|
||||
{getRoutingStrategyLabel(routingStrategy)}
|
||||
{getRouteRoutingStrategyLabel(routingStrategy)}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -394,7 +386,7 @@ function RouteCardInner({
|
||||
|
||||
{explicitGroupRoute ? (
|
||||
<div style={{ fontSize: 12, color: 'var(--color-text-muted)', marginBottom: 10 }}>
|
||||
{tr('该群组会将多个来源模型聚合为一个对外模型名;通道信息继承自来源模型,当前仅支持查看,不支持直接维护。')}
|
||||
{tr('该群组会将多个来源模型聚合为一个对外模型名;当前策略以群组设置为准,来源模型会尽量跟随同步,但已单独自定义或被其他群组复用的来源模型不会被覆盖。')}
|
||||
</div>
|
||||
) : !exactRoute ? (
|
||||
<div style={{ fontSize: 12, color: 'var(--color-text-muted)', marginBottom: 10 }}>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { tr } from '../../i18n.js';
|
||||
import type { RouteRoutingStrategy } from './types.js';
|
||||
|
||||
export function normalizeRouteRoutingStrategyValue(value?: RouteRoutingStrategy | null): RouteRoutingStrategy {
|
||||
if (value === 'round_robin' || value === 'stable_first') return value;
|
||||
return 'weighted';
|
||||
}
|
||||
|
||||
export function getRouteRoutingStrategyLabel(value?: RouteRoutingStrategy | null): string {
|
||||
const strategy = normalizeRouteRoutingStrategyValue(value);
|
||||
if (strategy === 'round_robin') return tr('轮询');
|
||||
if (strategy === 'stable_first') return tr('稳定优先');
|
||||
return tr('权重随机');
|
||||
}
|
||||
Reference in New Issue
Block a user