@oh-my-pi/pi-ai 18.2.7 → 18.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/types/auth-gateway/dispatch.d.ts +80 -0
  3. package/dist/types/auth-gateway/http.d.ts +5 -6
  4. package/dist/types/auth-gateway/index.d.ts +1 -0
  5. package/dist/types/auth-gateway/routes/embeddings.d.ts +3 -0
  6. package/dist/types/auth-gateway/routes/images.d.ts +3 -0
  7. package/dist/types/auth-gateway/routes/rerank.d.ts +3 -0
  8. package/dist/types/auth-gateway/routes/speech.d.ts +2 -0
  9. package/dist/types/auth-gateway/routes/systemone.d.ts +2 -0
  10. package/dist/types/auth-gateway/routes/transcriptions.d.ts +3 -0
  11. package/dist/types/auth-gateway/routes/video.d.ts +7 -0
  12. package/dist/types/auth-gateway/server.d.ts +10 -16
  13. package/dist/types/embeddings/index.d.ts +7 -0
  14. package/dist/types/embeddings/openai-embeddings.d.ts +15 -0
  15. package/dist/types/embeddings/types.d.ts +15 -0
  16. package/dist/types/images/google-antigravity.d.ts +9 -0
  17. package/dist/types/images/google-generative-ai.d.ts +3 -0
  18. package/dist/types/images/index.d.ts +14 -0
  19. package/dist/types/images/openai-hosted.d.ts +3 -0
  20. package/dist/types/images/openai-images.d.ts +5 -0
  21. package/dist/types/images/openrouter-images.d.ts +3 -0
  22. package/dist/types/images/shared.d.ts +34 -0
  23. package/dist/types/images/types.d.ts +31 -0
  24. package/dist/types/index.d.ts +7 -1
  25. package/dist/types/judgment/typesafe.d.ts +2 -0
  26. package/dist/types/providers/embeddings-server.d.ts +32 -0
  27. package/dist/types/providers/images-server.d.ts +22 -0
  28. package/dist/types/providers/rerank-server.d.ts +35 -0
  29. package/dist/types/providers/speech-server.d.ts +8 -0
  30. package/dist/types/providers/systemone-server.d.ts +26 -0
  31. package/dist/types/providers/transcriptions-server.d.ts +32 -0
  32. package/dist/types/providers/video-server.d.ts +39 -0
  33. package/dist/types/rerank/index.d.ts +7 -0
  34. package/dist/types/rerank/openrouter-rerank.d.ts +15 -0
  35. package/dist/types/rerank/types.d.ts +17 -0
  36. package/dist/types/speech/index.d.ts +13 -0
  37. package/dist/types/speech/openai-speech.d.ts +3 -0
  38. package/dist/types/speech/transport.d.ts +7 -0
  39. package/dist/types/speech/types.d.ts +24 -0
  40. package/dist/types/speech/xai-tts.d.ts +7 -0
  41. package/dist/types/transcription/index.d.ts +7 -0
  42. package/dist/types/transcription/openai-transcriptions.d.ts +15 -0
  43. package/dist/types/transcription/types.d.ts +41 -0
  44. package/dist/types/video/index.d.ts +11 -0
  45. package/dist/types/video/openrouter-video.d.ts +19 -0
  46. package/dist/types/video/types.d.ts +62 -0
  47. package/package.json +30 -6
  48. package/src/auth-gateway/dispatch.ts +273 -0
  49. package/src/auth-gateway/http.ts +6 -7
  50. package/src/auth-gateway/index.ts +1 -0
  51. package/src/auth-gateway/routes/embeddings.ts +98 -0
  52. package/src/auth-gateway/routes/images.ts +131 -0
  53. package/src/auth-gateway/routes/rerank.ts +87 -0
  54. package/src/auth-gateway/routes/speech.ts +101 -0
  55. package/src/auth-gateway/routes/systemone.ts +116 -0
  56. package/src/auth-gateway/routes/transcriptions.ts +98 -0
  57. package/src/auth-gateway/routes/video.ts +243 -0
  58. package/src/auth-gateway/server.ts +123 -260
  59. package/src/embeddings/index.ts +17 -0
  60. package/src/embeddings/openai-embeddings.ts +141 -0
  61. package/src/embeddings/types.ts +14 -0
  62. package/src/error/rate-limit.ts +1 -1
  63. package/src/images/google-antigravity.ts +180 -0
  64. package/src/images/google-generative-ai.ts +92 -0
  65. package/src/images/index.ts +59 -0
  66. package/src/images/openai-hosted.ts +185 -0
  67. package/src/images/openai-images.ts +110 -0
  68. package/src/images/openrouter-images.ts +33 -0
  69. package/src/images/shared.ts +193 -0
  70. package/src/images/types.ts +36 -0
  71. package/src/index.ts +7 -1
  72. package/src/judgment/typesafe.ts +5 -0
  73. package/src/providers/embeddings-server.ts +151 -0
  74. package/src/providers/images-server.ts +159 -0
  75. package/src/providers/rerank-server.ts +166 -0
  76. package/src/providers/speech-server.ts +53 -0
  77. package/src/providers/systemone-server.ts +73 -0
  78. package/src/providers/transcriptions-server.ts +243 -0
  79. package/src/providers/video-server.ts +286 -0
  80. package/src/rerank/index.ts +13 -0
  81. package/src/rerank/openrouter-rerank.ts +136 -0
  82. package/src/rerank/types.ts +20 -0
  83. package/src/speech/index.ts +35 -0
  84. package/src/speech/openai-speech.ts +26 -0
  85. package/src/speech/transport.ts +66 -0
  86. package/src/speech/types.ts +37 -0
  87. package/src/speech/xai-tts.ts +41 -0
  88. package/src/transcription/index.ts +17 -0
  89. package/src/transcription/openai-transcriptions.ts +133 -0
  90. package/src/transcription/types.ts +46 -0
  91. package/src/video/index.ts +34 -0
  92. package/src/video/openrouter-video.ts +210 -0
  93. package/src/video/types.ts +72 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [18.2.8] - 2026-09-21
