Skip to content

Add duplicate provider configurations - #2801

Merged
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:feat/duplicate-provider
Aug 16, 2026
Merged

Add duplicate provider configurations#2801
esokullu merged 3 commits into
webbrain-one:mainfrom
alectimison-maker:feat/duplicate-provider

Conversation

@alectimison-maker

Copy link
Copy Markdown
Contributor

Summary

  • add a Duplicate action to provider cards so work/personal credentials or two local model configurations can coexist
  • persist one independent duplicate per configurable provider through the existing ProviderManager and config transfer schema
  • keep duplicate fields, branding, local model discovery, vision detection, selection, and removal working in Chrome and Firefox
  • show an explanatory disabled Duplicate action for managed WebBrain Cloud and the shared in-browser WebGPU runtime

Implementation

Duplicates use a stable <source>__duplicate ID and persist duplicateOf as their source definition. ProviderManager owns creation, the one-duplicate limit, storage validation, removal, and active-provider fallback. It rejects duplicate-of-duplicate, second, orphaned, type-mismatched, and forged entries, and it pins structural identity fields during ordinary config updates.

The Settings UI saves current form values before cloning, then renders the duplicate with the source provider's fields and icon. Duplicate cards can be selected, tested, independently edited, and removed. All new copy is localized across the 23 shipped locales in both builds.

Verification

  • node test/run.js — 1756 passed, 0 failed
  • npm run test:toolbar-guard — 33 passed
  • npm run test:security — 60/60 passed
  • node --check on changed runtime/UI modules
  • git diff --check
  • unpacked Google Chrome: loaded the real extension Settings page, created an OpenAI duplicate, independently saved gpt-5.6-luna while the source remained gpt-5.6-terra, verified the one-duplicate limit, removed the duplicate, and found no console/page errors

Firefox was not installed on the verification machine; its manifest, mirrored implementation, locale parity, and Node coverage were verified.

Closes #2799

@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

@alectimison-maker is attempting to deploy a commit to the esokullu's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds one independently configurable duplicate per eligible provider across Chrome and Firefox.

Changes:

  • Adds duplicate creation, validation, persistence, removal, and fallback selection.
  • Updates Settings, provider pickers, local-model and vision behavior.
  • Adds localization, documentation, and cross-browser tests.

Reviewed changes

Copilot reviewed 52 out of 57 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
test/run.js Adds duplicate-provider coverage.
docs/providers-and-models.md Documents duplicate lifecycle and persistence.
src/chrome/src/background.js Exposes duplicate actions.
src/chrome/src/providers/manager.js Implements duplicate management.
src/chrome/src/agent/transcribe.js Resolves duplicate source identity.
src/chrome/src/ui/settings.js Adds duplicate Settings controls.
src/chrome/src/ui/sidepanel.js Reuses source provider icons.
src/chrome/src/ui/locales/ar.js Adds Arabic copy.
src/chrome/src/ui/locales/bn.js Adds Bengali copy.
src/chrome/src/ui/locales/de.js Adds German copy.
src/chrome/src/ui/locales/en.js Adds English copy.
src/chrome/src/ui/locales/es.js Adds Spanish copy.
src/chrome/src/ui/locales/fa.js Adds Persian copy.
src/chrome/src/ui/locales/fr.js Adds French copy.
src/chrome/src/ui/locales/he.js Adds Hebrew copy.
src/chrome/src/ui/locales/hi.js Adds Hindi copy.
src/chrome/src/ui/locales/id.js Adds Indonesian copy.
src/chrome/src/ui/locales/ja.js Adds Japanese copy.
src/chrome/src/ui/locales/ko.js Adds Korean copy.
src/chrome/src/ui/locales/ms.js Adds Malay copy.
src/chrome/src/ui/locales/nl.js Adds Dutch copy.
src/chrome/src/ui/locales/pl.js Adds Polish copy.
src/chrome/src/ui/locales/pt.js Adds Portuguese copy.
src/chrome/src/ui/locales/ru.js Adds Russian copy.
src/chrome/src/ui/locales/th.js Adds Thai copy.
src/chrome/src/ui/locales/tl.js Adds Filipino copy.
src/chrome/src/ui/locales/tr.js Adds Turkish copy.
src/chrome/src/ui/locales/uk.js Adds Ukrainian copy.
src/chrome/src/ui/locales/vi.js Adds Vietnamese copy.
src/chrome/src/ui/locales/zh.js Adds Chinese copy.
src/firefox/src/background.js Exposes duplicate actions.
src/firefox/src/providers/manager.js Implements duplicate management.
src/firefox/src/ui/settings.js Adds duplicate Settings controls.
src/firefox/src/ui/sidepanel.js Reuses source provider icons.
src/firefox/src/ui/locales/ar.js Adds Arabic copy.
src/firefox/src/ui/locales/bn.js Adds Bengali copy.
src/firefox/src/ui/locales/de.js Adds German copy.
src/firefox/src/ui/locales/en.js Adds English copy.
src/firefox/src/ui/locales/es.js Adds Spanish copy.
src/firefox/src/ui/locales/fa.js Adds Persian copy.
src/firefox/src/ui/locales/fr.js Adds French copy.
src/firefox/src/ui/locales/he.js Adds Hebrew copy.
src/firefox/src/ui/locales/hi.js Adds Hindi copy.
src/firefox/src/ui/locales/id.js Adds Indonesian copy.
src/firefox/src/ui/locales/ja.js Adds Japanese copy.
src/firefox/src/ui/locales/ko.js Adds Korean copy.
src/firefox/src/ui/locales/ms.js Adds Malay copy.
src/firefox/src/ui/locales/nl.js Adds Dutch copy.
src/firefox/src/ui/locales/pl.js Adds Polish copy.
src/firefox/src/ui/locales/pt.js Adds Portuguese copy.
src/firefox/src/ui/locales/ru.js Adds Russian copy.
src/firefox/src/ui/locales/th.js Adds Thai copy.
src/firefox/src/ui/locales/tl.js Adds Filipino copy.
src/firefox/src/ui/locales/tr.js Adds Turkish copy.
src/firefox/src/ui/locales/uk.js Adds Ukrainian copy.
src/firefox/src/ui/locales/vi.js Adds Vietnamese copy.
src/firefox/src/ui/locales/zh.js Adds Chinese copy.
Files not reviewed (5)
  • src/chrome/src/ui/locales/bn.js: Generated file
  • src/chrome/src/ui/locales/hi.js: Generated file
  • src/chrome/src/ui/locales/ru.js: Generated file
  • src/chrome/src/ui/locales/th.js: Generated file
  • src/chrome/src/ui/locales/uk.js: Generated file
