mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-18 21:22:28 +03:00
173 lines
6.4 KiB
TypeScript
173 lines
6.4 KiB
TypeScript
/**
|
|
* Modality Bridge default configuration values (PR-1).
|
|
*
|
|
* New `modalityBridge*` settings keys supersede the legacy `visionBridge*`
|
|
* keys; the legacy keys stay accepted as a fallback for one release cycle
|
|
* (rollback window) and are resolved here in a single place.
|
|
*/
|
|
import { VISION_BRIDGE_DEFAULTS } from "./visionBridgeDefaults";
|
|
|
|
export type VisionBridgeMode = "auto" | "describe" | "reroute";
|
|
export type VideoSamplingPolicy = "uniform" | "scene_aware";
|
|
|
|
export const VIDEO_BRIDGE_TIMEOUT_MIN_MS = 1_000;
|
|
export const VIDEO_BRIDGE_TIMEOUT_MAX_MS = 120_000;
|
|
|
|
export const MODALITY_BRIDGE_DEFAULTS = {
|
|
visionMode: "auto" as VisionBridgeMode,
|
|
visionTaskAware: true,
|
|
cacheEnabled: true,
|
|
cacheTtlMinutes: 60,
|
|
cacheMaxEntries: 200,
|
|
// 0 = no cap (existing behavior, description is passed through in full).
|
|
visionMaxChars: 0,
|
|
audioEnabled: true,
|
|
audioModel: "",
|
|
audioTimeoutMs: 60000,
|
|
audioMaxClips: 3,
|
|
videoEnabled: false,
|
|
videoModel: "",
|
|
videoFrameCount: 8,
|
|
videoSamplingPolicy: "uniform" as VideoSamplingPolicy,
|
|
videoMaxVideos: 1,
|
|
videoTimeoutMs: 120000,
|
|
} as const;
|
|
|
|
export interface VisionBridgeRuntimeSettings {
|
|
enabled: boolean;
|
|
mode: VisionBridgeMode;
|
|
model: string;
|
|
taskAware: boolean;
|
|
prompt: string;
|
|
timeoutMs: number;
|
|
maxImages: number;
|
|
maxChars: number;
|
|
cacheEnabled: boolean;
|
|
cacheTtlMinutes: number;
|
|
cacheMaxEntries: number;
|
|
}
|
|
|
|
export interface AudioBridgeRuntimeSettings {
|
|
enabled: boolean;
|
|
model: string;
|
|
timeoutMs: number;
|
|
maxClips: number;
|
|
cacheEnabled: boolean;
|
|
cacheTtlMinutes: number;
|
|
cacheMaxEntries: number;
|
|
}
|
|
|
|
export interface VideoBridgeRuntimeSettings {
|
|
enabled: boolean;
|
|
model: string;
|
|
frameCount: number;
|
|
samplingPolicy: VideoSamplingPolicy;
|
|
maxVideos: number;
|
|
timeoutMs: number;
|
|
cacheEnabled: boolean;
|
|
cacheTtlMinutes: number;
|
|
cacheMaxEntries: number;
|
|
}
|
|
|
|
// Typed candidate pickers: a stored value of the wrong type (e.g. the string
|
|
// "off" in a boolean field) is skipped so the next candidate/default wins.
|
|
function pickBoolean(...values: unknown[]): boolean | undefined {
|
|
for (const v of values) if (typeof v === "boolean") return v;
|
|
return undefined;
|
|
}
|
|
|
|
function pickNumber(...values: unknown[]): number | undefined {
|
|
for (const v of values) if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
return undefined;
|
|
}
|
|
|
|
function pickString(...values: unknown[]): string | undefined {
|
|
for (const v of values) if (typeof v === "string") return v;
|
|
return undefined;
|
|
}
|
|
|
|
/** New modalityBridge* keys win; legacy visionBridge* keys are a one-cycle fallback. */
|
|
export function resolveVisionBridgeRuntimeSettings(
|
|
settings: Record<string, unknown> | null | undefined
|
|
): VisionBridgeRuntimeSettings {
|
|
const s = settings ?? {};
|
|
const mode = pickString(s.modalityBridgeVisionMode);
|
|
return {
|
|
enabled:
|
|
pickBoolean(s.modalityBridgeVisionEnabled, s.visionBridgeEnabled) ??
|
|
VISION_BRIDGE_DEFAULTS.enabled,
|
|
mode: mode === "describe" || mode === "reroute" ? mode : MODALITY_BRIDGE_DEFAULTS.visionMode,
|
|
model:
|
|
pickString(s.modalityBridgeVisionModel, s.visionBridgeModel) ?? VISION_BRIDGE_DEFAULTS.model,
|
|
taskAware:
|
|
pickBoolean(s.modalityBridgeVisionTaskAware) ?? MODALITY_BRIDGE_DEFAULTS.visionTaskAware,
|
|
prompt:
|
|
pickString(s.modalityBridgeVisionPrompt, s.visionBridgePrompt) ??
|
|
VISION_BRIDGE_DEFAULTS.prompt,
|
|
timeoutMs:
|
|
pickNumber(s.modalityBridgeVisionTimeout, s.visionBridgeTimeout) ??
|
|
VISION_BRIDGE_DEFAULTS.timeoutMs,
|
|
maxImages:
|
|
pickNumber(s.modalityBridgeVisionMaxImages, s.visionBridgeMaxImages) ??
|
|
VISION_BRIDGE_DEFAULTS.maxImagesPerRequest,
|
|
maxChars: pickNumber(s.modalityBridgeVisionMaxChars) ?? MODALITY_BRIDGE_DEFAULTS.visionMaxChars,
|
|
cacheEnabled:
|
|
pickBoolean(s.modalityBridgeCacheEnabled) ?? MODALITY_BRIDGE_DEFAULTS.cacheEnabled,
|
|
cacheTtlMinutes:
|
|
pickNumber(s.modalityBridgeCacheTtlMinutes) ?? MODALITY_BRIDGE_DEFAULTS.cacheTtlMinutes,
|
|
cacheMaxEntries:
|
|
pickNumber(s.modalityBridgeCacheMaxEntries) ?? MODALITY_BRIDGE_DEFAULTS.cacheMaxEntries,
|
|
};
|
|
}
|
|
|
|
/** Resolve persisted Audio Bridge settings with the shared PR-1 defaults. */
|
|
export function resolveAudioBridgeRuntimeSettings(
|
|
settings: Record<string, unknown> | null | undefined
|
|
): AudioBridgeRuntimeSettings {
|
|
const s = settings ?? {};
|
|
return {
|
|
enabled: pickBoolean(s.modalityBridgeAudioEnabled) ?? MODALITY_BRIDGE_DEFAULTS.audioEnabled,
|
|
model: pickString(s.modalityBridgeAudioModel) ?? MODALITY_BRIDGE_DEFAULTS.audioModel,
|
|
timeoutMs: pickNumber(s.modalityBridgeAudioTimeout) ?? MODALITY_BRIDGE_DEFAULTS.audioTimeoutMs,
|
|
maxClips: pickNumber(s.modalityBridgeAudioMaxClips) ?? MODALITY_BRIDGE_DEFAULTS.audioMaxClips,
|
|
cacheEnabled:
|
|
pickBoolean(s.modalityBridgeCacheEnabled) ?? MODALITY_BRIDGE_DEFAULTS.cacheEnabled,
|
|
cacheTtlMinutes:
|
|
pickNumber(s.modalityBridgeCacheTtlMinutes) ?? MODALITY_BRIDGE_DEFAULTS.cacheTtlMinutes,
|
|
cacheMaxEntries:
|
|
pickNumber(s.modalityBridgeCacheMaxEntries) ?? MODALITY_BRIDGE_DEFAULTS.cacheMaxEntries,
|
|
};
|
|
}
|
|
|
|
/** Resolve persisted Video Bridge settings with safe, bounded defaults. */
|
|
export function resolveVideoBridgeRuntimeSettings(
|
|
settings: Record<string, unknown> | null | undefined
|
|
): VideoBridgeRuntimeSettings {
|
|
const s = settings ?? {};
|
|
return {
|
|
enabled: pickBoolean(s.modalityBridgeVideoEnabled) ?? MODALITY_BRIDGE_DEFAULTS.videoEnabled,
|
|
model: pickString(s.modalityBridgeVideoModel) ?? MODALITY_BRIDGE_DEFAULTS.videoModel,
|
|
frameCount:
|
|
pickNumber(s.modalityBridgeVideoFrameCount) ?? MODALITY_BRIDGE_DEFAULTS.videoFrameCount,
|
|
samplingPolicy:
|
|
pickString(s.modalityBridgeVideoSamplingPolicy) === "scene_aware"
|
|
? "scene_aware"
|
|
: MODALITY_BRIDGE_DEFAULTS.videoSamplingPolicy,
|
|
maxVideos:
|
|
pickNumber(s.modalityBridgeVideoMaxVideos) ?? MODALITY_BRIDGE_DEFAULTS.videoMaxVideos,
|
|
timeoutMs: Math.min(
|
|
VIDEO_BRIDGE_TIMEOUT_MAX_MS,
|
|
Math.max(
|
|
VIDEO_BRIDGE_TIMEOUT_MIN_MS,
|
|
pickNumber(s.modalityBridgeVideoTimeout) ?? MODALITY_BRIDGE_DEFAULTS.videoTimeoutMs
|
|
)
|
|
),
|
|
cacheEnabled:
|
|
pickBoolean(s.modalityBridgeCacheEnabled) ?? MODALITY_BRIDGE_DEFAULTS.cacheEnabled,
|
|
cacheTtlMinutes:
|
|
pickNumber(s.modalityBridgeCacheTtlMinutes) ?? MODALITY_BRIDGE_DEFAULTS.cacheTtlMinutes,
|
|
cacheMaxEntries:
|
|
pickNumber(s.modalityBridgeCacheMaxEntries) ?? MODALITY_BRIDGE_DEFAULTS.cacheMaxEntries,
|
|
};
|
|
}
|