6
+
7
+ ### Added
8
+
9
+ - Added support for text embeddings, document reranking, video generation, image generation across multiple providers, audio speech synthesis, and audio transcription services.
10
+ - Added support for the System One judgment API, including configurable request headers for proxy routing and custom authentication.
11
+
12
+ ### Changed
13
+
14
+ - Updated API response cost reporting to use aggregate usage totals.
15
+ - Model list responses now optionally include a model kind.
16
+
17
+ ### Fixed
18
+
19
+ - Fixed detection of Claude usage-limit errors.
20
+
5
21
  ## [18.2.7] - 2026-09-21
6
22
 
7
23
  ### Breaking Changes
@@ -0,0 +1,80 @@
1
+ import type { ApiKeyResolver } from "../auth-retry.js";
2
+ import type { AuthStorage } from "../auth-storage.js";
3
+ import { type GatewayErrorClassification } from "../error/gateway.js";
4
+ import type { Api, FetchImpl, Model, Usage } from "../types.js";
5
+ import type { ClientUsageIdentity } from "../usage.js";
6
+ import type { AuthGatewayServerOptions } from "./types.js";
7
+ export type ModelResolver = (modelId: string) => Model<Api> | undefined;
8
+ export interface AuthGatewayBootOptions extends AuthGatewayServerOptions {
9
+ /** Source of credentials. Caller wires this to a broker-backed AuthStorage. */
10
+ storage: AuthStorage;
11
+ /**
12
+ * Resolve a client-requested model id to a pi-ai Model. Caller supplies
13
+ * this from a ModelRegistry (lives in `coding-agent` to avoid an inverse
14
+ * dependency in `pi-ai`).
15
+ */
16
+ resolveModel: ModelResolver;
17
+ /** Optional supplier for `/v1/models` listing. Returns the full model array. */
18
+ listModels?: () => Iterable<Model<Api>>;
19
+ /** Upstream transport for every provider call; defaults to global `fetch`. Test seam. */
20
+ fetch?: FetchImpl;
21
+ }
22
+ /**
23
+ * The client's own session key, or `undefined` when it sent none. A blank key
24
+ * counts as none: honouring it would collapse every caller that sends an empty
25
+ * key into one shared credential-sticky, prefix-cache and provider-session
26
+ * bucket.
27
+ */
28
+ export declare function normalizeClientSessionKey(clientKey: string | undefined): string | undefined;
29
+ /**
30
+ * Stable identity of the account a request's credential belongs to.
31
+ *
32
+ * `markUsageLimitReached` and the auth-retry resolver switch a session to a
33
+ * sibling credential, so the provider state retained for that session can
34
+ * outlive the account that taught it. OAuth rows expose an account id / email
35
+ * that survives token refresh — fingerprinting the bearer instead would look
36
+ * like a rotation every time a token refreshes and discard the retained
37
+ * lessons for nothing. Key-based rows fall back to a hash of the key, never
38
+ * the key itself: this value is held for the lifetime of the entry.
39
+ */
40
+ export declare function resolveGatewayAccount(storage: AuthStorage, provider: string, sessionId: string, apiKey: string): string;
41
+ /**
42
+ * Resolve the credential for one request from broker-backed storage.
43
+ *
44
+ * pi-ai clients never consult `AuthStorage`; the gateway resolves the bearer
45
+ * (an OAuth access token refreshed through the broker when needed) and hands
46
+ * it to the client. Returns the key, or the error classification the route
47
+ * should encode in its own envelope: storage failures map through
48
+ * {@link classifyGatewayError}, a provider without any credential is a 401.
49
+ */
50
+ export declare function resolveGatewayApiKey(storage: AuthStorage, model: Model<Api>, sessionId: string, signal: AbortSignal, peer: string): Promise<string | GatewayErrorClassification>;
51
+ /**
52
+ * Build the {@link ApiKeyResolver} handed to a pi-ai client for a gateway
53
+ * request. Drives the central a/b/c auth-retry policy server-side:
54
+ *
55
+ * - initial resolve → the credential already resolved for this request.
56
+ * - step (b) `!lastChance` → force-refresh the SAME session-sticky credential
57
+ * (a peer/broker may have rotated its token out from under our cached copy).
58
+ * - step (c) `lastChance` → {@link refreshGatewayApiKeyAfterAuthError} switches
59
+ * to a sibling (usage-limit block vs credential invalidation by error class).
60
+ *
61
+ * `lastKey` tracks the most recent bearer so the switch step invalidates the
62
+ * credential that actually failed. `onResolvedKey` observes every rotation;
63
+ * routes that retain provider session state use it to re-key the account
64
+ * lease, one-shot routes pass `undefined`.
65
+ */
66
+ export declare function buildGatewayApiKeyResolver(storage: AuthStorage, model: Model<Api>, sessionId: string, initialKey: string, requestSignal: AbortSignal, format: string, peer: string, onResolvedKey?: (apiKey: string) => void): ApiKeyResolver;
67
+ /**
68
+ * Attribute one settled upstream request to the originating client via the
69
+ * broker's observed-usage channel (`AuthStorage.recordObservedUsage`, batched
70
+ * by the remote store). Error/aborted turns still record — the provider
71
+ * billed whatever tokens the partial turn consumed; zero-usage results
72
+ * (pre-flight failures) are skipped. `at` defaults to now.
73
+ */
74
+ export declare function recordGatewayUsage(storage: AuthStorage, model: Model<Api>, client: ClientUsageIdentity, usage: Usage, at?: number): void;
75
+ /**
76
+ * An `AbortController` that follows the inbound request's abort signal. Routes
77
+ * abort it themselves when the response body is cancelled mid-stream, which
78
+ * `req.signal` alone does not observe.
79
+ */
80
+ export declare function mirrorRequestAbort(req: Request): AbortController;
@@ -1,4 +1,4 @@
1
- import type { Api, AssistantMessage, Model } from "../types.js";
1
+ import type { Api, Model } from "../types.js";
2
2
  import type { ClientUsageIdentity } from "../usage.js";
