feat(arr): add the OpenAI endpoint fields to /settings

Shown only when openai is among available_engines. Placeholders say the
base URL is optional and what a local one looks like.
This commit is contained in:
Miguel Palhas
2026-08-25 08:29:59 +01:00
parent 5aa914f81c
commit e467bd47fb
+27
View File
@@ -46,6 +46,15 @@ export interface SubtitleSettings {
provider_daily_budgets: Record<string, number>;
translator_daily_budgets: Record<string, number>;
remote_command_timeout_seconds: number;
/**
* Where the OpenAI-compatible backend points and which model it names
* (§15, #220). `null` on either means the backend's own default — that
* backend is anything speaking the shape, `llama.cpp` included, so both
* are settings rather than deployment facts. Neither is a secret; the API
* key stays in the environment.
*/
openai_base_url: string | null;
openai_model: string | null;
/** Engines this binary compiled in — `translation_engine` is always one of these, or null. */
available_engines: string[];
}
@@ -815,6 +824,20 @@ export function settingsMain(views: { hide: () => void }[], goHome: () => void):
const timeout = numberControl(settings.remote_command_timeout_seconds);
grid.append(field("remote command timeout (s)", timeout));
// #220: only meaningful when this build compiled the backend in, and the
// engine list is exactly that fact. Placeholders carry the two things
// the labels cannot: that the base URL is optional, and what a local one
// looks like.
const hasOpenAi = settings.available_engines.includes("openai");
const openAiBaseUrl = textControl(
settings.openai_base_url ?? "",
"optional — e.g. http://127.0.0.1:8080/v1",
);
const openAiModel = textControl(settings.openai_model ?? "", "optional — e.g. gpt-4o-mini");
if (hasOpenAi) {
grid.append(field("openai base url", openAiBaseUrl), field("openai model", openAiModel));
}
panel.append(grid);
if (!hasEngines) {
panel.append(
@@ -908,6 +931,10 @@ export function settingsMain(views: { hide: () => void }[], goHome: () => void):
provider_daily_budgets: providerBudgets,
translator_daily_budgets: translatorBudgets,
remote_command_timeout_seconds: Number(timeout.value),
// An emptied field is "use the backend's default", which the API
// stores as NULL.
openai_base_url: hasOpenAi ? openAiBaseUrl.value.trim() || null : settings.openai_base_url,
openai_model: hasOpenAi ? openAiModel.value.trim() || null : settings.openai_model,
};
void saveSubtitleSettings(input).then((outcome) => {
if (outcome.ok) {