Skip to content
| Marketplace
Sign in
Visual Studio Code>AI>9Router & OpenAI-Compatible ChatNew to Visual Studio Code? Get it now.
9Router & OpenAI-Compatible Chat

9Router & OpenAI-Compatible Chat

Vheins

|
13 installs
| (0) | Free
Use 9Router or any OpenAI-compatible gateway as VS Code chat model + inline completions. No Copilot subscription.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

OpenAI-Compatible Chat (9Router, OmniRoute & /v1/models providers)

VS Code ≥ 1.96 License: MIT Providers: 9Router · OmniRoute · any /v1/models No telemetry BYOK

Use 9Router, OmniRoute, or any gateway that exposes the standard OpenAI-compatible GET /v1/models endpoint as your VS Code chat model — with inline completions (ghost text) — without a GitHub Copilot subscription.

Compatible with any provider implementing the OpenAI /v1 standard — 9Router, OmniRoute, OpenRouter, LM Studio, Ollama (OpenAI-compat shim), Groq, vLLM, LiteLLM, custom proxies, and more. See Supported providers for details.

The extension registers an OpenAI-compatible language model provider into VS Code's native chat UI, so your configured models appear directly in the model picker of the Chat view.

BYOK Policy: This extension stores API keys in your operating system's secret store (Windows Credential Manager / macOS Keychain / Linux Secret Service) via VS Code's SecretStorage. Keys never leave your machine. No telemetry. See Security below.

Supported providers

The extension is provider-agnostic — it speaks the public OpenAI /v1 HTTP standard, so any gateway that implements it works out of the box. The wizard ships with a few presets for the most common setups, and you can point it at any other /v1/models-compatible endpoint via the Custom option.

Provider / gateway Default base URL Auth Notes
9Router (built-in preset) http://localhost:20128/v1 Optional (loopback) Local gateway, zero-config on localhost.
OmniRoute (built-in preset) http://localhost:20128/v1 Optional (loopback) Shares the 9Router-compatible local API surface.
OpenRouter https://openrouter.ai/api/v1 API key Cloud, pay-as-you-go.
LM Studio http://localhost:1234/v1 Optional (loopback) Local model server.
Ollama (OpenAI-compat shim) http://localhost:11434/v1 Optional (loopback) Enable the OpenAI-compatible endpoint in Ollama settings.
Groq https://api.groq.com/openai/v1 API key Cloud, low-latency inference.
vLLM / LiteLLM / custom proxy your own URL Depends on upstream Anything speaking GET /v1/models + POST /v1/chat/completions.
Any other /v1/models provider Custom option in the wizard Depends on provider Just paste the base URL and (if needed) the API key.

What "compatible" means: a provider is supported if it implements the three endpoints the extension uses — GET /v1/models (model discovery), POST /v1/chat/completions (chat + streaming SSE + tool calls), and optionally POST /v1/completions (FIM inline completions). This is the de-facto OpenAI standard used by 9Router, OmniRoute, and most LLM gateways.

What it does

  • Native chat: the configured models appear in the VS Code Chat model picker, powered by the public LanguageModelChatProvider API.
  • Multi-provider support: works with 9Router, OmniRoute, and any gateway that exposes the standard GET /v1/models endpoint — including OpenRouter, LM Studio, Ollama (with OpenAI shim), Groq, vLLM, LiteLLM, and custom proxies.
  • Streaming responses: SSE text streams into the chat as they arrive.
  • Agent mode: tool calls round-trip between VS Code and your gateway (tools → OpenAI tool_calls → tool results).
  • Inline completions: ghost-text suggestions in the editor (non-streaming), using a hybrid FIM → chat-completion fallback prompt.
  • Profile wizard: a guided command to set up a profile — preset → base URL → API key → model discovery → save.
  • Model auto-discovery: models are fetched from the gateway's standard GET /v1/models — no hard-coded list, just what the gateway advertises.
  • SecretStorage: API keys are stored in the OS keychain via VS Code's SecretStorage — never in settings.json and never in logs.

