diff --git a/README.fr.md b/README.fr.md index 84d801237..2e39783c9 100644 --- a/README.fr.md +++ b/README.fr.md @@ -102,7 +102,7 @@ compacte la conversation à mesure qu'elle se remplit. Il existe aussi un relais **API cloud** — OpenAI, Anthropic Claude, Google Gemini, Azure OpenAI, AWS Bedrock, Mistral, DeepSeek, xAI Grok, MiniMax, Kimi, Qwen, z.ai GLM, Groq, Together, Cloudflare, Nvidia NIM, Hugging Face, Fireworks, OpenRouter et -d'autres. Les Paramètres embarquent **103 cartes de fournisseurs** avec URL de +d'autres. Les Paramètres embarquent **104 cartes de fournisseurs** avec URL de base et modèle par défaut préremplis — voir le [catalogue complet](docs/fr/providers-and-models.md#catalogue-étendu-de-fournisseurs). @@ -195,7 +195,7 @@ WebBrain a le focus. | [Architecture](docs/fr/architecture.md) | Vue d'ensemble, flux d'un tour, sous-systèmes | | [Outils de l'agent](docs/fr/agent-tools.md) | Niveaux, modes et matrice complète | | [Commandes slash](docs/fr/slash-commands.md) | Toutes les commandes et options | -| [Fournisseurs et modèles](docs/fr/providers-and-models.md) | Les 103 cartes, configuration locale, niveaux | +| [Fournisseurs et modèles](docs/fr/providers-and-models.md) | Les 104 cartes, configuration locale, niveaux | | [Compétences](docs/fr/skills.md) | Compétences intégrées, import, outils de compétence | | [Modèle de sécurité](docs/fr/security-model.md) | Permissions, identifiants, frontières de confiance | | [Défense contre l'injection de prompt](docs/fr/prompt-injection-defense.md) | Couches de défense et limites connues | diff --git a/README.md b/README.md index 512e5f5d5..54212281b 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ preview `ollama launch webbrain --model ` handoff. Details: **Cloud APIs** — OpenAI, Anthropic Claude, Google Gemini, Azure OpenAI, AWS Bedrock, Mistral, DeepSeek, xAI Grok, MiniMax, Kimi, Qwen, z.ai GLM, Groq, Together, Cloudflare, Nvidia NIM, Hugging Face, Fireworks, OpenRouter, and more. -Settings ships **103 built-in provider cards** with base URLs and default models +Settings ships **104 built-in provider cards** with base URLs and default models pre-filled — see the [full catalog](docs/providers-and-models.md#extended-provider-catalog). ## Features @@ -179,7 +179,7 @@ Chrome side panel shortcuts work when the WebBrain side panel has focus. | [Architecture](docs/architecture.md) | System overview, turn flow, subsystems | | [Agent tools](docs/agent-tools.md) | Tiers, modes, and the full tool matrix | | [Slash commands](docs/slash-commands.md) | Every command and flag | -| [Providers and models](docs/providers-and-models.md) | All 103 provider cards, local setup, tiers | +| [Providers and models](docs/providers-and-models.md) | All 104 provider cards, local setup, tiers | | [Skills](docs/skills.md) | Bundled skills, importing, skill tools | | [Security model](docs/security-model.md) | Permissions, credentials, trust boundaries | | [Prompt-injection defense](docs/prompt-injection-defense.md) | Defense layers and known gaps | diff --git a/README.zh-CN.md b/README.zh-CN.md index a9b5d657e..910601e9e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -92,7 +92,7 @@ LM Studio(`:1234/v1`)、Jan(`:1337/v1`)和 LocalAI(`:8080/v1`)用法 **云端 API** —— OpenAI、Anthropic Claude、Google Gemini、Azure OpenAI、AWS Bedrock、 Mistral、DeepSeek、xAI Grok、MiniMax、Kimi、通义千问、z.ai GLM、Groq、Together、 Cloudflare、Nvidia NIM、Hugging Face、Fireworks、OpenRouter 等。设置中内置 -**103 张提供商卡片**,已预填 base URL 和默认模型 —— 参见 +**104 张提供商卡片**,已预填 base URL 和默认模型 —— 参见 [完整目录](docs/zh-CN/providers-and-models.md#扩展提供商目录)。 ## 功能特性 @@ -168,7 +168,7 @@ Chrome 侧边面板快捷键在 WebBrain 侧边面板获得焦点时生效。 | [架构](docs/zh-CN/architecture.md) | 系统概览、轮次流程、子系统 | | [智能体工具](docs/zh-CN/agent-tools.md) | 层级、模式与完整工具矩阵 | | [斜杠命令](docs/zh-CN/slash-commands.md) | 所有命令与参数 | -| [提供商与模型](docs/zh-CN/providers-and-models.md) | 全部 103 张提供商卡片、本地配置、层级 | +| [提供商与模型](docs/zh-CN/providers-and-models.md) | 全部 104 张提供商卡片、本地配置、层级 | | [技能](docs/zh-CN/skills.md) | 内置技能、导入、技能工具 | | [安全模型](docs/zh-CN/security-model.md) | 权限、凭证、信任边界 | | [提示注入防御](docs/zh-CN/prompt-injection-defense.md) | 防御层级与已知缺口 | diff --git a/docs/fr/providers-and-models.md b/docs/fr/providers-and-models.md index 3ed889724..6c7cf2d1c 100644 --- a/docs/fr/providers-and-models.md +++ b/docs/fr/providers-and-models.md @@ -44,6 +44,7 @@ class BaseLLMProvider { | `vllm` | `openai` | local | (modèle chargé) | Oui (activé par défaut) | | `sglang` | `openai` | local | (modèle chargé) | Oui (activé par défaut) | | `localai` | `openai` | local | (modèle chargé) | Oui (activé par défaut) | +| `gpt4all` | `openai` | local | (modèle chargé) | Oui (activé par défaut) | | `azure_openai` | `azure_openai` | cloud | (déploiement) | Bascule manuelle | | `aws_bedrock` | `aws_bedrock` | cloud | (ID de modèle) | Non | | `openai` | `openai` | cloud | `gpt-5.6-terra` | Regex nom de modèle | @@ -68,8 +69,8 @@ class BaseLLMProvider { WebBrain ajoute 76 cartes désactivées par défaut depuis l’instantané du catalogue OpenCode au commit -`62e4641235d7847dadc60da37cca8a023dd54fc1`. Avec les 27 cartes existantes, -les Paramètres proposent **103 fournisseurs intégrés**. La liste exacte des +`62e4641235d7847dadc60da37cca8a023dd54fc1`. Avec les 28 cartes existantes, +les Paramètres proposent **104 fournisseurs intégrés**. La liste exacte des identifiants est : `302ai`, `abacus`, `aihubmix`, `alibaba-coding-plan`, diff --git a/docs/providers-and-models.md b/docs/providers-and-models.md index 8acbb1259..3f7556963 100644 --- a/docs/providers-and-models.md +++ b/docs/providers-and-models.md @@ -44,6 +44,7 @@ class BaseLLMProvider { | `vllm` | `openai` | local | (loaded model) | Yes (default on) | | `sglang` | `openai` | local | (loaded model) | Yes (default on) | | `localai` | `openai` | local | (loaded model) | Yes (default on) | +| `gpt4all` | `openai` | local | (loaded model) | Yes (default on) | | `azure_openai` | `azure_openai` | cloud | (deployment) | Manual toggle | | `aws_bedrock` | `aws_bedrock` | cloud | (model id) | No | | `openai` | `openai` | cloud | `gpt-5.6-terra` | Model-name regex | @@ -68,8 +69,8 @@ class BaseLLMProvider { WebBrain also ships 76 disabled-by-default provider cards sourced from the OpenCode provider catalog snapshot at commit -`62e4641235d7847dadc60da37cca8a023dd54fc1`. Together with the 27 original -cards, Settings contains **103 built-in providers**. +`62e4641235d7847dadc60da37cca8a023dd54fc1`. Together with the 28 original +cards, Settings contains **104 built-in providers**. | IDs | |---| diff --git a/docs/zh-CN/providers-and-models.md b/docs/zh-CN/providers-and-models.md index 937e98409..0ac7cc09f 100644 --- a/docs/zh-CN/providers-and-models.md +++ b/docs/zh-CN/providers-and-models.md @@ -44,6 +44,7 @@ class BaseLLMProvider { | `vllm` | `openai` | 本地 | (已加载模型) | 是(默认开启) | | `sglang` | `openai` | 本地 | (已加载模型) | 是(默认开启) | | `localai` | `openai` | 本地 | (已加载模型) | 是(默认开启) | +| `gpt4all` | `openai` | 本地 | (已加载模型) | 是(默认开启) | | `azure_openai` | `azure_openai` | 云端 | (部署) | 手动开关 | | `aws_bedrock` | `aws_bedrock` | 云端 | (模型 ID) | 否 | | `openai` | `openai` | 云端 | `gpt-5.6-terra` | 模型名正则 | @@ -68,7 +69,7 @@ class BaseLLMProvider { WebBrain 从 OpenCode 提供商目录提交 `62e4641235d7847dadc60da37cca8a023dd54fc1` 的快照中新增了 76 张默认禁用的 -提供商卡片。加上原有 27 张,设置中共有 **103 个内置提供商**。完整 ID +提供商卡片。加上原有 28 张,设置中共有 **104 个内置提供商**。完整 ID 列表如下: `302ai`、`abacus`、`aihubmix`、`alibaba-coding-plan`、 diff --git a/src/chrome/icons/providers/SOURCES.md b/src/chrome/icons/providers/SOURCES.md index 7c8855c3e..80d1eb245 100644 --- a/src/chrome/icons/providers/SOURCES.md +++ b/src/chrome/icons/providers/SOURCES.md @@ -9,6 +9,7 @@ Most brand marks come from [Lobe Icons](https://github.com/lobehub/lobe-icons) | llamacpp | Jan app asset (brand mark used for llama.cpp) | | jan | Jan official app icon | | localai | LocalAI official logo (`mudler/LocalAI`) | +| gpt4all | Simple mark (not an official GPT4All brand asset) | | sglang | SGLang official `logo_square` (`sgl-project/sglang`) | | webbrain_cloud | WebBrain extension icon | | 302ai, abacus, aihubmix, alibaba-coding-plan, alibaba-coding-plan-cn, azure-cognitive-services, bailing, baseten, berget, cerebras, chutes, clarifai, cloudferro-sherlock, cohere, cortecs, deepinfra, digitalocean, dinference, drun, evroc, fastrouter, friendli, google-vertex, google-vertex-anthropic, helicone, iflowcn, inception, inference, io-net, jiekou, kilo, kimi-for-coding, kuae-cloud-coding-plan, llama, lucidquery, meganova, minimax-cn-coding-plan, minimax-coding-plan, moark, modelscope, morph, nano-gpt, nebius, nova, novita-ai, ollama-cloud, opencode, opencode-go, ovhcloud, perplexity, perplexity-agent, poe, privatemode-ai, qihang-ai, qiniu-ai, requesty, scaleway, siliconflow, siliconflow-cn, stackit, stepfun, submodel, synthetic, tencent-coding-plan, upstage, v0, venice, vercel, vivgrid, vultr, wandb, xiaomi, zai-coding-plan, zenmux, zhipuai, zhipuai-coding-plan | OpenCode provider icon set at commit `62e4641235d7847dadc60da37cca8a023dd54fc1` (MIT); DInference SVG normalized with a `viewBox` | diff --git a/src/chrome/icons/providers/gpt4all.svg b/src/chrome/icons/providers/gpt4all.svg new file mode 100644 index 000000000..2c5408798 --- /dev/null +++ b/src/chrome/icons/providers/gpt4all.svg @@ -0,0 +1,4 @@ + + + G4A + diff --git a/src/chrome/src/providers/manager.js b/src/chrome/src/providers/manager.js index b8a7bb760..dee308ef0 100644 --- a/src/chrome/src/providers/manager.js +++ b/src/chrome/src/providers/manager.js @@ -25,7 +25,7 @@ import { } from './context-windows.js'; const WEBBRAIN_CLOUD_PROVIDER_ID = 'webbrain_cloud'; -const LOCAL_MODEL_LIST_PROVIDER_IDS = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']; +const LOCAL_MODEL_LIST_PROVIDER_IDS = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']; const WEBBRAIN_CLOUD_CONTEXT_WINDOW = 1000000; const WEBBRAIN_CLOUD_LEGACY_CONTEXT_WINDOW = 256000; const WEBBRAIN_DEVICE_GUID_KEY = 'webbrainDeviceGuid'; @@ -263,6 +263,19 @@ export class ProviderManager { supportsVision: true, enabled: true, }, + gpt4all: { + type: 'openai', + category: 'local', + label: 'GPT4All (Local)', + providerName: 'gpt4all', + baseUrl: 'http://localhost:4891/v1', + model: '', + contextWindow: 16384, + apiKey: '', + supportsAskStreaming: true, + supportsVision: true, + enabled: true, + }, azure_openai: { type: 'azure_openai', category: 'cloud', @@ -632,7 +645,7 @@ export class ProviderManager { /** * Provider category for filter UI. Returns one of: - * 'local' — runs on the user's machine (llama.cpp, ollama, lmstudio, jan, vllm, sglang, localai) + * 'local' — runs on the user's machine (llama.cpp, ollama, lmstudio, jan, vllm, sglang, localai, gpt4all) * 'cloud' — first-party API endpoint (openai, anthropic, gemini, etc.) * 'router' — multi-model gateways that fan out to many backends (openrouter, cloudflare, nvidia, groq) * Reads `config.category` first; falls back to a per-id table so configs @@ -641,7 +654,7 @@ export class ProviderManager { static categoryFor(id, config) { if (config && config.category) return config.category; if (config?.type === 'llamacpp') return 'local'; - if (['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai'].includes(id)) return 'local'; + if (['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all'].includes(id)) return 'local'; if (ROUTER_PROVIDER_IDS.includes(id)) return 'router'; return 'cloud'; } diff --git a/src/chrome/src/ui/provider-icons.js b/src/chrome/src/ui/provider-icons.js index a40ac795c..e7d6c57c2 100644 --- a/src/chrome/src/ui/provider-icons.js +++ b/src/chrome/src/ui/provider-icons.js @@ -19,6 +19,7 @@ export const PROVIDER_ICON_FILES = { vllm: 'vllm.svg', sglang: 'sglang.png', localai: 'localai.png', + gpt4all: 'gpt4all.svg', azure_openai: 'azure_openai.svg', aws_bedrock: 'aws_bedrock.svg', openai: 'openai.svg', @@ -83,6 +84,7 @@ export const PROVIDER_SHORT_LABELS = { vllm: 'vLLM', sglang: 'SGLang', localai: 'LocalAI', + gpt4all: 'GPT4All', azure_openai: 'Azure OpenAI', aws_bedrock: 'AWS Bedrock', openai: 'OpenAI', diff --git a/src/chrome/src/ui/settings.js b/src/chrome/src/ui/settings.js index 9358869ab..25eec3017 100644 --- a/src/chrome/src/ui/settings.js +++ b/src/chrome/src/ui/settings.js @@ -2094,6 +2094,16 @@ function renderProviders() { PROMPT_TIER_FIELD, ], }, + gpt4all: { + fields: [ + { key: 'baseUrl', labelKey: 'st.provider.field.server_url', type: 'text', placeholder: 'http://localhost:4891/v1' }, + { key: 'apiKey', labelKey: 'st.provider.field.api_key', type: 'password', placeholder: 'optional' }, + { key: 'model', labelKey: 'st.provider.field.model', type: 'text', placeholder: 'loaded model' }, + CONTEXT_WINDOW_FIELD, + { key: 'supportsVision', labelKey: 'st.provider.field.supports_vision', type: 'checkbox' }, + PROMPT_TIER_FIELD, + ], + }, azure_openai: { fields: [ { key: 'baseUrl', labelKey: 'st.provider.field.api_base_url', type: 'text', placeholder: 'https://{resource}.openai.azure.com' }, @@ -2417,7 +2427,7 @@ function renderProviders() { `; } else { - const localModelProviders = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']; + const localModelProviders = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']; const canLoadModels = localModelProviders.includes(id) && field.key === 'model'; const listAttr = canLoadModels ? `list="models-${id}"` : ''; const datalistHTML = canLoadModels ? `` : ''; diff --git a/src/chrome/src/ui/sidepanel.js b/src/chrome/src/ui/sidepanel.js index 199368263..9b0cc91fb 100644 --- a/src/chrome/src/ui/sidepanel.js +++ b/src/chrome/src/ui/sidepanel.js @@ -204,7 +204,7 @@ const pinCoachmarkDismissed = (async function initPinCoachmark() { const localModels = document.getElementById('ob-local-models'); const localModelList = document.getElementById('ob-local-model-list'); const totalSteps = steps.length; - const LOCAL_PROVIDER_ORDER = ['jan', 'lmstudio', 'ollama', 'llamacpp', 'vllm', 'sglang', 'localai']; + const LOCAL_PROVIDER_ORDER = ['jan', 'lmstudio', 'ollama', 'llamacpp', 'vllm', 'sglang', 'localai', 'gpt4all']; let current = 0; let localScanStarted = false; let localModelChoices = []; diff --git a/src/firefox/icons/providers/SOURCES.md b/src/firefox/icons/providers/SOURCES.md index 7c8855c3e..80d1eb245 100644 --- a/src/firefox/icons/providers/SOURCES.md +++ b/src/firefox/icons/providers/SOURCES.md @@ -9,6 +9,7 @@ Most brand marks come from [Lobe Icons](https://github.com/lobehub/lobe-icons) | llamacpp | Jan app asset (brand mark used for llama.cpp) | | jan | Jan official app icon | | localai | LocalAI official logo (`mudler/LocalAI`) | +| gpt4all | Simple mark (not an official GPT4All brand asset) | | sglang | SGLang official `logo_square` (`sgl-project/sglang`) | | webbrain_cloud | WebBrain extension icon | | 302ai, abacus, aihubmix, alibaba-coding-plan, alibaba-coding-plan-cn, azure-cognitive-services, bailing, baseten, berget, cerebras, chutes, clarifai, cloudferro-sherlock, cohere, cortecs, deepinfra, digitalocean, dinference, drun, evroc, fastrouter, friendli, google-vertex, google-vertex-anthropic, helicone, iflowcn, inception, inference, io-net, jiekou, kilo, kimi-for-coding, kuae-cloud-coding-plan, llama, lucidquery, meganova, minimax-cn-coding-plan, minimax-coding-plan, moark, modelscope, morph, nano-gpt, nebius, nova, novita-ai, ollama-cloud, opencode, opencode-go, ovhcloud, perplexity, perplexity-agent, poe, privatemode-ai, qihang-ai, qiniu-ai, requesty, scaleway, siliconflow, siliconflow-cn, stackit, stepfun, submodel, synthetic, tencent-coding-plan, upstage, v0, venice, vercel, vivgrid, vultr, wandb, xiaomi, zai-coding-plan, zenmux, zhipuai, zhipuai-coding-plan | OpenCode provider icon set at commit `62e4641235d7847dadc60da37cca8a023dd54fc1` (MIT); DInference SVG normalized with a `viewBox` | diff --git a/src/firefox/icons/providers/gpt4all.svg b/src/firefox/icons/providers/gpt4all.svg new file mode 100644 index 000000000..2c5408798 --- /dev/null +++ b/src/firefox/icons/providers/gpt4all.svg @@ -0,0 +1,4 @@ + + + G4A + diff --git a/src/firefox/src/providers/manager.js b/src/firefox/src/providers/manager.js index addf4ba6a..67a5811b3 100644 --- a/src/firefox/src/providers/manager.js +++ b/src/firefox/src/providers/manager.js @@ -18,7 +18,7 @@ import { } from './context-windows.js'; const WEBBRAIN_CLOUD_PROVIDER_ID = 'webbrain_cloud'; -const LOCAL_MODEL_LIST_PROVIDER_IDS = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']; +const LOCAL_MODEL_LIST_PROVIDER_IDS = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']; const WEBBRAIN_CLOUD_CONTEXT_WINDOW = 1000000; const WEBBRAIN_CLOUD_LEGACY_CONTEXT_WINDOW = 256000; const WEBBRAIN_DEVICE_GUID_KEY = 'webbrainDeviceGuid'; @@ -250,6 +250,19 @@ export class ProviderManager { supportsVision: true, enabled: true, }, + gpt4all: { + type: 'openai', + category: 'local', + label: 'GPT4All (Local)', + providerName: 'gpt4all', + baseUrl: 'http://localhost:4891/v1', + model: '', + contextWindow: 16384, + apiKey: '', + supportsAskStreaming: true, + supportsVision: true, + enabled: true, + }, azure_openai: { type: 'azure_openai', category: 'cloud', @@ -617,7 +630,7 @@ export class ProviderManager { static categoryFor(id, config) { if (config && config.category) return config.category; if (config?.type === 'llamacpp') return 'local'; - if (['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai'].includes(id)) return 'local'; + if (['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all'].includes(id)) return 'local'; if (ROUTER_PROVIDER_IDS.includes(id)) return 'router'; return 'cloud'; } diff --git a/src/firefox/src/ui/provider-icons.js b/src/firefox/src/ui/provider-icons.js index a40ac795c..e7d6c57c2 100644 --- a/src/firefox/src/ui/provider-icons.js +++ b/src/firefox/src/ui/provider-icons.js @@ -19,6 +19,7 @@ export const PROVIDER_ICON_FILES = { vllm: 'vllm.svg', sglang: 'sglang.png', localai: 'localai.png', + gpt4all: 'gpt4all.svg', azure_openai: 'azure_openai.svg', aws_bedrock: 'aws_bedrock.svg', openai: 'openai.svg', @@ -83,6 +84,7 @@ export const PROVIDER_SHORT_LABELS = { vllm: 'vLLM', sglang: 'SGLang', localai: 'LocalAI', + gpt4all: 'GPT4All', azure_openai: 'Azure OpenAI', aws_bedrock: 'AWS Bedrock', openai: 'OpenAI', diff --git a/src/firefox/src/ui/settings.js b/src/firefox/src/ui/settings.js index b384480ab..332672ac8 100644 --- a/src/firefox/src/ui/settings.js +++ b/src/firefox/src/ui/settings.js @@ -2042,6 +2042,16 @@ function renderProviders() { PROMPT_TIER_FIELD, ], }, + gpt4all: { + fields: [ + { key: 'baseUrl', labelKey: 'st.provider.field.server_url', type: 'text', placeholder: 'http://localhost:4891/v1' }, + { key: 'apiKey', labelKey: 'st.provider.field.api_key', type: 'password', placeholder: 'optional' }, + { key: 'model', labelKey: 'st.provider.field.model', type: 'text', placeholder: 'loaded model' }, + CONTEXT_WINDOW_FIELD, + { key: 'supportsVision', labelKey: 'st.provider.field.supports_vision', type: 'checkbox' }, + PROMPT_TIER_FIELD, + ], + }, azure_openai: { fields: [ { key: 'baseUrl', labelKey: 'st.provider.field.api_base_url', type: 'text', placeholder: 'https://{resource}.openai.azure.com' }, @@ -2361,7 +2371,7 @@ function renderProviders() { `; } else { - const localModelProviders = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']; + const localModelProviders = ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']; const canLoadModels = localModelProviders.includes(id) && field.key === 'model'; const listAttr = canLoadModels ? `list="models-${id}"` : ''; const datalistHTML = canLoadModels ? `` : ''; diff --git a/src/firefox/src/ui/sidepanel.js b/src/firefox/src/ui/sidepanel.js index 4850a8270..22b48caca 100644 --- a/src/firefox/src/ui/sidepanel.js +++ b/src/firefox/src/ui/sidepanel.js @@ -82,7 +82,7 @@ if (globalThis.browser?.storage?.onChanged) { const localModels = document.getElementById('ob-local-models'); const localModelList = document.getElementById('ob-local-model-list'); const totalSteps = steps.length; - const LOCAL_PROVIDER_ORDER = ['jan', 'lmstudio', 'ollama', 'llamacpp', 'vllm', 'sglang', 'localai']; + const LOCAL_PROVIDER_ORDER = ['jan', 'lmstudio', 'ollama', 'llamacpp', 'vllm', 'sglang', 'localai', 'gpt4all']; let current = 0; let localScanStarted = false; let localModelChoices = []; diff --git a/test/run.js b/test/run.js index f5eddc014..8e297db21 100644 --- a/test/run.js +++ b/test/run.js @@ -28177,7 +28177,7 @@ console.log('\nprovider categorization'); test('categoryFor: local family', () => { for (const PM of [ProviderManagerCh, ProviderManagerFx]) { - for (const id of ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']) { + for (const id of ['llamacpp', 'ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']) { assert.equal(PM.categoryFor(id, { type: id === 'llamacpp' ? 'llamacpp' : 'openai' }), 'local'); } assert.equal(PM.categoryFor('custom_llama_cpp', { type: 'llamacpp' }), 'local'); @@ -28236,7 +28236,7 @@ test('llama.cpp provider defaults to mid prompt tier for saved configs without c test('inferContextWindow: model-aware cloud/router defaults and local 16k fallback', () => { for (const infer of [inferContextWindowCh, inferContextWindowFx]) { - for (const providerName of ['lmstudio', 'jan', 'vllm', 'sglang', 'localai']) { + for (const providerName of ['lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']) { assert.equal(infer({ category: 'local', providerName, model: 'qwen3.7-plus' }), 16384); } for (const model of ['gpt-5.6', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna']) { @@ -28928,7 +28928,7 @@ test('listProviderModels sends saved API keys for auth-enabled OpenAI-compatible try { for (const PM of [ProviderManagerCh, ProviderManagerFx]) { - for (const id of ['jan', 'vllm', 'sglang', 'localai']) { + for (const id of ['jan', 'vllm', 'sglang', 'localai', 'gpt4all']) { const mgr = new PM(); const config = { ...mgr._defaultConfigs()[id], @@ -29621,7 +29621,7 @@ test('extended provider catalog is complete, mirrored, safe, and excluded-provid ['firefox', ProviderManagerFx, 'src/firefox'], ]) { const defaults = new PM()._defaultConfigs(); - assert.equal(Object.keys(defaults).length, 103, `${label}: expected 27 original + 76 new providers`); + assert.equal(Object.keys(defaults).length, 104, `${label}: expected 28 original + 76 new providers`); for (const id of expectedIds) { const config = defaults[id]; assert.ok(config, `${label}: missing ${id}`); @@ -30415,7 +30415,7 @@ test('_defaultConfigs: new offline providers present and enabled by default', () for (const PM of [ProviderManagerCh, ProviderManagerFx]) { const mgr = new PM(); const defaults = mgr._defaultConfigs(); - for (const id of ['jan', 'vllm', 'sglang', 'localai']) { + for (const id of ['jan', 'vllm', 'sglang', 'localai', 'gpt4all']) { assert.ok(defaults[id], `${PM.name}: missing default config for ${id}`); assert.equal(defaults[id].type, 'openai', `${PM.name}: ${id} should use OpenAI-compatible provider`); assert.equal(defaults[id].category, 'local', `${PM.name}: ${id} should be local`); @@ -30756,6 +30756,7 @@ test('documented built-in providers opt into interactive Ask streaming', () => { 'vllm', 'sglang', 'localai', + 'gpt4all', 'azure_openai', 'anthropic', 'gemini', @@ -31332,6 +31333,7 @@ test('OpenAI-compatible Ask providers consume text, tool, usage, and DONE fixtur 'vllm', 'sglang', 'localai', + 'gpt4all', 'gemini', 'mistral', 'deepseek', @@ -32504,6 +32506,7 @@ test('OpenAI-compatible local streams do not request usage metadata', () => { { category: 'local', providerName: 'vllm' }, { category: 'local', providerName: 'sglang' }, { category: 'local', providerName: 'localai' }, + { category: 'local', providerName: 'gpt4all' }, { category: 'local', providerName: 'openai' }, ]) { const provider = new Provider(config); @@ -32516,7 +32519,7 @@ test('OpenAI-compatible local streams do not request usage metadata', () => { test('OpenAI-compatible local providers always use legacy request token fields', () => { for (const Provider of [OpenAIProviderCh, OpenAIProviderFx]) { - for (const providerName of ['ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai']) { + for (const providerName of ['ollama', 'lmstudio', 'jan', 'vllm', 'sglang', 'localai', 'gpt4all']) { const provider = new Provider({ category: 'local', providerName,