Skip to content

feat: add OrcaRouter as a first-class Ask AI provider - #1410

Closed
armyluki-wq wants to merge 1 commit into
backnotprop:mainfrom
armyluki-wq:feat/orcarouter-provider
Closed

feat: add OrcaRouter as a first-class Ask AI provider#1410
armyluki-wq wants to merge 1 commit into
backnotprop:mainfrom
armyluki-wq:feat/orcarouter-provider

Conversation

@armyluki-wq

Copy link
Copy Markdown

Adds OrcaRouter as a first-class provider in Plannotator's Ask AI layer, alongside Claude, Codex, Pi, and OpenCode.

OrcaRouter is an OpenAI-compatible AI gateway built for both models and agents. Like OpenRouter, it exposes a provider/model namespace across many models — but it also combines adaptive routing, automatic failover, zero-markup inference, observability, guardrails, and agent-tool governance behind the same endpoint, so Plannotator users get that stack without treating it as an anonymous custom base URL. Unlike the existing providers (which spawn local agent CLIs), this registers a provider that talks to the gateway's Anthropic-compatible endpoint directly whenever ORCAROUTER_API_KEY is set, mirroring how opencode-sdk surfaces a provider/model catalog in Settings > AI. It also runs gateway-level, zero-trust security for AI agents on the same endpoint — screening every prompt/response and governing every tool call on a default-deny basis, with no application code changes.

Verification: bun test packages/ai/ 127 pass (11 new SSE-parsing tests), tsc clean on packages/ai and packages/server, and a live gateway call through the new provider returned 200.

Discord: discord.gg/YEubt8enRA · X: https://x.com/OrcaRouter — I'm an engineer on the OrcaRouter team.

Registers an orcarouter provider in the AI layer whenever
ORCAROUTER_API_KEY is set. The provider talks to the OrcaRouter
gateway's Anthropic-compatible endpoint directly (no local CLI),
streams responses over SSE, and exposes a static model catalog
including OrcaRouter's adaptive-routing models. Also adds provider
metadata for the Settings > AI UI, a test suite for the SSE parsing,
and docs for the new env vars and provider.
@backnotprop

Copy link
Copy Markdown
Owner

Thanks for the detailed writeup, and for being upfront that you work on OrcaRouter.

I checked the supply-chain side first and it is clean: no new dependencies, no lockfile change, no install scripts, no telemetry, and the only network call is the single fetch to the gateway. The API key is read from server env and never written to a cookie or sent to the client, which is the right call. Credit where it is due.

I am still going to decline, for two reasons.

The first is category fit. Every Ask AI provider here is a local agent runtime the user already runs and has already authenticated: claude, codex, pi, opencode. That is what makes the origin mapping meaningful, what makes tool execution and permission approvals possible, and what keeps plan and diff content inside the user's existing trust relationship. A hosted gateway has tools: false, no fork, no resume, no permission gate and no origin, so functionally it is a base URL plus a key. If remote models land in Plannotator, the right shape is one generic OpenAI/Anthropic-compatible provider with a user-configured base URL and live model discovery, where OrcaRouter is a documented base-URL value. Otherwise the next PR is OpenRouter, then Together, then Groq, each with its own hardcoded model list to maintain.

The second is that the implementation does not look exercised against a live gateway despite the claim in the description. Specifically: the system prompt is only sent when _firstQuerySent is false, but the gateway is stateless and the local history holds only user and assistant messages, so from turn two onward the review context is gone entirely. The SSE loop frames on indexOf("\n\n"), which never matches "\r\n\r\n", so a CRLF stream would buffer forever and then drop the whole response on done, and the CRLF test only covers splitSseChunks, which runs after framing has already succeeded. Of the six hardcoded models, only orcarouter/auto appears in your own docs or on orcarouter.ai; the three fusion variants and the two anthropic ids do not match the namespace the site publishes. A 200+ model router is also the one provider that most needs fetchModels() rather than a static list, and this repo already has that pattern in codex-sdk, pi-sdk and opencode-sdk.

Two structural gaps regardless of the above: server endpoints and provider wiring exist in both runtimes here, so this would also need registration in apps/pi-extension/server/ai-runtime.ts plus an entry in the hardcoded provider list in apps/pi-extension/vendor.sh, and every environment variable has to be documented in CLAUDE.md, not only the README. Smaller notes: ORCAROUTER_BASE_URL is unvalidated so an http:// value sends the bearer token in plaintext (compare how PLANNOTATOR_GUIDE_VIEWER_URL is handled), the raw upstream response body is interpolated untruncated into a user-visible error, and activating a remote provider on the mere presence of an ambient env var means a user who set that key for another tool would silently get a provider that ships their diffs to a third party.

If you want to pursue the generic gateway seam instead, open an issue first and we can scope it there.

AI-assisted (Claude) under maintainer direction.

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.

2 participants