refactor(ai): rebranded openrouter identifiers and user agent to omp

- Updated user agent and openrouter titles in packages/ai from Oh-My-Pi to omp.
- Integrated getOpenRouterHeaders into image generation tool requests in packages/coding-agent.
- Updated provider documentation and test assertions to reflect the rebrand.
This commit is contained in:
can1357
2026-08-11 15:28:28 +02:00
parent 47b282ff9b
commit 8fed93632a
5 changed files with 8 additions and 10 deletions
+1 -1
View File
@@ -1303,7 +1303,7 @@ OpenRouter is a unified multi-provider routing gateway serving hundreds of third
- **Provider Order & Exclusion Preferences**: `applyOpenAIGatewayRouting` in `packages/ai/src/providers/openai-shared.ts` injects catalog `openRouterRouting` preferences (`OpenRouterRouting` interface with `only?: string[]` and `order?: string[]`) into the top-level `provider` request parameter when `compat.isOpenRouterHost` is true.
- **Anthropic `cache_control` Breakpoints**: `isOpenRouterAnthropicModel` (`packages/ai/src/providers/openai-shared.ts`) identifies models matching `provider === "openrouter"` and ID starting with `anthropic/`. On the Chat Completions wire, `applyOpenAIChatCompletionsPromptCachePolicy` (`openai-completions.ts`) attaches `cache_control: { type: "ephemeral" }` to the last non-empty text part of the latest message. On the Responses wire, `applyOpenAIResponsesPromptCachePolicy` (`openai-responses.ts`) sets `params.cache_control = cacheRetention === "long" ? { type: "ephemeral", ttl: "1h" } : { type: "ephemeral" }`.
- **Catalog Default Max-Tokens Omission**: `resolveOpenAIOutputTokenParam` in `packages/ai/src/providers/openai-shared.ts` omits default output token limits (`max_tokens`, `max_completion_tokens`, `max_output_tokens`) when `isOpenRouterHost` is true and `maxTokensExplicit` is false. This prevents OpenRouter from filtering out upstreams whose advertised output ceiling is below catalog maximums when executing `provider.order` / `only` fallbacks; explicitly specified caller `maxTokens` are retained.
- **Custom Request Headers**: `getOpenRouterHeaders` in `packages/ai/src/utils/openrouter-headers.ts` attaches `User-Agent: Oh-My-Pi/<ver>`, `HTTP-Referer: https://omp.sh/`, `X-OpenRouter-Title: Oh-My-Pi`, `X-OpenRouter-Categories: cli-agent`, `X-OpenRouter-Cache: true`, and `X-OpenRouter-Cache-TTL: 3600` to all requests for edge response caching.
- **Custom Request Headers**: `getOpenRouterHeaders` in `packages/ai/src/utils/openrouter-headers.ts` attaches `User-Agent: omp/<ver>`, `HTTP-Referer: https://omp.sh/`, `X-OpenRouter-Title: omp`, `X-OpenRouter-Categories: cli-agent`, `X-OpenRouter-Cache: true`, and `X-OpenRouter-Cache-TTL: 3600` to all requests for edge response caching.
### Auth & usage
- **Auth Key Validation via `/api/v1/auth/key`**: `loginOpenRouter` in `packages/ai/src/registry/openrouter.ts` configures API key validation using `validateApiKeyAgainstModelsEndpoint` targeted at `https://openrouter.ai/api/v1/auth/key`. Public `/api/v1/models` returns HTTP 200 for unauthenticated requests, so `/api/v1/auth/key` is used as the canonical identity check (returning 200 for valid keys, 401 otherwise). Key resolution checks `OPENROUTER_API_KEY` via `getEnvApiKey` in `packages/ai/src/stream.ts`.
+2 -2
View File
@@ -2,9 +2,9 @@ import packageJson from "../../package.json" with { type: "json" };
export function getOpenRouterHeaders(): Record<string, string> {
return {
"User-Agent": `Oh-My-Pi/${packageJson.version}`,
"User-Agent": `omp/${packageJson.version}`,
"HTTP-Referer": "https://omp.sh/",
"X-OpenRouter-Title": "Oh-My-Pi",
"X-OpenRouter-Title": "omp",
"X-OpenRouter-Categories": "cli-agent",
"X-OpenRouter-Cache": "true",
"X-OpenRouter-Cache-TTL": "3600",
+2 -4
View File
@@ -1,7 +1,7 @@
import * as os from "node:os";
import * as path from "node:path";
import { type } from "@oh-my-pi/omptype";
import { type ApiKey, type FetchImpl, getEnvApiKey, type Model, withAuth } from "@oh-my-pi/pi-ai";
import { type ApiKey, type FetchImpl, getEnvApiKey, getOpenRouterHeaders, type Model, withAuth } from "@oh-my-pi/pi-ai";
import { ProviderHttpError } from "@oh-my-pi/pi-ai/error";
import {
CODEX_BASE_URL,
@@ -1479,9 +1479,7 @@ export const imageGenTool: CustomTool<typeof imageGenSchema, ImageGenToolDetails
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${key}`,
"HTTP-Referer": "https://omp.sh/",
"X-OpenRouter-Title": "Oh-My-Pi",
"X-OpenRouter-Categories": "cli-agent",
...getOpenRouterHeaders(),
},
body: JSON.stringify(requestBody),
signal: requestSignal,
@@ -133,9 +133,9 @@ describe("optional embeddings", () => {
fetch: async request => {
requests += 1;
expect(request.headers.get("content-type")).toBe("application/json");
expect(request.headers.get("user-agent")).toBe(`Oh-My-Pi/${packageJson.version}`);
expect(request.headers.get("user-agent")).toBe(`omp/${packageJson.version}`);
expect(request.headers.get("http-referer")).toBe("https://omp.sh/");
expect(request.headers.get("x-openrouter-title")).toBe("Oh-My-Pi");
expect(request.headers.get("x-openrouter-title")).toBe("omp");
expect(request.headers.get("x-openrouter-categories")).toBe("cli-agent");
expect(request.headers.get("x-title")).toBeNull();
expect(request.headers.get("authorization")).toBeNull();
+1 -1
View File
@@ -417,7 +417,7 @@ export function makeOpenRouterRewriter(opts: OpenRouterOptions): RewriteChunk {
Authorization: `Bearer ${opts.apiKey}`,
"Content-Type": "application/json",
"HTTP-Referer": "https://omp.sh/",
"X-Title": "Oh-My-Pi",
"X-Title": "omp",
},
body,
});