Browser extension
The pre-send advisor for ChatGPT, Claude, Gemini, Copilot and Perplexity: task and tokens, PII redaction, model hints and cost quotes - on-device by default, platform quotes and sign-in when you want them.
The OpenSmartRoute browser extension is a pre-send advisor for the chat sites people already use - ChatGPT, Claude, Gemini, Microsoft Copilot and Perplexity. While you type, a small card next to the composer shows what the request is, how many tokens it carries, whether it contains personal details or pasted secrets, which kind of model it deserves and what it would cost across the OpenSmartRoute catalogue. Everything runs on-device by default; the platform is only involved when you ask for it.
Source: platform/extension. Chrome and Edge builds share one package (Manifest V3); a Firefox build is produced by the same script.
What the card shows
| Row | Source | What you can do |
|---|---|---|
| Task, domains, tokens, complexity | On-device signals (a TypeScript port of the router's heuristics) | See what the router would infer before sending |
| Personal details found (email, phone, card, IBAN, SSN, Aadhaar, IP, API keys and tokens) | On-device patterns, the same list the platform's guard uses | Redact replaces them in the composer with <EMAIL_1>-style placeholders; the mapping stays in the page so you can restore the answer yourself |
| Model hint | The tier the request needs versus the model label the site shows in its picker | Switch to a fast model for a simple task or to a thinking model for a reasoning task |
| Tighten prompt | On-device compaction (filler, duplicated lines, whitespace) | Tighten replaces the draft and shows the tokens saved |
| Quote | On-device estimate over the cached public catalogue (GET /api/v1/models), or the platform's full quote (POST /api/v1/estimate) when the analysis policy allows | Recommended, cheapest and best-quality candidates with estimated cost; prices carry the catalogue date |
| Cross-site hint | Best-quality vendor for this task, when it is another site you have enabled | Open that site in a new tab; the extension never navigates for you |
The extension reads only the draft in the composer and the model label. It never reads or changes what the site sends, never blocks a request and never automates the site's UI beyond replacing your own text when you click Redact or Tighten.
Anywhere you write, anything you select
The extension behaves like a writing assistant and an AI sidebar at the same time:
- Field badge - a small mark sits in the bottom-right corner of the field you are typing in and shows how many things the advisor found (personal details, writing slips, a model hint, a tighter version). Its colour is the risk: grey nothing, green suggestions only, amber personal details, red secrets or financial identifiers. Click it to open or close the card. On the chat sites the card opens as you type; everywhere else the badge comes first and the card opens on demand - except when a draft carries a secret or a card number, which opens it straight away.
- Selection actions - select text on any enabled page and a small toolbar appears above it: Explain, Summarise, Rewrite, Translate, Fix grammar and Ask…. Each runs through the routed side panel with the selection attached, so the router picks the model and you see the decision under the answer. The same actions are in the right-click menu, together with Summarise this page and Open routed chat.
- Edge tab and shortcut - a slim tab on the right edge opens the side panel (right-click it to hide it on
that site);
Alt+Shift+Oopens it anywhere. The empty side panel offers Summarise this page and the quick actions for whatever is attached; an Attached chip shows what will travel with the next message and can be detached. - Assist in every text field (options, off by default) - registers the advisor for all sites (or for the sites you have granted) so mail, docs, tickets and forms get the badge too. The browser asks for access once.
Analysis policy
Chosen at onboarding and changeable in the options page.
| Level | What leaves the browser |
|---|---|
| Local only (default) | Only the public catalogue download (GET /api/v1/models, no user data). Quotes are computed on-device |
| Quote with the platform | The draft is sent to POST /api/v1/estimate - anonymously (rate limited) or with your key - after on-device redaction unless you turn that off. The platform stores no request text (activity rows carry request id and metadata only) |
Keys are kept in chrome.storage.local (not synced). Sign out from the popup or revoke the key from
the dashboard's API keys page.
Sign in
Popup -> Sign in to OpenSmartRoute. The extension starts a device sign-in
(POST /api/v1/auth/device/code), opens the approval page in a tab and polls
POST /api/v1/auth/device/token until you approve; the minted key is labelled Browser extension in
the dashboard. For a self-hosted osr serve or an existing key, paste the token on the options page
and set the API prefix to Self-hosted osr serve.
Once signed in, quotes are metered as estimate on your workspace, tenant rules apply
(set the tenant in options) and the traffic is attributed to the app browser-extension: every call carries
X-OSR-App: browser-extension, and the dashboard's Usage page breaks metered calls down by app
(GET /api/v1/usage -> by_app), so a workspace can see how much of its routed traffic came from the
extension, the CLI or its own integrations.
Routed chat in the side panel
Popup -> Open routed chat (or Continue in the side panel on the card when you are signed in). The
side panel sends your messages to POST /v1/chat/completions with model: "auto" and streams the answer;
under each answer it shows the decision - the target that answered, the confidence, the cost and latency the
platform measured, the plan and whether a fallback ran - and thumbs that post POST /api/v1/feedback, so the
workspace's learners hear how the answer went. The three sliders set the objective (osr.objective:
quality / cost / latency) for every request. From a chat site, Continue in the side panel carries the
visible turns and your draft across as history.
Metering provider API calls
Two channels, both off until you switch them on in options.
- Provider consoles and your own apps - an observe-only
webRequestlistener on the LLM API hosts (OpenAI, Azure OpenAI, Anthropic, Gemini, OpenRouter, Groq, Mistral, Together, DeepSeek, xAI, Cohere), onlocalhost/127.0.0.1and on any origin you add. It reads the request body (model, messages) and the status, estimates the completion frommax_tokens, prices the call from the catalogue and never blocks or changes anything. The browser asks for access to those hosts once. The popup shows today's calls and estimated cost per vendor. - DevTools panel (F12 -> OpenSmartRoute) - every LLM call the inspected tab makes with the exact
usagefrom the response body (OpenAI chat and Responses, Anthropic Messages, Gemini, Cohere; JSON and SSE), latency, status, the detected task and the catalogue price; a detail view with the messages and the answer; JSONL / CSV export; and Replay through OpenSmartRoute, which sends the same messages through the router and shows both answers with both costs side by side.
Share observed usage with my workspace (options, signed in) uploads call shapes - vendor, model,
token counts, site, task type, complexity - to POST /api/v1/usage/observed every few minutes. No text
field is ever sent; the platform rejects unknown fields (422). The workspace's opportunity report
(GET /api/v1/usage/opportunity) compares what those calls cost at list price with what the router's
recommended target would have cost for the same token shape.
The Opportunity page
Signed-in users read the report on /platform/dashboard/opportunity: observed calls and spend, the
router's quote for the same requests, the gap, the models with the widest gap and the target the router
would have picked, breakdowns by model, site and task, the per-call history (GET /api/v1/usage/observed,
newest first, never any text) and a CSV export. Only calls the catalogue can price count towards the gap,
so both sides describe the same requests; the page says so and never calls the number a saving. Rows are
kept for 90 days and deleted with the workspace. While nothing has been observed yet the page explains
what to install and how to switch sharing on.
Install
The product page /extension on the website is the front door: it offers the store listing for the
visitor's browser (Chrome Web Store, Microsoft Edge Add-ons) once the deployment sets
NEXT_PUBLIC_EXTENSION_CHROME_URL / NEXT_PUBLIC_EXTENSION_EDGE_URL at build time, a download when
NEXT_PUBLIC_EXTENSION_DOWNLOAD_URL points at a release zip, and otherwise the developer-mode steps below.
The page recognises an installed extension - the platform-origin content script sets
data-osr-extension="<version>" on <html> - and turns the call to action into a link to the Opportunity
page. Signed-in users on a Chromium browser without the extension see a one-time, dismissible suggestion
on the dashboard overview and the Usage page.
Managed browsers. A web page cannot install an extension by itself (browsers removed inline install in
2018); what installs it automatically for everyone in a company is the ExtensionSettings policy - Group
Policy or Intune for Edge and Chrome on Windows, Google Admin for managed Chrome profiles. The product page
renders the snippet with the store id (NEXT_PUBLIC_EXTENSION_CHROME_ID / _EDGE_ID):
{ "<extension-id>": { "installation_mode": "force_installed", "update_url": "https://clients2.google.com/service/update2/crx" } }Edge uses the same shape with https://edge.microsoft.com/extensionwebstorebase/v1/crx.
Until the store listings are published, load the unpacked build:
cd platform/extension
npm install
npm run build:chrome # dist/chrome (Chrome, Edge)
npm run build:firefox # dist/firefox
npm run pack # zips for the stores- Chrome:
chrome://extensions-> Developer mode -> Load unpacked ->platform/extension/dist/chrome. - Edge:
edge://extensions-> Developer mode -> Load unpacked -> the same folder. - Firefox:
about:debugging#/runtime/this-firefox-> Load Temporary Add-on ->dist/firefox/manifest.json.
Permissions: storage, alarms, sidePanel, webRequest (observe-only; no install warning), contextMenus,
scripting and activeTab (page summaries and the optional assist-everywhere script), the five chat sites for
the content script, and the platform origin (https://opensmartroute.ai, localhost, 127.0.0.1) for the
worker. The LLM API hosts are optional host permissions requested when you switch on Provider consoles; all
sites are requested when you switch on Assist in every text field; a self-hosted platform URL on another
origin is requested when you save it.
Test
npm run check # eslint, tsc, vitest (analysis library, card rendering, adapters)
npm run e2e # Playwright: loads the unpacked build in real Chrome and EdgeThe end-to-end suite starts a mocked platform API and serves a fixture chat page at https://chatgpt.com/
through request interception, so the real content-script match, the shadow-DOM card, redaction, the
model hint, the quote policy, the popup counters, the device sign-in and the options page are all
exercised in both browsers without touching the live sites. The same run covers the side panel (streamed
routed answer, metadata, feedback), the DevTools panel (exact usage, pricing, replay) and the observer
(a page's API call metered, uploaded as a shape), audits the card (light and dark
scheme) and every extension page with axe against WCAG 2.1 A/AA and checks that the card is fully keyboard
operable (Enter on Redact and the collapse control, Escape hides it).
Design
The card and the pages follow the brand guide: the real mark (positive artwork on light surfaces, reverse
on dark), the Quicksand wordmark with Smart in the cyan text tone, the website palette in both colour
schemes (paper, snow, mist, line, ink), hairline rules instead of shadows for emphasis, mono numerals in
the quote ledger and the three brand hues reserved for the tier badge and the pick labels. The card sits
just above the composer, right-aligned with it, collapses to a single line, folds long candidate lists
behind Show all, shows a loading row while a draft is first analysed and respects prefers-reduced-motion.
Privacy summary
- Default policy is local only; nothing about your prompt leaves the browser.
- With the quote policy, personal details are redacted on-device before the draft is sent.
- No telemetry. No remote code: the heuristics and adapters are bundled; the catalogue is data.
- Keys are stored locally, never synced, and can be revoked from the dashboard at any time.