diff --git a/README.md b/README.md index ec541b69..85136981 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ Persistent admin and time travel
- When something breaks, admin mode gives you a stable control plane, and Git-backed history lets you roll back user or group changes without taking everyone down with you. + Enter Space opens the native workspace shell. Admin mode gives you the stable control plane, and Git-backed history lets you roll back user or group changes without taking everyone down with you. diff --git a/app/L0/_all/mod/_core/admin/views/agent/AGENTS.md b/app/L0/_all/mod/_core/admin/views/agent/AGENTS.md index 705608d2..9bcace03 100644 --- a/app/L0/_all/mod/_core/admin/views/agent/AGENTS.md +++ b/app/L0/_all/mod/_core/admin/views/agent/AGENTS.md @@ -83,7 +83,7 @@ Current behavior: - the admin HuggingFace panel should let users either enter a compatible repo id directly or pick from the shared saved-model list, then load or unload that selection directly from the modal while reusing the same progress block and current-model status area as the routed sidebar - the admin local-provider panel should show the selected model separately from the currently loaded model, so an unloaded but configured selection is visible immediately instead of looking stuck on `None loaded` - when no Hugging Face model is selected and the shared saved-model list has entries, the admin local-provider panel should preselect the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded -- when no Hugging Face model is selected, no model is loaded, and the shared saved-model list is empty, the admin local-provider panel should prefill the model field with the same default used by the routed testing page: `onnx-community/gemma-4-E4B-it-ONNX` +- when no Hugging Face model is selected, no model is loaded, and the shared saved-model list is empty, the admin local-provider panel should prefill the model field with the same default used by the routed testing page: `onnx-community/Qwen3-0.6B-ONNX` - admin-local provider inputs mounted through the shared sidebar components should write back through explicit `store.js` setter methods instead of depending on implicit nested `x-model` mutation across component boundaries - discarding a HuggingFace repo from the routed testing harness removes it from the shared browser-side saved-model list too, so it disappears from the admin saved-model shortcut selector until it is loaded again - admin should subscribe to `_core/huggingface/manager.js` directly, so the modal and send flow read the same live worker state, saved-model options, loading, and streaming behavior as the routed Hugging Face surface within the current browser context diff --git a/app/L0/_all/mod/_core/admin/views/agent/store.js b/app/L0/_all/mod/_core/admin/views/agent/store.js index 4aacf7b4..65b97b1a 100644 --- a/app/L0/_all/mod/_core/admin/views/agent/store.js +++ b/app/L0/_all/mod/_core/admin/views/agent/store.js @@ -803,17 +803,6 @@ const model = { return false; } - const preferredSavedModel = huggingfaceManager.refreshPreferredSavedModelSelection(); - - if (preferredSavedModel?.modelId && preferredSavedModel?.dtype) { - this.settingsDraft = { - ...this.settingsDraft, - huggingfaceDtype: preferredSavedModel.dtype, - huggingfaceModel: preferredSavedModel.modelId - }; - return true; - } - const snapshot = huggingfaceManager.getSnapshot(); const hasSavedModels = Array.isArray(snapshot.savedModels) && snapshot.savedModels.length > 0; const activeModelId = normalizeHuggingFaceModelInput(snapshot.activeModelId || ""); @@ -1633,21 +1622,31 @@ const model = { }, openSettingsDialog() { + const provider = config.normalizeAdminChatLlmProvider(this.settings.provider); + this.settingsDraft = { ...this.settings, promptBudgetRatios: clonePromptBudgetRatios(this.settings.promptBudgetRatios) }; this.syncHuggingFaceFromManager(); - this.prefillSettingsDraftDefaultHuggingFaceModel(); - if (!String(this.settingsDraft.huggingfaceDtype || "").trim()) { - this.settingsDraft.huggingfaceDtype = DTYPE_OPTIONS[0]?.value || config.DEFAULT_ADMIN_CHAT_SETTINGS.huggingfaceDtype; + if (provider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL) { + this.prefillSettingsDraftDefaultHuggingFaceModel(); + + if (!String(this.settingsDraft.huggingfaceDtype || "").trim()) { + this.settingsDraft.huggingfaceDtype = DTYPE_OPTIONS[0]?.value || config.DEFAULT_ADMIN_CHAT_SETTINGS.huggingfaceDtype; + } + } else { + this.settingsDraft.huggingfaceModel = ""; + this.settingsDraft.huggingfaceDtype = ""; } - void this.warmSettingsDraftLocalProvider() - .catch((error) => { - this.reportError("warming the local-provider settings draft", error); - }); + if (provider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL) { + void this.warmSettingsDraftLocalProvider() + .catch((error) => { + this.reportError("warming the local-provider settings draft", error); + }); + } openDialog(this.refs.settingsDialog); }, @@ -1656,9 +1655,17 @@ const model = { }, setSettingsProvider(provider) { + const nextProvider = config.normalizeAdminChatLlmProvider(provider); + this.settingsDraft = { ...this.settingsDraft, - provider: config.normalizeAdminChatLlmProvider(provider) + huggingfaceDtype: nextProvider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL + ? this.settingsDraft.huggingfaceDtype + : "", + huggingfaceModel: nextProvider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL + ? this.settingsDraft.huggingfaceModel + : "", + provider: nextProvider }; if (this.isSettingsDraftUsingLocalProvider) { @@ -1877,8 +1884,12 @@ const model = { this.settings = { apiEndpoint: (this.settingsDraft.apiEndpoint || "").trim(), apiKey: (this.settingsDraft.apiKey || "").trim(), - huggingfaceDtype: (this.settingsDraft.huggingfaceDtype || "").trim(), - huggingfaceModel: normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || ""), + huggingfaceDtype: provider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL + ? (this.settingsDraft.huggingfaceDtype || "").trim() + : "", + huggingfaceModel: provider === config.ADMIN_CHAT_LLM_PROVIDER.LOCAL + ? normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || "") + : "", localProvider, maxTokens, model: (this.settingsDraft.model || "").trim(), diff --git a/app/L0/_all/mod/_core/documentation/docs/agent/onscreen-agent-runtime.md b/app/L0/_all/mod/_core/documentation/docs/agent/onscreen-agent-runtime.md index 30d18b95..b01f7d5c 100644 --- a/app/L0/_all/mod/_core/documentation/docs/agent/onscreen-agent-runtime.md +++ b/app/L0/_all/mod/_core/documentation/docs/agent/onscreen-agent-runtime.md @@ -110,7 +110,7 @@ The settings and prompt-history dialogs reuse the shared `_core/visual/forms/dia Caught overlay runtime errors are logged through `console.error` and shown through the shared toast stack from `_core/visual/chrome/toast.js`. The composer placeholder still belongs to ready-state and lightweight status guidance, so raw exception text should not be pushed into the textarea placeholder. Overlay execution transcripts now use the shared YAML-first formatter for both console logs and returned values, emitting block headers such as `log↓`, `warn↓`, `error↓`, and `result↓` so structured telemetry stays complete across the thread and execution cards. Queued follow-up submissions wait behind any just-finished assistant reply that contains `_____javascript`; the runtime must execute the block and append the `execution-output` turn before sending the queued draft, so the next model request sees the execution result in history. Immediately before those execution results are serialized back into the `execution-output` follow-up turn, the overlay also runs the shared assistant-message evaluation seam; the current first-party hook from `_core/agent-chat` prepends synthetic loop warnings when the exact same assistant message reappears, using `info` on the 2nd send, `warn` on the 3rd send, and `error` on the 4th send onward. -The settings dialog now has two provider tabs named `API` and `Local`. `API` keeps the OpenAI-compatible endpoint, model, and key fields. `Local` mounts the shared Hugging Face config sidebar in onscreen mode, so the overlay reads the same saved-model list and live WebGPU worker state as the routed Local LLM page and the admin chat. Opening the Local tab should refresh saved-model shortcuts without booting the worker; saving local settings persists the selected repo id and dtype, then starts background model preparation. When no local model is selected and saved models exist, the Local panel preselects the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded. When no local model is selected, no local model is loaded, and the shared saved-model list is empty, the Local panel prefills the Hugging Face model field with the same testing-page default: `onnx-community/gemma-4-E4B-it-ONNX`. +The settings dialog now has two provider tabs named `API` and `Local`. `API` keeps the OpenAI-compatible endpoint, model, and key fields. `Local` mounts the shared Hugging Face config sidebar in onscreen mode, so the overlay reads the same saved-model list and live WebGPU worker state as the routed Local LLM page and the admin chat. Opening the Local tab should refresh saved-model shortcuts without booting the worker; saving local settings persists the selected repo id and dtype, then starts background model preparation. When no local model is selected and saved models exist, the Local panel preselects the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded. When no local model is selected, no local model is loaded, and the shared saved-model list is empty, the Local panel prefills the Hugging Face model field with the same testing-page default: `onnx-community/Qwen3-0.6B-ONNX`. The API-key composer blocker applies only to the default API-provider configuration with no API key, where the composer shows a centered `Set LLM API key` action over the disabled textarea. Local Hugging Face mode can send without an API key and falls back to loading the selected local model on the first message if background preparation has not finished. diff --git a/app/L0/_all/mod/_core/documentation/docs/app/admin-agent-runtime.md b/app/L0/_all/mod/_core/documentation/docs/app/admin-agent-runtime.md index 458c5902..6637643a 100644 --- a/app/L0/_all/mod/_core/documentation/docs/app/admin-agent-runtime.md +++ b/app/L0/_all/mod/_core/documentation/docs/app/admin-agent-runtime.md @@ -64,7 +64,7 @@ The admin settings modal now starts with a provider switch: Below those provider-specific sections, the shared settings area also exposes `max_tokens`, prompt-budget ratios for `system`, `history`, and `transient`, plus the separate single-history-message ratio used by the shared trimming path. Those values are persisted in `prompt_budget_ratios` and feed the same prompt-budget builder used by the onscreen agent: prepared entries and prompt items reuse cached token counts, single live history messages are capped first, contributor-level trims must each be at least `250` tokens, and `system` or `transient` falls back to one combined section-body trim when smaller contributor cuts would otherwise be required. -When no local model is selected and saved models exist, the admin local panel preselects the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded. When no local model is selected, no local model is loaded, and the shared saved-model list is empty, the admin local panel prefills the Hugging Face model field with the same testing-page default: `onnx-community/gemma-4-E4B-it-ONNX`. +When no local model is selected and saved models exist, the admin local panel preselects the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded. When no local model is selected, no local model is loaded, and the shared saved-model list is empty, the admin local panel prefills the Hugging Face model field with the same testing-page default: `onnx-community/Qwen3-0.6B-ONNX`. The stored config keeps both API settings and the selected local provider state: diff --git a/app/L0/_all/mod/_core/documentation/docs/app/huggingface-browser-runtime.md b/app/L0/_all/mod/_core/documentation/docs/app/huggingface-browser-runtime.md index ae3bafec..7c62f31f 100644 --- a/app/L0/_all/mod/_core/documentation/docs/app/huggingface-browser-runtime.md +++ b/app/L0/_all/mod/_core/documentation/docs/app/huggingface-browser-runtime.md @@ -44,7 +44,7 @@ The page owns: - a simple testing chat with system prompt, user messages, streamed assistant replies, stop, and clear-chat - compact response metrics inline under each assistant reply -When admin or onscreen chat local settings have no selected model and the browser has saved Hugging Face models, the shared sidebar preselects the browser-wide last successfully loaded saved model from local storage. If that entry was discarded, it falls back to the first saved model. When the browser has no saved local Hugging Face models and no persisted auto-reload target, the routed testing-page model input prefills `onnx-community/gemma-4-E4B-it-ONNX` as the empty-state suggestion; admin and onscreen chat local settings reuse that same default only when there is no preferred saved-model selection. The default generation cap is `16384` max new tokens unless the user changes it. +When admin or onscreen chat local settings have no selected model and the browser has saved Hugging Face models, the shared sidebar preselects the browser-wide last successfully loaded saved model from local storage. If that entry was discarded, it falls back to the first saved model. When the browser has no saved local Hugging Face models and no persisted auto-reload target, the routed testing-page model input prefills `onnx-community/Qwen3-0.6B-ONNX` as the empty-state suggestion; admin and onscreen chat local settings reuse that same default only when there is no preferred saved-model selection. The default generation cap is `16384` max new tokens unless the user changes it. This is not a general agent surface. It does not expose tool execution, queueing, attachments, persisted conversations, or backend orchestration. diff --git a/app/L0/_all/mod/_core/huggingface/AGENTS.md b/app/L0/_all/mod/_core/huggingface/AGENTS.md index c5b01a5e..f0fc3b04 100644 --- a/app/L0/_all/mod/_core/huggingface/AGENTS.md +++ b/app/L0/_all/mod/_core/huggingface/AGENTS.md @@ -40,7 +40,7 @@ Current route contract: - `manager.js` exposes startup explicitly through `isWorkerBooting`; routed, admin, and onscreen consumers should treat an unbooted idle manager as `Idle`, not as `Starting`, and should reserve `Starting` for an actual in-flight worker boot - `manager.js` snapshots and subscription payloads must stay plain-data and clone-safe; do not leak raw browser host objects or rely on generic `structuredClone(...)` fallbacks that can fail on reactive proxies - when the admin or onscreen local-provider draft has no selected model and saved Hugging Face models exist in browser storage, the sidebar should preselect the last successfully loaded saved model from browser-wide `localStorage`; if that stored model is no longer in the saved list, it should fall back to the first saved entry -- when the browser has no saved models, no active model, and no persisted auto-reload target, the routed testing-page model input should prefill `onnx-community/gemma-4-E4B-it-ONNX` as the empty-state suggestion; admin and onscreen chat sidebars should reuse that same empty-state default only when their selected local model is blank and there is no preferred saved-model selection +- when the browser has no saved models, no active model, and no persisted auto-reload target, the routed testing-page model input should prefill `onnx-community/Qwen3-0.6B-ONNX` as the empty-state suggestion; admin and onscreen chat sidebars should reuse that same empty-state default only when their selected local model is blank and there is no preferred saved-model selection - the sidebar should surface the currently loaded model first, inside a slightly more prominent rounded panel with a larger model label, a compact right-aligned state badge, and an unload control beside the model name - while a model is loading, that action switches to `Stop`; stopping a Hugging Face load or unload resets the shared singleton-managed worker and boots a fresh one instead of leaving stale partial state behind - the load progress area should show a debounced aggregate download status below the bar, with total transferred bytes appended such as `Downloading model files (412 MB / 1.8 GB)` instead of rapidly alternating per-file names diff --git a/app/L0/_all/mod/_core/huggingface/config-sidebar.html b/app/L0/_all/mod/_core/huggingface/config-sidebar.html index 34cb12fd..90c5f80d 100644 --- a/app/L0/_all/mod/_core/huggingface/config-sidebar.html +++ b/app/L0/_all/mod/_core/huggingface/config-sidebar.html @@ -60,7 +60,7 @@

Models

:value="$store.huggingface.modelInput" @input="$store.huggingface.setModelInput($event.target.value)" :disabled="$store.huggingface.isGenerating" - placeholder="onnx-community/gemma-4-E4B-it-ONNX or https://huggingface.co/..." + placeholder="onnx-community/Qwen3-0.6B-ONNX or https://huggingface.co/..." /> @@ -228,7 +228,7 @@

Advanced

type="text" :value="$store.adminAgent.settingsDraft.huggingfaceModel" @input="$store.adminAgent.handleSettingsHuggingFaceModelInput($event.target.value)" - placeholder="onnx-community/gemma-4-E4B-it-ONNX" + placeholder="onnx-community/Qwen3-0.6B-ONNX" /> @@ -342,7 +342,7 @@

Advanced

type="text" :value="$store.onscreenAgent.settingsDraft.huggingfaceModel" @input="$store.onscreenAgent.handleSettingsHuggingFaceModelInput($event.target.value)" - placeholder="onnx-community/gemma-4-E4B-it-ONNX" + placeholder="onnx-community/Qwen3-0.6B-ONNX" /> diff --git a/app/L0/_all/mod/_core/huggingface/helpers.js b/app/L0/_all/mod/_core/huggingface/helpers.js index 18060e7e..6c3062cf 100644 --- a/app/L0/_all/mod/_core/huggingface/helpers.js +++ b/app/L0/_all/mod/_core/huggingface/helpers.js @@ -1,6 +1,7 @@ export const DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant."; export const DEFAULT_DTYPE = "q4"; -export const DEFAULT_MODEL_INPUT = "onnx-community/gemma-4-E4B-it-ONNX"; +export const LEGACY_DEFAULT_MODEL_INPUT = "onnx-community/gemma-4-E4B-it-ONNX"; +export const DEFAULT_MODEL_INPUT = "onnx-community/Qwen3-0.6B-ONNX"; export const DEFAULT_MAX_NEW_TOKENS = 16384; export const COMPATIBLE_MODELS_URL = "https://huggingface.co/onnx-community/models"; export const HUGGINGFACE_SAVED_MODELS_STORAGE_KEY = "space.huggingface.saved-models"; @@ -209,9 +210,23 @@ export function readSavedModelEntries() { return []; } - return parsedValue + const nextEntries = parsedValue .map((entry) => createSavedModelEntry(entry)) + .filter((entry) => entry?.modelId !== LEGACY_DEFAULT_MODEL_INPUT) .filter(Boolean); + + if (nextEntries.length !== parsedValue.length) { + try { + globalThis.localStorage?.setItem( + HUGGINGFACE_SAVED_MODELS_STORAGE_KEY, + JSON.stringify(nextEntries) + ); + } catch { + // Ignore storage write failures and still return the sanitized list. + } + } + + return nextEntries; } catch { return []; } diff --git a/app/L0/_all/mod/_core/huggingface/manager.js b/app/L0/_all/mod/_core/huggingface/manager.js index 9862bb4e..90415963 100644 --- a/app/L0/_all/mod/_core/huggingface/manager.js +++ b/app/L0/_all/mod/_core/huggingface/manager.js @@ -4,6 +4,7 @@ import { DEFAULT_DTYPE, DEFAULT_MAX_NEW_TOKENS, DEFAULT_MODEL_INPUT, + LEGACY_DEFAULT_MODEL_INPUT, discardCachedModelEntries, describeModelSelection, DTYPE_OPTIONS, @@ -273,6 +274,11 @@ function readPersistedModelSelection() { return null; } + if (modelId === LEGACY_DEFAULT_MODEL_INPUT) { + globalThis.localStorage?.removeItem(PERSISTED_MODEL_STORAGE_KEY); + return null; + } + return { dtype: String(parsedValue.dtype || DEFAULT_DTYPE).trim() || DEFAULT_DTYPE, maxNewTokens: normalizeMaxNewTokens(parsedValue.maxNewTokens), diff --git a/app/L0/_all/mod/_core/onscreen_agent/AGENTS.md b/app/L0/_all/mod/_core/onscreen_agent/AGENTS.md index e8dc5099..ce995a81 100644 --- a/app/L0/_all/mod/_core/onscreen_agent/AGENTS.md +++ b/app/L0/_all/mod/_core/onscreen_agent/AGENTS.md @@ -283,7 +283,7 @@ Current overlay behavior: - the settings modal keeps a provider switch with exactly two tabs named `API` and `Local`; API settings show endpoint, model, and API key fields, while local settings mount the shared `_core/huggingface/config-sidebar.html` component in `onscreen` mode - local provider settings are limited to the shared Hugging Face browser runtime for now; the overlay subscribes to `_core/huggingface/manager.js`, reads the same saved-model list and live worker state as the routed Local LLM page, and should not boot the worker just because the modal opened - when no Hugging Face model is selected and the shared saved-model list has entries, the overlay local-provider panel should preselect the browser-wide last successfully loaded saved model from `_core/huggingface/manager.js`, falling back to the first saved entry if that last-used entry was discarded -- when no Hugging Face model is selected, no model is loaded, and the shared saved-model list is empty, the overlay local-provider panel should prefill the model field with the same default used by the routed testing page: `onnx-community/gemma-4-E4B-it-ONNX` +- when no Hugging Face model is selected, no model is loaded, and the shared saved-model list is empty, the overlay local-provider panel should prefill the model field with the same default used by the routed testing page: `onnx-community/Qwen3-0.6B-ONNX` - saving local settings must persist the selected Hugging Face repo id and dtype, then start background model preparation; the first local send remains the fallback load trigger if that preparation has not finished - local-provider sends should use the same prompt assembly path as API sends, including the full firmware prompt, prompt-include sections, skill catalog, auto-loaded skill context, custom instructions, history, and transient context; the routed `_core/huggingface` testing page remains the first-party plain system-prompt-only local-LLM surface - local-provider sends should reuse the same final transport message payload that the API path sends upstream; `requestBody.messages` is the local runtime input, while the richer prepared prompt entries remain the prompt-history inspection surface diff --git a/app/L0/_all/mod/_core/onscreen_agent/store.js b/app/L0/_all/mod/_core/onscreen_agent/store.js index ae4fba33..d62800b0 100644 --- a/app/L0/_all/mod/_core/onscreen_agent/store.js +++ b/app/L0/_all/mod/_core/onscreen_agent/store.js @@ -2945,17 +2945,6 @@ const model = { return false; } - const preferredSavedModel = huggingfaceManager.refreshPreferredSavedModelSelection(); - - if (preferredSavedModel?.modelId && preferredSavedModel?.dtype) { - this.settingsDraft = { - ...this.settingsDraft, - huggingfaceDtype: preferredSavedModel.dtype, - huggingfaceModel: preferredSavedModel.modelId - }; - return true; - } - const snapshot = huggingfaceManager.getSnapshot(); const hasSavedModels = Array.isArray(snapshot.savedModels) && snapshot.savedModels.length > 0; const activeModelId = normalizeHuggingFaceModelInput(snapshot.activeModelId || ""); @@ -4394,24 +4383,34 @@ const model = { }, openSettingsDialog() { + const provider = config.normalizeOnscreenAgentLlmProvider(this.settings.provider); + this.settingsDraft = { ...this.settings, promptBudgetRatios: clonePromptBudgetRatios(this.settings.promptBudgetRatios) }; this.syncHuggingFaceFromManager(); - this.prefillSettingsDraftDefaultHuggingFaceModel(); - if (!String(this.settingsDraft.huggingfaceDtype || "").trim()) { - this.settingsDraft.huggingfaceDtype = - DTYPE_OPTIONS[0]?.value || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.huggingfaceDtype; + if (provider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL) { + this.prefillSettingsDraftDefaultHuggingFaceModel(); + + if (!String(this.settingsDraft.huggingfaceDtype || "").trim()) { + this.settingsDraft.huggingfaceDtype = + DTYPE_OPTIONS[0]?.value || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.huggingfaceDtype; + } + } else { + this.settingsDraft.huggingfaceModel = ""; + this.settingsDraft.huggingfaceDtype = ""; } this.systemPromptDraft = this.systemPrompt; - void this.warmSettingsDraftLocalProvider().catch((error) => { - this.reportError("warming the local-provider settings draft", error, { - preserveStatus: true + if (provider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL) { + void this.warmSettingsDraftLocalProvider().catch((error) => { + this.reportError("warming the local-provider settings draft", error, { + preserveStatus: true + }); }); - }); + } openDialog(resolveDialogRef(this.refs, "settingsDialog", SETTINGS_DIALOG_ELEMENT_ID)); }, @@ -4420,9 +4419,17 @@ const model = { }, setSettingsProvider(provider) { + const nextProvider = config.normalizeOnscreenAgentLlmProvider(provider); + this.settingsDraft = { ...this.settingsDraft, - provider: config.normalizeOnscreenAgentLlmProvider(provider) + huggingfaceDtype: nextProvider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL + ? this.settingsDraft.huggingfaceDtype + : "", + huggingfaceModel: nextProvider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL + ? this.settingsDraft.huggingfaceModel + : "", + provider: nextProvider }; if (this.isSettingsDraftUsingLocalProvider) { @@ -4604,8 +4611,12 @@ const model = { this.settings = { apiEndpoint: (this.settingsDraft.apiEndpoint || "").trim(), apiKey: (this.settingsDraft.apiKey || "").trim(), - huggingfaceDtype: (this.settingsDraft.huggingfaceDtype || "").trim(), - huggingfaceModel: normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || ""), + huggingfaceDtype: provider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL + ? (this.settingsDraft.huggingfaceDtype || "").trim() + : "", + huggingfaceModel: provider === config.ONSCREEN_AGENT_LLM_PROVIDER.LOCAL + ? normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || "") + : "", localProvider, maxTokens, model: (this.settingsDraft.model || "").trim(), diff --git a/app/share/novamaster-scout.html b/app/share/novamaster-scout.html new file mode 100644 index 00000000..ac0f5a3f --- /dev/null +++ b/app/share/novamaster-scout.html @@ -0,0 +1,227 @@ + + + + + +NovaMaster Scout + + + +
+
+

🛰️ NovaMaster Scout

+ Real-time stack health monitor +
+
● checking
+
+
+ + +
+
+
+ ⚠️ Cross-origin (CORS) may block health checks from browser. Serve via python3 -m http.server 8080 or open via Space Agent for best results. +
+
+
0 online
+
0 offline
+
0 CORS
+
+ + + + + \ No newline at end of file diff --git a/server/pages/AGENTS.md b/server/pages/AGENTS.md index e779cc58..79c3f29d 100644 --- a/server/pages/AGENTS.md +++ b/server/pages/AGENTS.md @@ -110,7 +110,7 @@ Current public shell assets: - must stay safe even when routed customware is broken - must not depend on authenticated `/mod/...` assets - is served for launcher-eligible sessions; in multi-user mode, unauthenticated requests are redirected to `/login` before this shell loads -- owns the firmware-backed launcher UI that links to `/` and `/admin`, labeled as Enter Space and Admin Mode, and when the Electron preload bridge reports a packaged desktop runtime with updater support it also runs a fresh background update check on each shell load unless an install is already downloading or ready to restart, reveals an update button below `Admin Mode` only after a newer bundle is available or ready to install, keeps all normal update status inside that button label with no second text line or subtitle underneath, uses the downloaded-state label `Restart and update`, opens a login-styled confirmation modal before restart-to-install with `Okay, restart` and `Back` actions plus copy explaining that the bundled app will quit and update in the background, fades the launcher shell to black only after the user confirms that modal, stays visually quiet when the bundled app is already current, and only replaces the button with a `Could not check updates` disclosure when the update check or download fails, rendering the update button version with a `v` prefix while still collapsing redundant updater versions such as `0.44.0` to the two-segment display form `v0.44` +- owns the firmware-backed launcher UI that links to `/` and `/admin`, labeled as Enter Space and Admin Mode, and treats Enter Space as the native workspace shell while Admin Mode is the stable control plane for recovery, admin, and rollback; when the Electron preload bridge reports a packaged desktop runtime with updater support it also runs a fresh background update check on each shell load unless an install is already downloading or ready to restart, reveals an update button below `Admin Mode` only after a newer bundle is available or ready to install, keeps all normal update status inside that button label with no second text line or subtitle underneath, uses the downloaded-state label `Restart and update`, opens a login-styled confirmation modal before restart-to-install with `Okay, restart` and `Back` actions plus copy explaining that the bundled app will quit and update in the background, fades the launcher shell to black only after the user confirms that modal, stays visually quiet when the bundled app is already current, and only replaces the button with a `Could not check updates` disclosure when the update check or download fails, rendering the update button version with a `v` prefix while still collapsing redundant updater versions such as `0.44.0` to the two-segment display form `v0.44` - declares that same shared product-level Open Graph and Twitter social-preview card so launcher-route shares use the same public Space Agent banner and description - declares the shared Space Agent transparent-helmet favicon set, including ICO fallback, PNG browser and install icons, Apple touch icon, and the `Enter Space | Space Agent` document title - runs the shared public-shell browser compatibility gate from `server/pages/res/browser-compat.js` before launcher logic starts, and renders the same blocking message contract as `/login` when the browser is missing required runtime features for the later app shell diff --git a/server/pages/enter.html b/server/pages/enter.html index 38dafd72..58f58877 100644 --- a/server/pages/enter.html +++ b/server/pages/enter.html @@ -427,6 +427,14 @@ word-break: break-word; } + .launcher-mode-note { + margin: 0.15rem 0 0; + color: var(--color-text-tertiary); + font-size: 0.84rem; + line-height: 1.45; + text-align: center; + } + .run-modal { position: fixed; inset: 0; @@ -768,6 +776,9 @@

Space Agent


           
         
+        

+ Enter Space opens the native workspace. Admin Mode opens the stable control plane. +