Complete local HTTP endpoint parity

This commit is contained in:
Georg Bauer
2026-07-25 14:18:57 +02:00
parent a1761fa731
commit 668d8b787e
13 changed files with 493 additions and 69 deletions

View File

@@ -6,6 +6,8 @@ pub(super) struct PreferenceDraft {
pub(super) dspark_enabled: bool,
pub(super) idle_timeout_minutes: String,
pub(super) endpoint_port: String,
pub(super) endpoint_enabled: bool,
pub(super) endpoint_cors: bool,
pub(super) context_tokens: String,
pub(super) max_generated_tokens: String,
pub(super) system_prompt: String,
@@ -51,6 +53,8 @@ impl PreferenceDraft {
dspark_enabled: speculative.dspark_enabled,
idle_timeout_minutes: preferences.idle_timeout_minutes.to_string(),
endpoint_port: preferences.endpoint_port.to_string(),
endpoint_enabled: preferences.endpoint_enabled,
endpoint_cors: preferences.endpoint_cors,
context_tokens: generation.context_tokens.to_string(),
max_generated_tokens: generation.max_generated_tokens.to_string(),
system_prompt: generation.system_prompt,
@@ -147,6 +151,8 @@ impl PreferenceDraft {
self.dspark_enabled = false;
self.idle_timeout_minutes = "10".into();
self.endpoint_port = "4000".into();
self.endpoint_enabled = true;
self.endpoint_cors = false;
self.context_tokens = defaults.context_tokens.to_string();
self.max_generated_tokens = defaults.max_generated_tokens.to_string();
self.system_prompt = defaults.system_prompt;
@@ -429,8 +435,18 @@ impl App {
return;
}
#[cfg(target_os = "macos")]
let pending_endpoint = if self.preferences.endpoint_port != i32::from(endpoint_port)
|| self._endpoint.is_none()
let endpoint_changed = self.preferences.endpoint_port != i32::from(endpoint_port)
|| self.preferences.endpoint_enabled != self.preference_draft.endpoint_enabled
|| self.preferences.endpoint_cors != self.preference_draft.endpoint_cors;
#[cfg(target_os = "macos")]
if endpoint_changed
&& self.preferences.endpoint_port == i32::from(endpoint_port)
&& self._endpoint.is_some()
{
self._endpoint = None;
}
let pending_endpoint = if self.preference_draft.endpoint_enabled
&& (endpoint_changed || self._endpoint.is_none())
{
let Some(generation) = &self.generation_service else {
self.preference_error = Some("The model runtime is unavailable.".into());
@@ -442,6 +458,7 @@ impl App {
models_path(),
application_support_path().join("kv-cache").join("http"),
endpoint_port,
self.preference_draft.endpoint_cors,
Arc::clone(&self.metrics),
) {
Ok(endpoint) => Some(endpoint),
@@ -460,6 +477,8 @@ impl App {
model.id(),
idle_timeout_minutes,
i32::from(endpoint_port),
self.preference_draft.endpoint_enabled,
self.preference_draft.endpoint_cors,
&generation,
&runtime,
) {
@@ -468,7 +487,9 @@ impl App {
#[cfg(target_os = "macos")]
update_runtime_preferences(&self.runtime_preferences, &self.preferences);
#[cfg(target_os = "macos")]
if let Some(endpoint) = pending_endpoint {
if endpoint_changed {
self._endpoint = pending_endpoint;
} else if let Some(endpoint) = pending_endpoint {
self._endpoint = Some(endpoint);
}
self.preference_draft = PreferenceDraft::from_saved(&self.preferences)

View File

@@ -107,12 +107,22 @@ impl App {
let endpoint_group = preference_group(
"LOCAL ENDPOINT",
column![
checkbox(
"Enable OpenAI-compatible endpoint",
self.preference_draft.endpoint_enabled,
)
.on_toggle(Message::PreferenceEndpointEnabledChanged),
preference_input_row(
"Port",
text_input("4000", &self.preference_draft.endpoint_port)
.on_input(Message::PreferenceEndpointPortChanged),
),
text("Listens on 127.0.0.1. Saving a changed port restarts the local endpoint.")
checkbox(
"Allow browser clients (CORS)",
self.preference_draft.endpoint_cors,
)
.on_toggle(Message::PreferenceEndpointCorsChanged),
text("Listens only on 127.0.0.1. Saving changed endpoint settings restarts it.")
.size(12),
]
.spacing(10),