Skip to content

Commit 75b335b

Browse files
authored
Merge pull request webbrain-one#2731 from esokullu/main
Detect vision support and toggle for local model providers
2 parents f75234c + dfd9453 commit 75b335b

72 files changed

Lines changed: 1218 additions & 272 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/webbrain-cloud-smoke.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,6 @@ name: WebBrain Cloud Smoke
22

33
on:
44
workflow_dispatch:
5-
schedule:
6-
- cron: "17 5 * * *"
7-
push:
8-
branches: [main]
9-
paths:
10-
- ".github/workflows/webbrain-cloud-smoke.yml"
11-
- "ci/**"
12-
- "src/chrome/src/agent/**"
13-
- "src/chrome/src/background.js"
14-
- "src/chrome/src/offscreen/cloud-bridge.js"
15-
- "src/chrome/src/cloud-runs.js"
16-
- "src/firefox/src/agent/**"
175

186
permissions:
197
contents: read

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This changelog was generated from the repository Git history and release tags. V
88

99
### Changed
1010
- Updated the LM Studio plugin for the current browser-delegation protocol.
11+
- Added model-bound vision capability detection for llama.cpp, LM Studio, and LocalAI, with Auto / Force on / Off settings and fail-closed Chrome/Firefox request routing.
1112

1213
### Fixed
1314
- Hid empty assistant placeholders until response content is ready to render.

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ LM Studio (`:1234/v1`), Jan (`:1337/v1`), and LocalAI (`:8080/v1`) work the same
9090
way. Load a model with **at least a 16k-token context window** — 8k works only
9191
with the Compact tier, and 4k is too small for the system prompt plus tool
9292
schemas. WebBrain auto-detects the real window for llama.cpp, Ollama, and LM
93-
Studio, and auto-compacts the conversation as it fills up. For Ollama, the
94-
Vision setting defaults to Auto and reads the selected model's native
95-
`/api/show` capabilities; Force on and Off remain available as explicit
96-
overrides. There is also a
93+
Studio, and auto-compacts the conversation as it fills up. For Ollama,
94+
llama.cpp, LM Studio, and LocalAI, it also reads native server metadata before
95+
adding screenshots; Settings provides Auto, Force on, and Off overrides. When
96+
the optional Model field is blank, the loaded-model capability is rechecked on
97+
every user turn so a server-side hot swap takes effect. There is also a
9798
preview `ollama launch webbrain --model <model>` handoff. Details:
9899
[providers and models](docs/providers-and-models.md#local-providers).
99100

docs/architecture.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,6 @@ background.js handleMessage('chat_start')
160160

161161
### Step 3: Enrich First User Message
162162
```
163-
providerManager.prepareActiveProviderCapabilities()
164-
→ for Ollama Auto, resolve the model/base-URL-scoped `/api/show` check
165-
→ coalesce concurrent checks and fail closed to text-only on metadata errors
166-
167163
_enrichUserMessageWithCurrentPage(tabId, messages, userMessage)
168164
169165
1. Collect URL + title via chrome.tabs.get(tabId)
@@ -709,11 +705,13 @@ testConnection() → { ok, error, model }
709705

710706
`promptTier` drives both the action prompt and the normal tool subset. Local providers default to Mid, cloud providers are forced Full, and the legacy `useCompactPrompt` flag maps to Compact for existing configs. Dev mode is a separate conversation mode: Mid/Full Dev uses the selected Act tier plus `SYSTEM_PROMPT_DEV_APPENDIX`; Compact Dev is blocked before an LLM request is sent.
711707

712-
Ollama is the exception to OpenAI-compatible model-name vision inference. Its
713-
`visionMode` is `auto`, `on`, or `off`; Auto performs one coalesced,
714-
three-second `/api/show` metadata check per model/base URL and service-worker
715-
lifetime before turn enrichment. Only successful metadata is persisted, and a
716-
late result is applied only if the same Ollama identity is still configured.
708+
Ollama, llama.cpp, LM Studio, and LocalAI resolve `supportsVision` from native
709+
server metadata before page enrichment. Explicit model/base-URL identities are
710+
cached and protected by stale-result guards; an empty Model field is treated as
711+
the server's mutable loaded-model slot, so concurrent checks are coalesced only
712+
within that turn and the next user turn rechecks it. Detection is bounded to
713+
three seconds and fails closed without failing the text request. User overrides
714+
bypass detection. Chrome and Firefox share the same parsers and behavior.
717715

718716
See `docs/providers-and-models.md`.
719717

docs/fr/providers-and-models.md

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ class BaseLLMProvider {
3737
| ID Fournisseur | Type | Catégorie | Modèle par défaut | Vision |
3838
|---|---|---|---|---|
3939
| `webbrain_cloud` | `openai` | cloud | `webbrain-cloud 1.0` | Oui |
40-
| `llamacpp` | `llamacpp` | local | (modèle chargé) | Oui (activé par défaut) |
41-
| `ollama` | `openai` | local | (modèle chargé) | Auto via `/api/show` |
42-
| `lmstudio` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
40+
| `llamacpp` | `llamacpp` | local | (modèle chargé) | Métadonnées auto / surcharge |
41+
| `ollama` | `openai` | local | (modèle chargé) | Auto via `/api/show` / surcharge |
42+
| `lmstudio` | `openai` | local | (modèle chargé) | Métadonnées auto / surcharge |
4343
| `jan` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
4444
| `vllm` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
4545
| `sglang` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
46-
| `localai` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
46+
| `localai` | `openai` | local | (modèle chargé) | Métadonnées auto / surcharge |
4747
| `gpt4all` | `openai` | local | (modèle chargé) | Oui (activé par défaut) |
4848
| `azure_openai` | `azure_openai` | cloud | (déploiement) | Bascule manuelle |
4949
| `aws_bedrock` | `aws_bedrock` | cloud | (ID de modèle) | Non |
@@ -125,10 +125,15 @@ serveur local a été démarré avec authentification :
125125
- **SGLang** : `http://localhost:30000/v1` — le serveur compatible OpenAI de SGLang
126126
- **LocalAI** : `http://localhost:8080/v1` — le serveur compatible OpenAI de LocalAI
127127

128-
Ollama utilise par défaut `visionMode: "auto"` et vérifie le modèle sélectionné
129-
avec les métadonnées natives de `/api/show` avant de joindre des images. Les
130-
autres fournisseurs locaux conservent leur comportement explicite
131-
`supportsVision` existant.
128+
Ollama, llama.cpp, LM Studio et LocalAI utilisent `visionMode: auto` par défaut.
129+
WebBrain lit les métadonnées natives du modèle sélectionné avant l'enrichissement et
130+
n'envoie des captures que si le serveur déclare explicitement l'entrée image.
131+
Une détection indisponible ou malformée reste en texte seul pour ce tour et
132+
sera retentée plus tard. Si le champ Modèle est vide, la capacité du modèle
133+
chargé est revérifiée à chaque tour afin de suivre les changements côté serveur.
134+
Les réglages proposent Automatique, Forcer
135+
l'activation et Désactivé ; les autres fournisseurs locaux conservent leur
136+
interrupteur explicite actuel.
132137

133138
#### Relais de lancement Ollama (préversion)
134139

@@ -180,9 +185,16 @@ Le mode Ask ignore le niveau du fournisseur et reste en lecture seule. Le mode A
180185
|---|---|
181186
| Compatible OpenAI | Regex sur le nom du modèle (`gpt-4o`, `gpt-5`, `claude-3`, `claude-sonnet-4`, `gemini-2.0-flash`, etc.) |
182187
| Anthropic | Patterns `claude-(3\|sonnet-4\|opus-4)` |
183-
| llama.cpp | Interrupteur explicite `supportsVision` dans la configuration |
184-
| Ollama | Champ `capabilities` de `POST /api/show`, avec repli historique sur `projector_info` / les métadonnées `.vision.` ; réglage Auto / Forcer l'activation / Désactivé |
185-
| LM Studio / Jan / vLLM / SGLang / LocalAI | Interrupteur explicite `supportsVision` dans la configuration (via le fournisseur OpenAI) |
188+
| Ollama | `POST /api/show` `capabilities`, avec replis historiques `projector_info` / `.vision.` |
189+
| llama.cpp | `GET /props``modalities.vision`, avec Automatique / Forcer / Désactivé |
190+
| LM Studio | `GET /api/v1/models``capabilities.vision`, puis ancien `/api/v0/models` `type` |
191+
| LocalAI | `GET /v1/models/capabilities``input_modalities` / `capabilities` |
192+
| Jan / vLLM / SGLang | Interrupteur explicite `supportsVision` dans la configuration (via le fournisseur OpenAI) |
193+
194+
La détection est liée au fournisseur, au modèle exact et à l'URL de base. Les
195+
requêtes simultanées sont regroupées et une réponse tardive d'une ancienne
196+
configuration ne peut pas modifier la configuration actuelle. Un fournisseur
197+
de vision dédié conserve le routage séparé existant.
186198

187199
### Conversion Anthropic
188200

@@ -286,11 +298,4 @@ myprovider: {
286298
},
287299
```
288300

289-
La vision est normalement auto-détectée via une regex sur le nom du modèle.
290-
Ollama fait exception : son mode Auto utilise les métadonnées natives de
291-
`/api/show` et échoue de manière fermée vers le mode texte seul si elles ne
292-
peuvent pas être vérifiées. Si un autre fournisseur a un ensemble connu de
293-
modèles de vision, ajoutez-les à la regex dans `openai.js`. Définissez
294-
`supportsStreamUsageOptions: true` uniquement pour les fournisseurs qui
295-
acceptent `stream_options.include_usage` de style OpenAI ; laissez-le à false
296-
lorsqu'un fournisseur retourne l'utilisation sans accepter ce champ de requête.
301+
La vision est auto-détectée via une regex sur le nom du modèle. Si le fournisseur a un ensemble connu de modèles de vision, ajoutez-les à la regex dans `openai.js`. Définissez `supportsStreamUsageOptions: true` uniquement pour les fournisseurs qui acceptent `stream_options.include_usage` de style OpenAI ; laissez-le à false lorsqu'un fournisseur retourne l'utilisation sans accepter ce champ de requête.

docs/providers-and-models.md

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ class BaseLLMProvider {
3737
| Provider ID | Type | Category | Default Model | Vision |
3838
|---|---|---|---|---|
3939
| `webbrain_cloud` | `openai` | cloud | `webbrain-cloud 1.0` | Yes |
40-
| `llamacpp` | `llamacpp` | local | (loaded model) | Yes (default on) |
41-
| `ollama` | `openai` | local | (loaded model) | Auto via `/api/show` |
42-
| `lmstudio` | `openai` | local | (loaded model) | Yes (default on) |
40+
| `llamacpp` | `llamacpp` | local | (loaded model) | Auto metadata / override |
41+
| `ollama` | `openai` | local | (loaded model) | Auto via `/api/show` / override |
42+
| `lmstudio` | `openai` | local | (loaded model) | Auto metadata / override |
4343
| `jan` | `openai` | local | (loaded model) | Yes (default on) |
4444
| `vllm` | `openai` | local | (loaded model) | Yes (default on) |
4545
| `sglang` | `openai` | local | (loaded model) | Yes (default on) |
46-
| `localai` | `openai` | local | (loaded model) | Yes (default on) |
46+
| `localai` | `openai` | local | (loaded model) | Auto metadata / override |
4747
| `gpt4all` | `openai` | local | (loaded model) | Yes (default on) |
4848
| `azure_openai` | `azure_openai` | cloud | (deployment) | Manual toggle |
4949
| `aws_bedrock` | `aws_bedrock` | cloud | (model id) | No |
@@ -155,9 +155,15 @@ local server was started with auth:
155155
- **SGLang**: `http://localhost:30000/v1` — SGLang's OpenAI-compatible server
156156
- **LocalAI**: `http://localhost:8080/v1` — LocalAI's OpenAI-compatible server
157157

158-
Ollama defaults to `visionMode: "auto"` and verifies the selected model through
159-
its native `/api/show` metadata before attaching images. The other local
160-
providers retain their existing explicit `supportsVision` behavior.
158+
Ollama, llama.cpp, LM Studio, and LocalAI default to `visionMode: auto`. WebBrain asks
159+
the selected server for model capability metadata before enrichment and sends
160+
screenshots only when the response explicitly reports image input. A failed or
161+
malformed metadata request is text-only for that turn and is retried later;
162+
Settings can override Auto with Force on or Off. For providers whose Model
163+
field may be blank, WebBrain coalesces concurrent checks but rechecks once per
164+
user turn, so changing the model loaded by the server cannot reuse a stale
165+
answer. Other local providers retain
166+
their existing explicit `supportsVision` setting.
161167

162168
#### Ollama launch handoff (preview)
163169

@@ -218,9 +224,16 @@ Ask mode ignores provider tier and stays read-only. Act mode uses the selected t
218224
|---|---|
219225
| OpenAI-compatible | Regex against model name (`gpt-4o`, `gpt-5`, `claude-3`, `claude-sonnet-4`, `gemini-2.0-flash`, etc.) |
220226
| Anthropic | `claude-(3\|sonnet-4\|opus-4)` patterns |
221-
| llama.cpp | Explicit `supportsVision` config toggle |
222-
| Ollama | `POST /api/show` `capabilities`, with legacy projector / `.vision.` metadata fallbacks; Auto / Force on / Off setting |
223-
| LM Studio / Jan / vLLM / SGLang / LocalAI | Explicit `supportsVision` config toggle (via OpenAI provider) |
227+
| Ollama | `POST /api/show` `capabilities`, with legacy projector / `.vision.` metadata fallbacks; Auto / Force on / Off |
228+
| llama.cpp | `GET /props``modalities.vision`, with Auto / Force on / Off |
229+
| LM Studio | `GET /api/v1/models``capabilities.vision`; legacy `/api/v0/models` `type`, with overrides |
230+
| LocalAI | `GET /v1/models/capabilities``input_modalities` / `capabilities`, with overrides |
231+
| Jan / vLLM / SGLang | Explicit `supportsVision` config toggle (via OpenAI provider) |
232+
233+
Auto results are keyed by provider, exact selected model, and canonical base
234+
URL. Concurrent checks share one request, and a late response from an older
235+
configuration cannot change the current provider. A separately configured
236+
dedicated vision provider continues to use the existing split-provider path.
224237

225238
### Anthropic Conversion
226239

@@ -331,10 +344,4 @@ myprovider: {
331344
},
332345
```
333346

334-
Vision is normally auto-detected via model-name regex. Ollama is the exception:
335-
its Auto mode uses native `/api/show` metadata and fails closed to text-only
336-
when metadata cannot be verified. If another provider has a known set of vision
337-
models, add them to the regex in `openai.js`. Set
338-
`supportsStreamUsageOptions: true` only for providers that accept OpenAI-style
339-
`stream_options.include_usage`; leave it false when a provider returns usage
340-
without accepting that request field.
347+
Vision is auto-detected via model-name regex. If the provider has a known set of vision models, add them to the regex in `openai.js`. Set `supportsStreamUsageOptions: true` only for providers that accept OpenAI-style `stream_options.include_usage`; leave it false when a provider returns usage without accepting that request field.

docs/zh-CN/providers-and-models.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ class BaseLLMProvider {
3737
| 提供商 ID | 类型 | 类别 | 默认模型 | 视觉能力 |
3838
|---|---|---|---|---|
3939
| `webbrain_cloud` | `openai` | 云端 | `webbrain-cloud 1.0` ||
40-
| `llamacpp` | `llamacpp` | 本地 | (已加载模型) | 是(默认开启) |
41-
| `ollama` | `openai` | 本地 | (已加载模型) | 通过 `/api/show` 自动检测 |
42-
| `lmstudio` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
40+
| `llamacpp` | `llamacpp` | 本地 | (已加载模型) | 自动元数据 / 覆盖 |
41+
| `ollama` | `openai` | 本地 | (已加载模型) | 通过 `/api/show` 自动检测 / 覆盖 |
42+
| `lmstudio` | `openai` | 本地 | (已加载模型) | 自动元数据 / 覆盖 |
4343
| `jan` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
4444
| `vllm` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
4545
| `sglang` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
46-
| `localai` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
46+
| `localai` | `openai` | 本地 | (已加载模型) | 自动元数据 / 覆盖 |
4747
| `gpt4all` | `openai` | 本地 | (已加载模型) | 是(默认开启) |
4848
| `azure_openai` | `azure_openai` | 云端 | (部署) | 手动开关 |
4949
| `aws_bedrock` | `aws_bedrock` | 云端 | (模型 ID) ||
@@ -118,9 +118,11 @@ WebBrain 会直接记录;若服务省略用量,则记录基于字符数的
118118
- **SGLang**`http://localhost:30000/v1` — SGLang 的 OpenAI 兼容服务器
119119
- **LocalAI**`http://localhost:8080/v1` — LocalAI 的 OpenAI 兼容服务器
120120

121-
Ollama 默认使用 `visionMode: "auto"`,并在附加图片前通过原生
122-
`/api/show` 元数据验证所选模型。其他本地提供商保持现有的显式
123-
`supportsVision` 行为。
121+
Ollama、llama.cpp、LM Studio 和 LocalAI 默认使用 `visionMode: auto`。WebBrain 在
122+
页面上下文增强前读取所选模型的原生服务器元数据,只有服务器明确报告支持图像输入时才
123+
发送截图。元数据请求失败或格式错误时,本回合按纯文本处理,之后会重试。设置中
124+
可选择自动、强制开启或关闭。模型字段为空时,每个用户回合都会重新检测当前加载
125+
模型的能力,以便服务端热切换立即生效;其他本地提供商保持现有的显式开关行为。
124126

125127
#### Ollama 启动交接(预览)
126128

@@ -170,9 +172,14 @@ Ask 模式忽略提供商层级,保持只读。Act 模式使用所选层级的
170172
|---|---|
171173
| OpenAI 兼容 | 根据模型名称进行正则匹配(`gpt-4o``gpt-5``claude-3``claude-sonnet-4``gemini-2.0-flash` 等) |
172174
| Anthropic | `claude-(3\|sonnet-4\|opus-4)` 模式 |
173-
| llama.cpp | 显式 `supportsVision` 配置开关 |
174-
| Ollama | `POST /api/show``capabilities` 字段,并兼容旧版 `projector_info` / `.vision.` 元数据;提供自动 / 强制开启 / 关闭设置 |
175-
| LM Studio / Jan / vLLM / SGLang / LocalAI | 显式 `supportsVision` 配置开关(通过 OpenAI 提供商) |
175+
| Ollama | `POST /api/show``capabilities`,并兼容旧版 `projector_info` / `.vision.` 元数据 |
176+
| llama.cpp | `GET /props``modalities.vision`,支持自动 / 强制开启 / 关闭 |
177+
| LM Studio | `GET /api/v1/models``capabilities.vision`;旧版本回退到 `/api/v0/models``type` |
178+
| LocalAI | `GET /v1/models/capabilities``input_modalities` / `capabilities` |
179+
| Jan / vLLM / SGLang | 显式 `supportsVision` 配置开关(通过 OpenAI 提供商) |
180+
181+
检测结果按提供商、精确模型和规范化基础 URL 绑定。并发检测会合并为一次请求,旧
182+
配置的延迟响应不能修改当前设置。单独配置的视觉提供商继续使用现有的分流路径。
176183

177184
### Anthropic 转换
178185

@@ -269,9 +276,4 @@ myprovider: {
269276
},
270277
```
271278

272-
视觉能力通常通过模型名称正则自动检测。Ollama 是例外:其自动模式使用
273-
原生 `/api/show` 元数据;无法验证元数据时会安全地回退为纯文本。如果其他
274-
提供商有已知的视觉模型集,请将它们添加到 `openai.js` 的正则表达式中。仅对
275-
接受 OpenAI 风格 `stream_options.include_usage` 的提供商设置
276-
`supportsStreamUsageOptions: true`;当提供商在不接受该请求字段的情况下返回
277-
使用量时,请将其保持为 false。
279+
视觉能力通过模型名称正则自动检测。如果提供商有已知的视觉模型集,请将它们添加到 `openai.js` 的正则表达式中。仅对接受 OpenAI 风格 `stream_options.include_usage` 的提供商设置 `supportsStreamUsageOptions: true`;当提供商在不接受该请求字段的情况下返回使用量时,请将其保持为 false。

src/chrome/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ ollama serve
7777
# LocalAI: http://localhost:8080/v1
7878
```
7979

80+
For llama.cpp, LM Studio, and LocalAI, Vision defaults to **Auto**. WebBrain
81+
reads the selected model's server metadata before a turn and sends screenshots
82+
only when image input is reported. Settings also offers **Force on** and
83+
**Off** overrides; metadata failures remain text-only for that turn.
84+
8085
### Use it
8186

8287
Click the WebBrain icon → the side panel opens. Type a message like:

0 commit comments

Comments
 (0)