3
3
  export declare function json(status: number, body: unknown, headers?: Record<string, string>): Response;
4
4
  /**
@@ -7,14 +7,13 @@ export declare function json(status: number, body: unknown, headers?: Record<str
7
7
  * `request-id` (surfaced as `_request_id` by the OpenAI and Anthropic SDKs,
8
8
  * matches the gateway log line), LiteLLM's model-resolution and cost headers,
9
9
  * and OpenAI's `openai-processing-ms`. Model/request-id headers are always
10
- * present; `message` — the final assistant message, available only on
11
- * non-streaming responses — adds the computed cost, and `startedAt` the wall
12
- * time. Streaming responses send headers before usage exists, so they carry
13
- * only the identity headers.
10
+ * present; `costUsd` — known only once a non-streaming response has settled —
11
+ * adds the computed cost, and `startedAt` the wall time. Streaming responses
12
+ * send headers before usage exists, so they carry only the identity headers.
14
13
  */
15
14
  export declare function gatewayResponseHeaders(model: Model<Api>, info: {
16
15
  requestId: string;
17
- message?: AssistantMessage;
16
+ costUsd?: number;
18
17
  startedAt?: number;
19
18
  }): Record<string, string>;
20
19
  export declare function resolvePeer(req: Request): string;
@@ -1,3 +1,4 @@
1
+ export * from "./dispatch.js";
1
2
  export * from "./http.js";
2
3
  export * from "./session-state.js";
3
4
  export * from "./server.js";
