Vektor Chat — Ad-Funded AI (VS Code extension)
AI coding chat inside VS Code, paid for by sponsors instead of by you. While
the model works on a reply, a large sponsor card fills the wait, then folds
into a small sponsored line under the finished answer. No credits, no gates, no
sign-up — the ads fund the chat.
- Zero configuration. Chat works right after install: the model API key
lives on the Vektor server, never in your settings and never in this package.
- Agent mode. The model can read, search, create and edit files in your
workspace, scoped to the workspace and respectful of unsaved editor changes.
- Free models, picked per turn.
Auto routes each turn to the best free
model for the job instead of pinning one.
- Ads are optional. Turn them off with
vektor.adsEnabled; chat behaves
exactly the same.
Run it (F5)
- Open this folder in VS Code.
npm install (or bun install) once.
- Press F5 — an Extension Development Host opens.
- Command Palette → Vektor: Open AI Chat.
Model backend defaults to proxy — chat requests go to a Vektor chat
server that holds the model API key server-side, so users never configure a
key and there is nothing secret inside the extension to extract. The shipped
vektor.proxyUrl / vektor.proxyToken defaults point at the Vektor
Workers proxy (https://vektor-proxy.samton65.workers.dev), so chat works
out of the box after install with zero configuration. The only other
option in the model picker is mock, a no-key offline demo. Upstream
providers are chosen on the server (see server/), never by the client.
Run your own proxy instead (see
server/):
VEKTOR_UPSTREAM_API_KEY=<openrouter-key> node server/index.mjs
and override vektor.proxyUrl / vektor.proxyToken to point at it.
About vektor.proxyToken: it is a shared bootstrap token, not a secret.
It ships in the package on purpose so the extension works out of the box, and
the actual OpenRouter key never leaves the server. It is not a credential and
cannot spend money on its own: every model served is free-tier (:free), so
the provider's own free quota is what bounds usage, with the optional
DAILY_REQ_CAP_PER_CLIENT / DAILY_REQ_CAP_GLOBAL allowances as a circuit
breaker if you want one. Treat it as a public client identifier. If you run
your own proxy, generate your own token, set it as VEKTOR_CLIENT_TOKEN, and
ship that instead.
Free models it can route to: Auto (chosen per turn), MiniMax M3.1 Flash,
North Mini Code, Dots 3 Note, Laguna S 2.1, Nemotron 3.5 Lightning.
The ad loop
you send a message
│
▼
while the model works, the sponsor shows LARGE
at the top of the streaming reply — the wait
time is the ad slot (Freebuff-style)
│
▼
impression recorded once (deduped by impUrl)
│
▼
reply lands ──► the card folds into the small
sponsored line under the answer (clicks tracked)
- Ads on (
vektor.adsEnabled=true, default): every turn fetches a
sponsor in parallel with the model call — the big card is the wait, the
compact line stays under the finished reply. Requests are never blocked;
there is no balance and nothing to run out.
- Ads off (
vektor.adsEnabled=false): no ads are fetched or shown; chat
works exactly the same (model traffic still flows through the Vektor
proxy).
- Audit: impressions/clicks stream to the Vektor Ads output channel.
Settings
| Setting |
Default |
Meaning |
vektor.chatLocation |
sidebar |
Where the chat docks: sidebar (default) homes it in the Activity Bar (left, next to your code — the Copilot/Cline pattern); secondarySidebar homes it in the Secondary Side Bar on the right (Settings → Chat location); editor opens it as a tab splitting the editor |
vektor.agentTools |
true |
Agent mode: model can read/search the workspace and create/edit files (read_file, list_directory, search_files, find_files, write_file, edit_file, active_editor) — workspace-scoped; edits never clobber unsaved editor changes |
vektor.adsEnabled |
true |
Show sponsor ads that fund the chat (big card while generating + compact line under replies) vs no ads |
vektor.model |
proxy |
proxy (default; Vektor chat server, no user key), mock (offline demo) |
vektor.proxyUrl |
https://vektor-proxy.samton65.workers.dev |
Base URL of the Vektor chat proxy — this shipped default means chat works with zero configuration |
vektor.proxyToken |
(shared bootstrap token) |
Sent as the proxy bearer token; readable in the package by design — the server's daily allowances are the real protection |
vektor.proxyModel |
auto |
Free model sent to the proxy; auto picks one per turn (all shipped models stream; server holds the key) |
vektor.adServerUrl |
empty |
Mediation server base URL; empty = built-in mock inventory |
vektor.adServerToken |
– |
Bearer token for the ad server |
vektor.adEmbedCode |
– |
Third-party display-ad snippet to host in the idle banner instead of the built-in creative rotation |
vektor.warmKeepAlive |
true |
Send a 1-token keep-alive while idle so the endpoint doesn't cold-start |
Ad server contract (when you set adServerUrl)
The client hits one normalized contract — the same one Freebuff's server
mediates (POST /api/v1/ads, /ads/impression, /ads/click). Point it at
your own waterfall (Gravity → ZeroClick → Carbon → first-party) and the
extension switches from demo inventory to paid inventory with zero code
changes.
POST {base}/api/v1/ads body: { messages, sessionId, surface } where
messages is text-only recent conversation (never file contents).
Response: { ads: [{ adText, title, cta, url, clickUrl, impUrl }] }.
POST {base}/api/v1/ads/impression body: { impUrl, surface } (a verified
view; response body is ignored — the extension has no credit system).
POST {base}/api/v1/ads/click body: { impUrl, surface }.
Roadmap
- [ ] Real agent tool loop (
@codebuff/sdk agent runtime: terminal,
diff apply) — workspace read/search plus file creation and editing
(write_file / edit_file) already ship in the local tool loop
- [ ] Inline ads inside long responses (Freebuff pool: ≤4 unique ads per
response, cycled for later slots)
- [ ] Composer-adjacent rotating slot (60s rotation, idle pause)
- [x] Session caps to bound inference spend — now enforced server-side by
the proxy's daily allowances (
DAILY_REQ_CAP_PER_CLIENT /
DAILY_REQ_CAP_GLOBAL), so no credit system needs to live in the client
- [x] Package (
.vsix) for the VS Code Marketplace
- [ ] Publish to Open VSX and a self-hosted side-load
Privacy stance
Targeting context sent to an ad server is conversation text only — never
file contents, never repository data. Sponsors don't see your code. (Same line
Freebuff draws in its privacy policy.)