OpenMAIC-React / src /lib /ai /thinking-config.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
raw
history blame
7.07 kB
import type {
ThinkingCapability,
ThinkingConfig,
ThinkingEffort,
ThinkingLevel,
ThinkingMode,
} from '@/lib/types/provider';
export function getThinkingConfigKey(providerId: string, modelId: string): string {
return `${providerId}:${modelId}`;
}
export function supportsConfigurableThinking(
thinking?: ThinkingCapability,
): thinking is ThinkingCapability {
return !!thinking?.control && thinking.control !== 'none' && !!thinking.requestAdapter;
}
export function clampBudgetForCapability(
thinking: ThinkingCapability,
budgetTokens?: number,
): number | undefined {
const range = thinking.budgetRange;
if (!range || typeof budgetTokens !== 'number' || Number.isNaN(budgetTokens)) {
return undefined;
}
if (budgetTokens === -1 && range.allowDynamic) return -1;
return Math.max(range.min, Math.min(range.max, Math.round(budgetTokens)));
}
export function getThinkingMode(
config?: ThinkingConfig,
): 'disabled' | 'enabled' | 'auto' | undefined {
if (!config) return undefined;
if (config.mode && config.mode !== 'default') return config.mode;
if (config.enabled === false) return 'disabled';
if (config.enabled === true) return 'enabled';
return undefined;
}
export function pickThinkingEffort(
thinking: ThinkingCapability,
config: ThinkingConfig,
): ThinkingEffort | undefined {
const allowed = thinking.effortValues;
if (!allowed?.length) return undefined;
if (config.effort && allowed.includes(config.effort)) return config.effort;
const mode = getThinkingMode(config);
if (mode === 'disabled') {
return (
(allowed.includes('none') && 'none') ||
(allowed.includes('minimal') && 'minimal') ||
(allowed.includes('low') && 'low') ||
thinking.defaultEffort
);
}
if (mode === 'enabled') return thinking.defaultEffort;
return undefined;
}
export function pickThinkingLevel(
thinking: ThinkingCapability,
config: ThinkingConfig,
): ThinkingLevel | undefined {
const allowed = thinking.levelValues;
if (!allowed?.length) return undefined;
if (config.level && allowed.includes(config.level)) return config.level;
const mode = getThinkingMode(config);
if (mode === 'disabled') {
return (
(allowed.includes('minimal') && 'minimal') ||
(allowed.includes('low') && 'low') ||
thinking.defaultLevel
);
}
if (mode === 'enabled') return thinking.defaultLevel;
return undefined;
}
export function pickThinkingBudget(
thinking: ThinkingCapability,
config: ThinkingConfig,
): number | undefined {
const range = thinking.budgetRange;
if (!range) return undefined;
const mode = getThinkingMode(config);
if (mode === 'disabled' && range.disableValue !== undefined) {
return range.disableValue;
}
const rawBudget =
typeof config.budgetTokens === 'number' ? config.budgetTokens : thinking.defaultBudgetTokens;
return clampBudgetForCapability(thinking, rawBudget);
}
function defaultModeForCapability(thinking: ThinkingCapability): ThinkingMode {
return thinking.defaultMode ?? (thinking.defaultEnabled === false ? 'disabled' : 'enabled');
}
function defaultEffortForCapability(thinking: ThinkingCapability): ThinkingEffort | undefined {
return thinking.defaultEffort ?? thinking.effortValues?.[0];
}
function defaultLevelForCapability(thinking: ThinkingCapability): ThinkingLevel | undefined {
return thinking.defaultLevel ?? thinking.levelValues?.[0];
}
export function getDefaultThinkingConfig(
thinking?: ThinkingCapability,
): ThinkingConfig | undefined {
if (!supportsConfigurableThinking(thinking)) return undefined;
switch (thinking.control) {
case 'effort': {
const effort = defaultEffortForCapability(thinking);
return effort
? { mode: effort === 'none' ? 'disabled' : 'enabled', effort }
: { mode: defaultModeForCapability(thinking) };
}
case 'level': {
const level = defaultLevelForCapability(thinking);
return level ? { mode: 'enabled', level } : { mode: defaultModeForCapability(thinking) };
}
case 'toggle':
return { mode: defaultModeForCapability(thinking) };
case 'toggle-budget':
return {
mode: defaultModeForCapability(thinking),
budgetTokens: thinking.defaultBudgetTokens,
};
case 'budget-only':
return { mode: 'enabled', budgetTokens: thinking.defaultBudgetTokens };
case 'mode':
return { mode: defaultModeForCapability(thinking) };
default:
return undefined;
}
}
export function normalizeThinkingConfig(
thinking: ThinkingCapability | undefined,
config: ThinkingConfig | undefined,
): ThinkingConfig | undefined {
if (!supportsConfigurableThinking(thinking)) return undefined;
const mode = getThinkingMode(config);
switch (thinking.control) {
case 'effort': {
const effort =
(config ? pickThinkingEffort(thinking, config) : undefined) ??
defaultEffortForCapability(thinking);
if (!effort) return undefined;
return { mode: effort === 'none' ? 'disabled' : 'enabled', effort };
}
case 'level': {
const level =
(config ? pickThinkingLevel(thinking, config) : undefined) ??
defaultLevelForCapability(thinking);
if (!level) return undefined;
return { mode: 'enabled', level };
}
case 'toggle':
return { mode: mode ?? defaultModeForCapability(thinking) };
case 'toggle-budget': {
const normalizedMode = mode ?? defaultModeForCapability(thinking);
const budget = config ? pickThinkingBudget(thinking, config) : undefined;
return {
mode: normalizedMode,
budgetTokens: budget ?? thinking.defaultBudgetTokens,
};
}
case 'budget-only': {
const budget = config ? pickThinkingBudget(thinking, config) : undefined;
return {
mode: 'enabled',
budgetTokens: budget ?? thinking.defaultBudgetTokens,
};
}
case 'mode':
return { mode: mode ?? defaultModeForCapability(thinking) };
default:
return undefined;
}
}
export function getThinkingDisplayValue(
thinking: ThinkingCapability | undefined,
config: ThinkingConfig | undefined,
): string | undefined {
const normalized =
normalizeThinkingConfig(thinking, config) ?? getDefaultThinkingConfig(thinking);
if (!supportsConfigurableThinking(thinking) || !normalized) return undefined;
if (thinking.control === 'effort') return normalized.effort;
if (thinking.control === 'level') return normalized.level;
if (thinking.control === 'budget-only') {
return normalized.budgetTokens === -1 ? 'dynamic' : `${normalized.budgetTokens ?? ''}`;
}
if (thinking.control === 'toggle-budget') {
if (normalized.mode === 'disabled') return 'off';
if (normalized.budgetTokens === -1 && thinking.budgetRange?.allowDynamic) return 'auto';
return normalized.budgetTokens && normalized.budgetTokens !== -1
? `${normalized.budgetTokens}`
: 'on';
}
if (thinking.control === 'mode') return normalized.mode;
return normalized.mode === 'disabled' ? 'off' : 'on';
}