@@ -0,0 +1,3 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ /** OpenAI-compatible `POST /v1/embeddings` gateway handler. */
3
+ export declare function handleEmbeddings(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,3 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ export declare function handleImageGenerations(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
3
+ export declare function handleImageEdits(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,3 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ /** OpenRouter-compatible `POST /v1/rerank` gateway handler. */
3
+ export declare function handleRerank(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ export declare function handleSpeech(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,2 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ export declare function handleSystemOne(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,3 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ /** OpenAI-compatible `POST /v1/audio/transcriptions` gateway handler. */
3
+ export declare function handleTranscriptions(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
@@ -0,0 +1,7 @@
1
+ import { type AuthGatewayBootOptions } from "../dispatch.js";
2
+ /** OpenRouter-compatible `POST /v1/videos` asynchronous video submit handler. */
3
+ export declare function handleVideoSubmit(bootOpts: AuthGatewayBootOptions, req: Request, peer: string): Promise<Response>;
4
+ /** OpenRouter-compatible `GET /v1/videos/:id` asynchronous video poll handler. */
5
+ export declare function handleVideoPoll(bootOpts: AuthGatewayBootOptions, req: Request, peer: string, gatewayId: string): Promise<Response>;
6
+ /** OpenRouter-compatible `GET /v1/videos/:id/content` streaming video content handler. */
7
+ export declare function handleVideoContent(bootOpts: AuthGatewayBootOptions, req: Request, peer: string, gatewayId: string): Promise<Response>;
@@ -16,21 +16,15 @@
16
16
  * POST /v1/chat/completions → OpenAI chat-completions in/out
17
17
  * POST /v1/messages → Anthropic messages in/out
18
18
  * POST /v1/responses → OpenAI Responses in/out
19
+ * POST /v1/pi/stream → native pi-ai stream in/out
20
+ * POST /v1/systemone | /alpha/decisions → TypeSafe System One judgments (routes/systemone)
21
+ * POST /v1/images[/generations|/edits] → image generation, OpenAI/OpenRouter wire (routes/images)
22
+ * POST /v1/audio/speech → text-to-speech, raw audio out (routes/speech)
23
+ * POST /v1/audio/transcriptions → speech-to-text, multipart or JSON base64 in (routes/transcriptions)
24
+ *
25
+ * Chat routes live in this file; every other modality is a `routes/*` module
26
+ * built on the shared plumbing in `dispatch.ts`.
19
27
  */
20
- import type { AuthStorage } from "../auth-storage.js";
21
- import type { Api, Model } from "../types.js";
22
- import type { AuthGatewayServerHandle, AuthGatewayServerOptions } from "./types.js";
23
- export type ModelResolver = (modelId: string) => Model<Api> | undefined;
24
- export interface AuthGatewayBootOptions extends AuthGatewayServerOptions {
25
- /** Source of credentials. Caller wires this to a broker-backed AuthStorage. */
26
- storage: AuthStorage;
27
- /**
28
- * Resolve a client-requested model id to a pi-ai Model. Caller supplies
29
- * this from a ModelRegistry (lives in `coding-agent` to avoid an inverse
30
- * dependency in `pi-ai`).
31
- */
32
- resolveModel: ModelResolver;
33
- /** Optional supplier for `/v1/models` listing. Returns the full model array. */
34
- listModels?: () => Iterable<Model<Api>>;
35
- }
28
+ import { type AuthGatewayBootOptions } from "./dispatch.js";
29
+ import type { AuthGatewayServerHandle } from "./types.js";
36
30
  export declare function startAuthGateway(opts: AuthGatewayBootOptions): AuthGatewayServerHandle;
@@ -0,0 +1,7 @@
1
+ import type { Api, Model } from "@oh-my-pi/pi-catalog/types";
2
+ import { type EmbeddingOptions } from "./openai-embeddings.js";
3
+ import type { EmbeddingRequest, EmbeddingResult } from "./types.js";
4
+ export * from "./openai-embeddings.js";
5
+ export * from "./types.js";
6
+ /** Dispatch an embedding request through the transport selected by the catalog model. */
7
+ export declare function embed(model: Model<Api>, request: EmbeddingRequest, options: EmbeddingOptions): Promise<EmbeddingResult>;
@@ -0,0 +1,15 @@
1
+ import type { Api, FetchImpl, Model } from "@oh-my-pi/pi-catalog/types";
2
+ import { type ApiKey } from "../auth-retry.js";
3
+ import * as AIError from "../error/index.js";
4
+ import type { EmbeddingRequest, EmbeddingResult } from "./types.js";
5
+ export interface EmbeddingOptions {
6
+ apiKey: ApiKey;
7
+ fetch?: FetchImpl;
8
+ signal?: AbortSignal;
9
+ }
10
+ /** Non-2xx response from an OpenAI-compatible embeddings endpoint. */
11
+ export declare class EmbeddingApiError extends AIError.ProviderHttpError {
12
+ readonly name = "EmbeddingApiError";
13
+ }
14
+ /** Call an OpenAI/OpenRouter-compatible embeddings endpoint. */
15
+ export declare function embedOpenAI(model: Model<Api>, request: EmbeddingRequest, options: EmbeddingOptions): Promise<EmbeddingResult>;
@@ -0,0 +1,15 @@
1
+ import type { Usage } from "@oh-my-pi/pi-catalog/types";
2
+ export interface EmbeddingRequest {
3
+ input: string | string[] | number[] | number[][];
4
+ dimensions?: number;
5
+ encodingFormat: "float" | "base64";
6
+ user?: string;
7
+ }
8
+ export interface EmbeddingResult {
9
+ embeddings: Array<{
10
+ index: number;
11
+ embedding: number[] | string;
12
+ }>;
13
+ model: string;
14
+ usage: Usage;
15
+ }
@@ -0,0 +1,9 @@
1
+ import type { Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ interface AntigravityCredentials {
4
+ accessToken: string;
5
+ projectId: string;
6
+ }
7
+ export declare function parseAntigravityCredentials(raw: string): AntigravityCredentials | undefined;
8
+ export declare function generateAntigravityImage(model: Model, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
9
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ export declare function generateGoogleImage(model: Model, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
@@ -0,0 +1,14 @@
1
+ import type { Api, Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ export * from "./google-antigravity.js";
4
+ export * from "./google-generative-ai.js";
5
+ export * from "./openai-hosted.js";
6
+ export * from "./openai-images.js";
7
+ export * from "./openrouter-images.js";
8
+ export * from "./types.js";
9
+ /** Catalog APIs {@link generateImage} serves; the hosted Responses pair needs an explicit carrier model. */
10
+ export type ImageGenerationApi = "openai-images" | "openrouter-images" | "google-generative-ai" | "google-gemini-cli" | "openai-responses" | "openai-codex-responses";
11
+ /** Whether a catalog API generates images through one of the pi-ai image clients. */
12
+ export declare function isImageGenerationApi(api: Api): api is ImageGenerationApi;
13
+ /** Generate (or edit, when `request.inputImages` is set) images through the transport selected by the model's `api`. */
14
+ export declare function generateImage(model: Model<Api>, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
@@ -0,0 +1,3 @@
1
+ import type { Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ export declare function generateHostedImage(model: Model, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
@@ -0,0 +1,5 @@
1
+ import type { Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ export declare const XAI_MAX_EDIT_IMAGES = 3;
4
+ export declare function resolveXAIResolution(imageSize?: string): "1k" | "2k";
5
+ export declare function generateOpenAIImage(model: Model, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
@@ -0,0 +1,3 @@
1
+ import type { Model } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ImageGenerationOptions, ImageGenerationRequest, ImageGenerationResult } from "./types.js";
3
+ export declare function generateOpenRouterImage(model: Model, request: ImageGenerationRequest, options: ImageGenerationOptions): Promise<ImageGenerationResult>;
@@ -0,0 +1,34 @@
1
+ import type { FetchImpl, Model, Usage } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ApiKey } from "../auth-retry.js";
3
+ import * as AIError from "../error/index.js";
4
+ import type { GeneratedImage } from "./types.js";
5
+ export declare class ImageApiError extends AIError.ProviderHttpError {
6
+ readonly name = "ImageApiError";
7
+ }
8
+ export declare function emptyUsage(input?: number, output?: number, cost?: number): Usage;
9
+ export declare function usageFromWire(value: unknown): Usage;
10
+ export declare function imageBaseUrl(model: Model): string;
11
+ export declare function modelHeaders(model: Model, signal?: AbortSignal): Promise<Record<string, string>>;
12
+ export declare function errorMessage(rawText: string): string;
13
+ export declare function postJson(options: {
14
+ model: Model;
15
+ url: string;
16
+ body: unknown;
17
+ apiKey: ApiKey;
18
+ fetch: FetchImpl;
19
+ signal?: AbortSignal;
20
+ }): Promise<unknown>;
21
+ export declare function postMultipart(options: {
22
+ model: Model;
23
+ url: string;
24
+ body: FormData;
25
+ apiKey: ApiKey;
26
+ fetch: FetchImpl;
27
+ signal?: AbortSignal;
28
+ }): Promise<unknown>;
29
+ export declare function decodeImageResponse(value: unknown, fetch: FetchImpl, signal?: AbortSignal): Promise<{
30
+ images: GeneratedImage[];
31
+ usage: Usage;
32
+ }>;
33
+ export declare function toDataUrl(image: GeneratedImage): string;
34
+ export declare function resolveOpenAIImageSize(aspectRatio?: string, imageSize?: string): string | undefined;
@@ -0,0 +1,31 @@
1
+ import type { Api, FetchImpl, Model, Usage } from "@oh-my-pi/pi-catalog/types";
2
+ import type { ApiKey } from "../auth-retry.js";
3
+ export interface ImageInput {
4
+ data: string;
5
+ mimeType: string;
6
+ }
7
+ export interface ImageGenerationRequest {
8
+ prompt: string;
9
+ inputImages?: ImageInput[];
10
+ aspectRatio?: string;
11
+ imageSize?: string;
12
+ count?: number;
13
+ }
14
+ export interface GeneratedImage {
15
+ data: string;
16
+ mimeType: string;
17
+ }
18
+ export interface ImageGenerationResult {
19
+ images: GeneratedImage[];
20
+ text?: string;
21
+ usage: Usage;
22
+ }
23
+ export interface ImageGenerationOptions {
24
+ apiKey: ApiKey;
25
+ fetch?: FetchImpl;
26
+ signal?: AbortSignal;
27
+ /** Chat model that carries a Responses `image_generation` tool call. */
28
+ carrier?: Model<Api>;
29
+ /** Stable provider session id, used by the Codex Responses carrier. */
30
+ sessionId?: string;
31
+ }
@@ -1,12 +1,18 @@
1
1
  export { type Type, type } from "@oh-my-pi/omptype";
2
2
  export * from "./api-registry.js";
3
3
  export type * from "./auth-broker/index.js";
4
- export type { AuthGatewayBootOptions, ModelResolver } from "./auth-gateway/server.js";
4
+ export type { AuthGatewayBootOptions, ModelResolver } from "./auth-gateway/dispatch.js";
5
5
  export * from "./auth-gateway/types.js";
6
6
  export * from "./auth-retry.js";
7
7
  export * from "./auth-storage.js";
8
8
  export * from "./error/rate-limit.js";
9
+ export * from "./embeddings/index.js";
10
+ export * from "./images/index.js";
9
11
  export * from "./judgment/index.js";
12
+ export * from "./rerank/index.js";
13
+ export * from "./speech/index.js";
14
+ export * from "./transcription/index.js";
15
+ export * from "./video/index.js";
10
16
  export * from "./oneshot-retry.js";
11
17
  export * from "./provider-details.js";
12
18
  export * from "./provider-session-state.js";
@@ -27,6 +27,8 @@ export interface TypeSafeJudgeOptions {
27
27
  baseUrl?: string;
28
28
  /** Defaults to {@link typesafeModel}. */
29
29
  model?: string;
30
+ /** Static headers attached to judgment requests (e.g. proxy routing, gateway auth). */
31
+ headers?: Record<string, string>;
30
32
  fetch?: FetchImpl;
31
33
  /** Per-attempt timeout; defaults to {@link DEFAULT_TIMEOUT_MS}. */
32
34
  timeoutMs?: number;
@@ -0,0 +1,32 @@
1
+ import * as AIError from "../error/index.js";
2
+ import type { EmbeddingRequest, EmbeddingResult } from "../embeddings/types.js";
3
+ export declare const MAX_EMBEDDINGS_BODY_BYTES: number;
4
+ export declare class EmbeddingsWireError extends AIError.ValidationError {
5
+ readonly status: number;
6
+ constructor(status: number, message: string, options?: {
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ export interface EmbeddingsParsedRequest {
11
+ modelId: string;
12
+ request: EmbeddingRequest;
13
+ }
14
+ /** Parse an OpenAI-compatible embeddings request with a bounded JSON body. */
15
+ export declare function parseRequest(req: Request): Promise<EmbeddingsParsedRequest>;
16
+ export interface EmbeddingsResponseBody {
17
+ object: "list";
18
+ data: Array<{
19
+ object: "embedding";
20
+ index: number;
21
+ embedding: number[] | string;
22
+ }>;
23
+ model: string;
24
+ usage: {
25
+ prompt_tokens: number;
26
+ total_tokens: number;
27
+ cost?: number;
28
+ };
29
+ }
30
+ /** Encode a canonical result as an OpenAI/OpenRouter embeddings response. */
31
+ export declare function encodeResponse(result: EmbeddingResult, requestedModelId: string): EmbeddingsResponseBody;
32
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,22 @@
1
+ import type { ImageGenerationRequest, ImageGenerationResult } from "../images/types.js";
2
+ export type ImageRequestKind = "generations" | "edits";
3
+ export interface ImagesParsedRequest {
4
+ modelId: string;
5
+ request: ImageGenerationRequest;
6
+ }
7
+ export interface ImagesResponseBody {
8
+ created: number;
9
+ data: Array<{
10
+ b64_json: string;
11
+ revised_prompt?: string;
12
+ }>;
13
+ usage: {
14
+ prompt_tokens: number;
15
+ completion_tokens: number;
16
+ total_tokens: number;
17
+ cost: number;
18
+ };
19
+ }
20
+ export declare function parseRequest(body: unknown | FormData, kind: ImageRequestKind): Promise<ImagesParsedRequest>;
21
+ export declare function encodeResponse(result: ImageGenerationResult, _requestedModelId: string): ImagesResponseBody;
22
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,35 @@
1
+ import * as AIError from "../error/index.js";
2
+ import type { RerankRequest, RerankResult } from "../rerank/types.js";
3
+ export declare const MAX_RERANK_BODY_BYTES: number;
4
+ export interface RerankObjectDocument {
5
+ text: string;
6
+ }
7
+ export type RerankWireDocument = string | RerankObjectDocument;
8
+ export interface RerankParsedRequest {
9
+ modelId: string;
10
+ request: RerankRequest;
11
+ originalDocuments: RerankWireDocument[];
12
+ }
13
+ export declare class RerankWireError extends AIError.ValidationError {
14
+ readonly status: number;
15
+ constructor(status: number, message: string, options?: {
16
+ cause?: unknown;
17
+ });
18
+ }
19
+ /** Parse an OpenRouter-compatible JSON rerank request. */
20
+ export declare function parseRequest(req: Request): Promise<RerankParsedRequest>;
21
+ export interface RerankResponseBody {
22
+ model: string;
23
+ results: Array<{
24
+ index: number;
25
+ relevance_score: number;
26
+ document?: RerankObjectDocument;
27
+ }>;
28
+ usage: {
29
+ total_tokens: number;
30
+ cost: number;
31
+ };
32
+ }
33
+ /** Encode a canonical result as the OpenRouter rerank response shape. */
34
+ export declare function encodeResponse(result: RerankResult, requestedModelId: string, originalDocuments: readonly RerankWireDocument[], returnDocuments: boolean): RerankResponseBody;
35
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,8 @@
1
+ import type { SpeechRequest, SpeechResult } from "../speech/types.js";
2
+ export interface SpeechParsedRequest {
3
+ modelId: string;
4
+ request: SpeechRequest;
5
+ }
6
+ export declare function parseRequest(body: unknown, _headers?: Headers): SpeechParsedRequest;
7
+ export declare function encodeResponse(result: SpeechResult, _requestedModelId: string): Response;
8
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,26 @@
1
+ import type { JudgmentRequest, JudgmentResult } from "../judgment/types.js";
2
+ export interface SystemOneParsedRequest {
3
+ modelId: string;
4
+ request: JudgmentRequest;
5
+ }
6
+ /** `POST /v1/systemone` response body; `cost` (USD) appears only when the route billed one. */
7
+ export interface SystemOneResponseBody {
8
+ model: string;
9
+ answers: JudgmentResult["answers"];
10
+ usage: {
11
+ input_tokens: number;
12
+ output_tokens: number;
13
+ cost?: number;
14
+ };
15
+ }
16
+ /**
17
+ * Validate the routing-relevant parts of a System One request body.
18
+ *
19
+ * @throws {AIError.ValidationError} naming the offending field when `model`,
20
+ * `state`, or `questions` is missing or malformed.
21
+ */
22
+ export declare function parseRequest(body: unknown): SystemOneParsedRequest;
23
+ /** Re-encode a judgment result in TypeSafe's response shape. */
24
+ export declare function encodeResponse(result: JudgmentResult): SystemOneResponseBody;
25
+ /** TypeSafe answers errors with a status code and a JSON body; the envelope mirrors the other gateway routes. */
26
+ export declare function formatError(status: number, type: string, message: string): Response;
@@ -0,0 +1,32 @@
1
+ import * as AIError from "../error/index.js";
2
+ import type { TranscriptionRequest, TranscriptionResult } from "../transcription/types.js";
3
+ export declare const MAX_TRANSCRIPTION_BODY_BYTES: number;
4
+ export declare class TranscriptionWireError extends AIError.ValidationError {
5
+ readonly status: number;
6
+ constructor(status: number, message: string, options?: {
7
+ cause?: unknown;
8
+ });
9
+ }
10
+ export interface TranscriptionParsedRequest {
11
+ modelId: string;
12
+ request: TranscriptionRequest;
13
+ }
14
+ /** Parse either OpenAI multipart uploads or OpenRouter base64 JSON requests. */
15
+ export declare function parseRequest(req: Request): Promise<TranscriptionParsedRequest>;
16
+ export interface TranscriptionResponseBody {
17
+ text: string;
18
+ language?: string;
19
+ duration?: number;
20
+ segments?: TranscriptionResult["segments"];
21
+ words?: TranscriptionResult["words"];
22
+ usage: {
23
+ input_tokens: number;
24
+ output_tokens: number;
25
+ total_tokens: number;
26
+ cost: number;
27
+ seconds?: number;
28
+ };
29
+ }
30
+ /** Encode a canonical result as the shared OpenAI/OpenRouter transcription response. */
31
+ export declare function encodeResponse(result: TranscriptionResult): TranscriptionResponseBody;
32
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,39 @@
1
+ import * as AIError from "../error/index.js";
2
+ import type { VideoGenerationRequest, VideoJob } from "../video/types.js";
3
+ export declare class VideoWireError extends AIError.ValidationError {
4
+ readonly status: number;
5
+ constructor(status: number, message: string, options?: {
6
+ cause?: unknown;
7
+ });
8
+ }
9
+ export interface VideoParsedRequest {
10
+ modelId: string;
11
+ request: VideoGenerationRequest;
12
+ }
13
+ export interface GatewayJobIdentity {
14
+ provider: string;
15
+ modelId: string;
16
+ upstreamId: string;
17
+ }
18
+ /** Parse and validate an OpenRouter-compatible video submit body. */
19
+ export declare function parseRequest(body: unknown): VideoParsedRequest;
20
+ /** Encode all provider/model routing needed to resolve a future poll without gateway state. */
21
+ export declare function encodeGatewayJobId(identity: GatewayJobIdentity): string;
22
+ /** Decode a stateless gateway job id, rejecting malformed or incomplete identities. */
23
+ export declare function decodeGatewayJobId(id: string): GatewayJobIdentity;
24
+ export interface VideoResponseBody {
25
+ id: string;
26
+ status: VideoJob["status"];
27
+ polling_url: string;
28
+ generation_id?: string;
29
+ unsigned_urls?: string[];
30
+ error?: string;
31
+ usage?: {
32
+ cost: number;
33
+ };
34
+ }
35
+ /** Rewrite a provider submit response so every future operation returns through this gateway. */
36
+ export declare function encodeSubmitResponse(job: VideoJob, req: Request, gatewayId: string): VideoResponseBody;
37
+ /** Rewrite a provider poll response so content URLs and polling stay on this gateway. */
38
+ export declare function encodePollResponse(job: VideoJob, req: Request, gatewayId: string): VideoResponseBody;
39
+ export declare function formatError(status: number, errorType: string, message: string): Response;
@@ -0,0 +1,7 @@
1
+ import type { Api, Model } from "@oh-my-pi/pi-catalog/types";
2
+ import { type RerankOptions } from "./openrouter-rerank.js";
3
+ import type { RerankRequest, RerankResult } from "./types.js";
4
+ export * from "./openrouter-rerank.js";
5
+ export * from "./types.js";
6
+ /** Dispatch reranking through the transport selected by the catalog model. */
7
+ export declare function rerank(model: Model<Api>, request: RerankRequest, options: RerankOptions): Promise<RerankResult>;
@@ -0,0 +1,15 @@
1
+ import type { Api, FetchImpl, Model } from "@oh-my-pi/pi-catalog/types";
2
+ import { type ApiKey } from "../auth-retry.js";
3
+ import * as AIError from "../error/index.js";
4
+ import type { RerankRequest, RerankResult } from "./types.js";
5
+ export interface RerankOptions {
6
+ apiKey: ApiKey;
7
+ fetch?: FetchImpl;
8
+ signal?: AbortSignal;
9
+ }
10
+ /** Non-2xx response from an OpenRouter-compatible rerank endpoint. */
11
+ export declare class RerankApiError extends AIError.ProviderHttpError {
12
+ readonly name = "RerankApiError";
13
+ }
14
+ /** Call an OpenRouter-compatible rerank endpoint. */
15
+ export declare function rerankOpenRouter(model: Model<Api>, request: RerankRequest, options: RerankOptions): Promise<RerankResult>;