diff --git a/.env.example b/.env.example index 970bb9f3cf..5cc3c964c2 100644 --- a/.env.example +++ b/.env.example @@ -1648,6 +1648,16 @@ APP_LOG_TO_FILE=true # Used by: src/shared/constants/featureFlagDefinitions.ts, src/lib/arenaEloSync.ts # ARENA_ELO_SYNC_ENABLED=true +# How model ids are prefixed in GET /v1/models. "dual" (default) advertises BOTH the +# short alias prefix and the canonical provider prefix for each model (cc/claude-sonnet-4-6 +# AND claude/claude-sonnet-4-6) so client configs that hardcoded either form keep working β€” +# which roughly doubles the catalog. "alias" emits one id per model; "canonical" emits only +# the full provider-id prefix (and drops providers whose alias is already canonical). +# A client can override per request with GET /v1/models?prefix=alias instead. +# Also configurable from Dashboard > Settings > Feature Flags. +# Used by: src/shared/constants/featureFlagDefinitions.ts, src/app/api/v1/models/catalog.ts +# MODELS_CATALOG_PREFIX_MODE=dual + # Sync interval in seconds. Default: 86400 (24 hours). # ARENA_ELO_SYNC_INTERVAL=86400 diff --git a/AGENTS.md b/AGENTS.md index 7c6255a318..1ac759c0bc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -433,6 +433,7 @@ For any non-trivial change, read the matching deep-dive first: | Provider catalog (auto-generated) | `docs/reference/PROVIDER_REFERENCE.md` | | Tunnels | `docs/ops/TUNNELS_GUIDE.md` | | Electron desktop app | `docs/guides/ELECTRON_GUIDE.md` | +| VS Code Copilot Chat (OmniCopilot extension) | `docs/guides/VSCODE-COPILOT.md` | | Release flow | `docs/ops/RELEASE_CHECKLIST.md` | | Embedded services | `docs/frameworks/EMBEDDED-SERVICES.md` | | Quality gates (~80 scripts, allowlist policy) | `docs/architecture/QUALITY_GATES.md` | diff --git a/README.md b/README.md index a5ef67269e..607c411121 100644 --- a/README.md +++ b/README.md @@ -737,6 +737,8 @@ From inside the editor: open the **Extensions** view, search **"OmniRoute"**, cl β€” works the same way on both stores. Source, issues and the publishing runbook live at [diegosouzapw/OmniCopilot](https://github.com/diegosouzapw/OmniCopilot). +πŸ“– [VS Code Copilot Chat guide](docs/guides/VSCODE-COPILOT.md) β€” setup, what the picker shows, dashboard-in-a-tab, troubleshooting +
diff --git a/docs/guides/CLI-INTEGRATIONS.md b/docs/guides/CLI-INTEGRATIONS.md index 893476668e..a0eed99510 100644 --- a/docs/guides/CLI-INTEGRATIONS.md +++ b/docs/guides/CLI-INTEGRATIONS.md @@ -24,6 +24,8 @@ per-tool deep dives: - [Claude Code configuration](./CLAUDE-CODE-CONFIGURATION.md) - [Codex CLI configuration](./CODEX-CLI-CONFIGURATION.md) - [Remote Mode](./REMOTE-MODE.md) β€” drive a remote OmniRoute (VPS / Tailnet) from your laptop +- [VS Code Copilot Chat](./VSCODE-COPILOT.md) β€” the OmniCopilot extension; it can also run these + `setup-*` commands for you from inside the editor --- diff --git a/docs/guides/VSCODE-COPILOT.md b/docs/guides/VSCODE-COPILOT.md new file mode 100644 index 0000000000..ccdbcadcb0 --- /dev/null +++ b/docs/guides/VSCODE-COPILOT.md @@ -0,0 +1,138 @@ +--- +title: "VS Code Copilot Chat β€” OmniCopilot extension" +version: 3.8.50 +lastUpdated: 2026-08-18 +--- + +# VS Code Copilot Chat β€” OmniCopilot extension + +**OmniCopilot** puts every model your OmniRoute serves into the *native* GitHub Copilot Chat +model picker. No second sidebar, no separate chat UI β€” Copilot's agent mode, tool calling, +MCP servers and custom instructions all keep working, just running on the model you pick. + +| | | +| --- | --- | +| **Install (VS Code)** | [Marketplace β†’ `diegosouzapw.omnicopilot`](https://marketplace.visualstudio.com/items?itemName=diegosouzapw.omnicopilot) | +| **Install (forks)** | [Open VSX](https://open-vsx.org/extension/diegosouzapw/omnicopilot) β€” Cursor, Windsurf, VSCodium, Theia, code-server, Gitpod, Antigravity, Kiro | +| **Source / issues** | [github.com/diegosouzapw/OmniCopilot](https://github.com/diegosouzapw/OmniCopilot) (MIT) | +| **Requires** | VS Code 1.104+ | + +> **No Copilot subscription needed.** Since VS Code 1.122 a language-model provider works +> without a GitHub sign-in and without any Copilot plan. Inline completions and +> embeddings-based features stay outside the provider API and still require Copilot. + +--- + +## Setup + +1. **Run OmniRoute** β€” `npm install -g omniroute && omniroute` (dashboard on `http://localhost:20128`). +2. **Install the extension** β€” search "OmniRoute" in the Extensions view. +3. **Pick a model** β€” Copilot Chat β†’ model picker β†’ **Manage Models…** β†’ **OmniRoute**, then tick + what you want. + +Nothing to configure when OmniRoute runs on the default port. For a remote instance, open the +**OmniRoute icon in the Activity Bar** (or run `OmniRoute: Manage Connection`) and set: + +- **Server URL** β€” the server root, e.g. `http://192.168.0.15:20128`. The `/v1` suffix is + appended by the extension; do not include it. +- **API key** β€” only when the server sets `REQUIRE_API_KEY`. Stored in the OS keychain via VS + Code SecretStorage, never in `settings.json`. + +--- + +## What the picker will show + +The extension does not show the raw `GET /v1/models` payload β€” it shapes it, and the count you +see is lower than the catalog size for two deliberate reasons. + +### It asks for one id per model + +`MODELS_CATALOG_PREFIX_MODE` defaults to **`dual`**, which advertises every model twice β€” once +under the short alias prefix and once under the canonical provider prefix β€” so older client +configs keep resolving either form: + +``` +cc/claude-sonnet-4-6 ← alias prefix +claude/claude-sonnet-4-6 ← canonical prefix, same model +``` + +The extension requests **`GET /v1/models?prefix=alias`** so one id arrives per model, without +changing the server-wide setting for your other clients. On a reference instance this collapsed +**2345 entries to 1396 β€” 949 duplicates, zero models lost.** + +If you would rather fix it server-wide for *every* client, set the +`MODELS_CATALOG_PREFIX_MODE` feature flag to `alias` in the dashboard. See +[API_REFERENCE β†’ prefix](../reference/API_REFERENCE.md#model-id-prefixes-prefix) for the +query parameter and the warning about `canonical`. + +### It hides models that cannot chat + +The catalog also lists image, video, audio, rerank, embedding and moderation models. Those are +rejected on a chat request anyway: + +``` +HTTP 400 β€” Model '' is an image-generation model and cannot be used on +/v1/chat/completions. Use POST /v1/images/generations instead. +``` + +so they are filtered out by their `type` field before reaching the picker. **Responses-API +models are kept** β€” every Codex / GPT-5.x entry advertises `supported_endpoints: ["responses"]`, +and OmniRoute translates those for `/v1/chat/completions`, so they are perfectly usable. + +### Providers you never configured + +The catalog lists models from providers with an **active connection** *plus* every **noAuth** +provider β€” the keyless ones that make up much of the free tier. That is intentional. To hide +them, add them to `blockedProviders` in the dashboard settings; nothing changes in the +extension. + +--- + +## Dashboard inside a VS Code tab + +`omnicopilot.dashboardOpen: "editor"` renders the OmniRoute dashboard in an editor tab via the +Simple Browser instead of an external browser. Embedding is **opt-in on the server**: start +OmniRoute with + +```bash +DASHBOARD_ALLOW_EMBED=vscode omniroute +``` + +which serves the HTML pages with `frame-ancestors 'self' vscode-webview:` instead of the default +`frame-ancestors 'none'` + `X-Frame-Options: DENY`. The API surface (`/api`, `/v1`, `/v1beta`, +`/a2a`, `/healthz`) keeps the strict headers either way. Without the variable the page refuses to +frame and the extension falls back to the external browser β€” nothing breaks. See +[`ENVIRONMENT.md`](../reference/ENVIRONMENT.md) and issue +[#10273](https://github.com/diegosouzapw/OmniRoute/issues/10273). + +--- + +## Configuring your other tools from inside VS Code + +**`OmniRoute: Configure Coding CLI`** drives the `omniroute` CLI to write ready-to-use profiles +for Codex CLI, Claude Code, Cline, Continue, Cursor, Aider, OpenCode, Goose, Crush, Qwen Code, +Kilo and Roo β€” the same configs described in +[`CLI-INTEGRATIONS.md`](CLI-INTEGRATIONS.md). The API key is handed to the CLI through the +`OMNIROUTE_API_KEY` environment variable, never on the command line. + +--- + +## Troubleshooting + +| Symptom | Cause / fix | +| --- | --- | +| No OmniRoute models in the picker | Server unreachable. The status-bar dot goes grey; run `OmniRoute: Check Connection`. Discovery is silent by design and contributes no models rather than prompting. | +| Every model appears twice | You are on an OmniCopilot older than 1.0.1 β€” update. The extension now requests `?prefix=alias`. | +| An image/audio model used to be listed and is gone | Intentional since 1.0.1 β€” it could never answer a chat request. | +| Panel missing from the Activity Bar | VS Code moves extra view containers into the **"…"** overflow at the bottom of the Activity Bar, and a container hidden via right-click stays hidden. Right-click the Activity Bar β†’ tick **OmniRoute**, or open it with `OmniRoute: Manage Connection`. | +| Dashboard opens in the browser despite `editor` mode | The server is not started with `DASHBOARD_ALLOW_EMBED=vscode` (see above). The fallback is deliberate. | +| Models list is stale after changing providers | `OmniRoute: Refresh Models`, or the ↻ link in the panel. | + +--- + +## See also + +- [`CLI-INTEGRATIONS.md`](CLI-INTEGRATIONS.md) β€” every other coding tool +- [`REMOTE-MODE.md`](REMOTE-MODE.md) β€” driving a remote OmniRoute +- [`../reference/API_REFERENCE.md`](../reference/API_REFERENCE.md) β€” the `/v1/models` contract +- [`docs/CATALOG.md`](https://github.com/diegosouzapw/OmniCopilot/blob/main/docs/CATALOG.md) β€” the extension's own catalog notes diff --git a/docs/guides/meta.json b/docs/guides/meta.json index 7f9506b4cf..d7a3a94fdb 100644 --- a/docs/guides/meta.json +++ b/docs/guides/meta.json @@ -16,6 +16,7 @@ "CLAUDE-CODE-CONFIGURATION", "CODEX-CLI-CONFIGURATION", "CLI-INTEGRATIONS", + "VSCODE-COPILOT", "MANAGEMENT-AUTH", "REMOTE-MODE", "PWA_GUIDE", diff --git a/docs/reference/API_REFERENCE.md b/docs/reference/API_REFERENCE.md index 2d843f8ba9..c7b9b4cc87 100644 --- a/docs/reference/API_REFERENCE.md +++ b/docs/reference/API_REFERENCE.md @@ -270,6 +270,31 @@ Authorization: Bearer your-api-key β†’ Returns all chat, embedding, and image models + combos in OpenAI format ``` +### Model id prefixes (`?prefix=`) + +Most models are advertised under a **provider prefix**. Which prefix you get is controlled by +the `MODELS_CATALOG_PREFIX_MODE` feature flag, and can be overridden **per request** with a +query parameter β€” useful for a client that wants a clean list without changing the server-wide +setting for everyone else: + +```bash +GET /v1/models?prefix=alias # one id per model β€” the short alias prefix +GET /v1/models?prefix=dual # both forms (server default) +GET /v1/models?prefix=canonical # only the full provider-id prefix +``` + +| Mode | Emits | Notes | +| --- | --- | --- | +| `dual` | `cc/claude-sonnet-4-6` **and** `claude/claude-sonnet-4-6` | **Default.** Both ids route to the same model; kept so client configs that hardcoded either form keep working. Roughly doubles the catalog. | +| `alias` | `cc/claude-sonnet-4-6` | One entry per model. Providers without a distinct alias still emit their entry, so nothing is lost. | +| `canonical` | `claude/claude-sonnet-4-6` | ⚠️ The canonical row is only emitted when the canonical provider id **differs** from the alias, so providers without a distinct alias emit nothing in this mode. Prefer `alias` for a de-duplicated list. | + +A `dual`-mode mirror can also be recognised without the query parameter: it carries a `parent` +field pointing at the primary id. + +Clients that render a model picker should request `?prefix=alias` β€” this is what the +[OmniCopilot VS Code extension](../guides/VSCODE-COPILOT.md) does. + ### No-thinking model variants For thinking-capable Claude models, `/v1/models` also advertises a **no-thinking** variant whose id is prefixed with `claude-3-omniroute-no-thinking/`: diff --git a/docs/reference/ENVIRONMENT.md b/docs/reference/ENVIRONMENT.md index a47db4ed0c..5c6cb65e08 100644 --- a/docs/reference/ENVIRONMENT.md +++ b/docs/reference/ENVIRONMENT.md @@ -881,6 +881,7 @@ Automatic model pricing data synchronization from external sources. | Variable | Default | Source File | Description | | ------------------------- | ------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | | `ARENA_ELO_SYNC_ENABLED` | `true` | `src/shared/constants/featureFlagDefinitions.ts` | Periodic Arena AI leaderboard ELO sync, configurable from Dashboard Feature Flags or with `false` to opt out. | +| `MODELS_CATALOG_PREFIX_MODE` | `dual` | `src/shared/constants/featureFlagDefinitions.ts`, `src/app/api/v1/models/catalog.ts` | Prefix form used for model ids in `GET /v1/models`. `dual` advertises both the short alias prefix and the canonical provider prefix for every model (backward compatibility β€” roughly doubles the catalog); `alias` emits one id per model; `canonical` emits only the full provider-id prefix and omits providers whose alias already is the canonical id. Clients can override per request with `?prefix=alias`. See [API_REFERENCE](API_REFERENCE.md#model-id-prefixes-prefix). | | `ARENA_ELO_SYNC_INTERVAL` | `86400` (24h) | `src/lib/arenaEloSync.ts` | Sync interval in seconds. | --- diff --git a/scripts/check/check-fabricated-docs.mjs b/scripts/check/check-fabricated-docs.mjs index aba493b7d4..0a1d043032 100644 --- a/scripts/check/check-fabricated-docs.mjs +++ b/scripts/check/check-fabricated-docs.mjs @@ -114,6 +114,12 @@ const ENV_VAR_ALLOWLIST = new Set([ "LINUX_GPG_KEY", // electron AppImage signing key, CI/build only (ELECTRON_GUIDE.md) "BRANCH_LOCK_TOKEN", // release branch-protection ops token (QUALITY_GATE_PLAYBOOK.md) "NEXT_LOCALE", // next-intl locale cookie name (I18N.md) + // Feature flags are resolved by key at runtime β€” `resolveFeatureFlag()` reads + // `process.env[key]` (src/shared/utils/featureFlags.ts), never a literal + // `process.env.MODELS_CATALOG_PREFIX_MODE`, so this scan cannot see the read. + // The flag is real: defined in featureFlagDefinitions.ts, overridable from the + // dashboard or the environment. (API_REFERENCE.md, VSCODE-COPILOT.md) + "MODELS_CATALOG_PREFIX_MODE", // Telegram Mini App integration (proposal TELEGRAM-MINIAPP.md, not yet implemented): env vars named in the feasibility analysis but no code reads them yet. "TELEGRAM_WEBHOOK_URL", // proposal-only: Telegram webhook public endpoint (TELEGRAM-MINIAPP.md, future feature) "TELEGRAM_WEBHOOK_SECRET", // proposal-only: Telegram webhook HMAC secret (TELEGRAM-MINIAPP.md, future feature)