Suppressed comments (3)

src/chrome/src/ui/settings.js:3235

  • Rendering the warning for both Ollama cards duplicates the fixed ollama-warning-title DOM ID, so the duplicate note's aria-labelledby resolves ambiguously (typically to the source card). Give each warning a provider-specific title ID.
    const ollamaWarning = definitionId === 'ollama'
      ? `<aside class="provider-warning provider-ollama-warning" role="note"
                aria-labelledby="ollama-warning-title">
           <div class="provider-warning-label">${escapeHtml(t('st.providers.ollama_warning.label'))}</div>
           <strong class="provider-warning-title" id="ollama-warning-title">${escapeHtml(t('st.providers.ollama_warning.title'))}</strong>

src/firefox/src/ui/settings.js:2598

  • Rendering the warning for both Ollama cards duplicates the fixed ollama-warning-title DOM ID, so the duplicate note's aria-labelledby resolves ambiguously (typically to the source card). Give each warning a provider-specific title ID.
    src/chrome/src/ui/settings.js:3262
  • The unavailable reason exists only in a title on a disabled button. Disabled controls cannot receive keyboard focus, and title is not reliably announced by screen readers, so keyboard and assistive-technology users cannot access the promised explanation. Use a focusable aria-disabled control with a guarded click handler, or associate visible/help text with the disabled action.
            : (config.hasDuplicate
              ? `<button class="btn-secondary btn-duplicate" data-provider="${id}" disabled title="${escapeHtml(t('st.providers.duplicate_limit'))}">${escapeHtml(t('st.providers.duplicate'))}</button>`
              : `<button class="btn-secondary btn-duplicate" data-provider="${id}" disabled title="${escapeHtml(t('st.providers.duplicate_unavailable'))}">${escapeHtml(t('st.providers.duplicate'))}</button>`))}

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

if (!VISION_UI_PROVIDER_IDS.has(id)) return;
const hint = id === 'ollama'
? document.querySelector('[data-ollama-vision-status]')
const definitionId = providerDefinitionId(id);
if (!VISION_UI_PROVIDER_IDS.has(id)) return;
const hint = id === 'ollama'
? document.querySelector('[data-ollama-vision-status]')
const definitionId = providerDefinitionId(id);
activeGroup.appendChild(opt);
providerPickerLabelById.set(id, name);
appendProviderPickerOption(id, name, t('sp.providers.active'));
appendProviderPickerOption(id, name, t('sp.providers.active'), config.sourceProviderId || id);
activeGroup.appendChild(opt);
providerPickerLabelById.set(id, name);
appendProviderPickerOption(id, name, t('sp.providers.active'));
appendProviderPickerOption(id, name, t('sp.providers.active'), config.sourceProviderId || id);
Comment thread src/firefox/src/ui/settings.js Outdated
Comment on lines +2623 to +2625
: (config.hasDuplicate
? `<button class="btn-secondary btn-duplicate" data-provider="${id}" disabled title="${escapeHtml(t('st.providers.duplicate_limit'))}">${escapeHtml(t('st.providers.duplicate'))}</button>`
: `<button class="btn-secondary btn-duplicate" data-provider="${id}" disabled title="${escapeHtml(t('st.providers.duplicate_unavailable'))}">${escapeHtml(t('st.providers.duplicate'))}</button>`))}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alectimison-maker and others added 2 commits August 16, 2026 13:20
- Make ollama-warning-title IDs unique per provider card to avoid
  ambiguous aria-labelledby resolution for duplicate providers.
- Replace disabled with aria-disabled on unavailable duplicate buttons
  so keyboard and assistive-technology users can access the explanation.
- Guard duplicateProvider click handlers to skip aria-disabled buttons.
- Refresh vision detection status for all changed provider entries in
  the storage listener, including duplicates, by resolving definitionId.
- Pass config.sourceProviderId to toggledVisionProviderConfig so /vision
  correctly classifies Ollama duplicates.
@alectimison-maker

Copy link
Copy Markdown
Contributor Author

Copilot review resolved — commit 2805026d addresses all comments:

  1. Duplicate vision detections now refresh the settings card while the page is open: the storage listener iterates every changed provider entry and resolves the definition id via providerDefinitionId (so ollama__duplicate etc. refresh correctly).
  2. /vision on an Ollama duplicate classifies with config.sourceProviderId || active, so toggledVisionProviderConfig hits the ollama branch and the duplicate runtime id is what gets updated.
  3. Unavailable duplicate buttons use aria-disabled (focusable) with a guarded click handler and matching CSS, instead of a disabled button whose explanation lived only in title.
  4. ollama-warning-title ids are now per-card, so aria-labelledby resolves unambiguously when duplicates render.
    Verified: node test/run.js green.

@esokullu
esokullu merged commit d021d86 into webbrain-one:main Aug 16, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate Provider

3 participants