Requirements

  • VS Code ≥ 1.96 (stable).
  • Node.js ≥ 18.19 (or ≥ 20) for development.
  • A gateway that exposes the standard OpenAI-compatible /v1 API, e.g.:
    • 9Router at http://localhost:20128/v1 (built-in preset, no API key needed for localhost), or
    • OmniRoute at http://localhost:20128/v1 (built-in preset, 9Router-compatible surface, no API key needed for localhost), or
    • any other OpenAI-compatible endpoint — http:// on a loopback address (LM Studio, Ollama with its OpenAI shim, custom proxies) or https:// on any host (e.g. https://openrouter.ai/api/v1, https://api.groq.com/openai/v1, or your own gateway at https://your-gateway.example.com/v1).
    • See Supported providers for the full list and configuration notes.
    • An API key for endpoints that require one.

Install

  1. Package the extension:
    npx @vscode/vsce package --no-dependencies
    
  2. Install the resulting VSIX:
    code --install-extension 9router-openai-chat-0.1.0.vsix
    
  3. Reload the window.

Quick start

  1. Open the Command Palette (Ctrl+Shift+P / ⌘⇧P) and run 9Router: Manage Profiles.
  2. Pick a preset:
    • 9Router (localhost:20128/v1) — recommended for 9Router.
    • OmniRoute (localhost:20128/v1) — recommended for OmniRoute (same local endpoint, 9Router-compatible).
    • Custom OpenAI-compatible endpoint — for any other provider implementing the standard GET /v1/models (OpenRouter, LM Studio, Ollama, Groq, vLLM, custom proxies, etc.).
  3. Enter the base URL. Accepted: http:// on loopback hosts (localhost, 127.0.0.1, ::1) or https:// on any host, with a /v1 path. The URL does not have to point at 9Router or OmniRoute — any provider exposing the OpenAI /v1 standard works.
  4. Enter your API key. It is saved to SecretStorage only (leave empty for loopback presets that don't require auth).
  5. The wizard lists models fetched from the gateway's standard GET /v1/models — pick a default model.
  6. Confirm and save. The profile (without the API key) is written to your user settings.json and set as active.
  7. Open the Chat view and select the model — it appears under the extension's vendor in the model picker, regardless of whether the underlying gateway is 9Router, OmniRoute, or any other /v1/models-compatible provider.

Alternatively, configure a profile manually in your user settings.json:

{
  "9routerOpenai.profiles": [
    {
      "id": "local-9router",
      "name": "Local 9Router",
      "baseUrl": "http://localhost:20128/v1",
    },
  ],
  "9routerOpenai.activeProfileId": "local-9router",
}

For endpoints that require a key, store it via the wizard (or via the SecretStorage key 9router-openai.<profileId>). Localhost endpoints without a stored key send no Authorization header.

Profiles & Secrets (BYOK)

  • Multiple profiles can be stored; one active profile is used at a time (9routerOpenai.activeProfileId).
  • Each profile is { id, name, baseUrl, modelOverride?, capabilitiesOverride? } and can point at any provider that exposes the standard OpenAI-compatible /v1 API — 9Router, OmniRoute, OpenRouter, LM Studio, Ollama (OpenAI shim), Groq, vLLM, LiteLLM, custom proxies, etc. (see Supported providers).
  • API keys are never written to settings.json. They live in VS Code SecretStorage (OS keychain) under 9router-openai.<profileId>.
  • Bring-your-own-key: this extension is BYOK. Corporate policies for Copilot Business/Enterprise can hide third-party language model providers from the model picker — the extension is unaffected for personal/community use.

Models

  • Models are discovered from the active profile's standard GET /v1/models and cached (TTL) per profile. Because discovery is driven by the gateway itself, the extension works with any provider that follows the OpenAI /v1/models convention — 9Router, OmniRoute, OpenRouter, LM Studio, Ollama (OpenAI shim), Groq, vLLM, custom proxies, etc. — without any per-provider code paths.
  • Use modelOverride (comma-separated ids) on a profile to restrict the picker to specific models.
  • Model names in the picker are prefixed with the endpoint alias to disambiguate.
  • Context window & capabilities now come from gateway metadata: maxInputTokens is taken from context_length and maxOutputTokens from max_completion_tokens in the /v1/models payload; toolCalling / imageInput are derived from capabilities.tools / capabilities.vision. When the gateway does not expose those fields (e.g. kr/* or internal models) the extension falls back to 262144 (256K) / 4096 / false so every model still appears in the picker. The fallback is configurable via 9routerOpenai.chat.maxInputTokens (default 262144, max 1048576 — supports 1M-context models) and 9routerOpenai.chat.maxTokens (output, default 2048, max 128000).
  • capabilitiesOverride: a per-profile override { toolCalling?, imageInput? } in 9routerOpenai.profiles lets you force-enable (or suppress) capabilities on top of the mapped metadata — e.g. to enable tool calling for a gateway that reports it incorrectly. No contract change: this field already exists in profile config.
  • Model variants (9Router gateway): choosing low / medium / high variants in the picker selects the thinking level (reasoning effort) — the picker now shows a compact detail like effort: medium · thinking: gemini-level · ctx: 1M and a hover tooltip with context window, max output and capabilities (vision/audio/search/tools/reasoning/agentic). All 274 gateway models remain listed (no filtering); variant parsing recognizes extra-low/low/medium/high/xhigh/max (effort) and thinking/agentic/thinking-agentic/agent (mode).
  • No cost/price field — the gateway does not expose pricing and the VS Code LanguageModel API has no cost field; cost is out of scope.
  • Token counting uses a character-based heuristic (≈1 token per 4 characters) — no tokenizer weights are available for arbitrary gateway models.

Inline completions

  • Enabled by default (9routerOpenai.inline.enabled).
  • Triggered after ~1.5 s of inactivity while typing, at a word boundary, in code files (excluded: markdown, plaintext, json, jsonc, log, yaml, xml, csv).
  • FIM path: if the endpoint supports the OpenAI /completions (FIM) API — probed once per model and cached — it uses a cheap prefix/suffix request.
  • Chat fallback: otherwise it uses a chat-completions prompt ("Complete the following code…"), returning only the completion.
  • Non-streaming (platform limitation of the stable inline API).

Troubleshooting

  • Model doesn't appear in the picker: confirm activeProfileId matches a profile, and that a profile is configured (wizard or settings.json). The provider returns no models when no key is stored for a key-required endpoint.
  • "Unauthorized (401): check the API key": the stored key is wrong or missing. Re-run 9Router: Manage Profiles for the profile.
  • "Network error" / chat stops: the gateway is unreachable. Check it is running and reachable at the configured base URL.
  • Inline completions don't show: check 9routerOpenai.inline.enabled, that the active profile has a stored key, and that the model id is set (9routerOpenai.chat.defaultModel). Completion only triggers at a word boundary after the debounce.
  • SSRF guard blocks a URL: http:// is only allowed for loopback hosts (localhost, 127.0.0.1, ::1); any non-loopback endpoint must use https://.

Security

  • Loopback-only SSRF guard: HTTP base URLs are restricted to loopback hosts (localhost, 127.0.0.1, ::1); anything else must use https://. This prevents server-side request forgery through the extension host.
  • API keys: SecretStorage only — never logged, never in settings.json. Logs are redacted for sk-… patterns.
  • No telemetry: the extension collects and sends nothing.
  • No remote code execution: gateway responses are inserted only as chat markdown or inline suggestions.

Development

npm install
npm run typecheck   # tsc --noEmit
npm run lint        # eslint
npm run build       # esbuild bundle → out/
npm test            # vitest unit tests
npm run package     # vsce package --no-dependencies → .vsix

Architecture and design decisions: see docs/blueprint.md.

License

MIT — see LICENSE.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft