@anyr/ai-sdk-provider 0.1.4 → 0.1.7

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.
package/README.md CHANGED
@@ -3,8 +3,8 @@
3
3
  The [AnyRouter](https://anyrouter.dev) provider for the [Vercel AI SDK](https://ai-sdk.dev).
4
4
 
5
5
  Call every model on the AnyRouter gateway through the standard AI SDK
6
- interface — `generateText`, `streamText`, `generateObject`, `embedMany`,
7
- `generateImage` — with one key and one provider.
6
+ interface — `generateText`, `streamText`, `generateObject`, `embedMany` —
7
+ with one key and one provider.
8
8
 
9
9
  ## Install
10
10
 
@@ -147,23 +147,6 @@ const { embeddings } = await embedMany({
147
147
  console.log(embeddings[0]) // [0.123, -0.456, ...]
148
148
  ```
149
149
 
150
- ### Image generation
151
-
152
- ```ts
153
- import { createAnyRouter } from "@anyr/ai-sdk-provider"
154
- import { generateImage } from "ai"
155
-
156
- const anyrouter = createAnyRouter()
157
-
158
- const { image } = await generateImage({
159
- model: anyrouter.imageModel("openai/dall-e-3"),
160
- prompt: "A serene mountain lake at dawn, oil painting.",
161
- size: "1024x1024",
162
- })
163
-
164
- // image.base64 — base64-encoded PNG or URL depending on the model
165
- ```
166
-
167
150
  ### Provider options (routing, session, extra body)
168
151
 
169
152
  ```ts
@@ -227,7 +210,6 @@ const anyrouter = createAnyRouter({
227
210
  | `anyrouter.chat(modelId)` | `LanguageModelV3` | Chat / instruction language model |
228
211
  | `anyrouter.languageModel(modelId)` | `LanguageModelV3` | Alias for `.chat()` (ProviderV3 interface) |
229
212
  | `anyrouter.embeddingModel(modelId)` | `EmbeddingModelV3` | Text embedding model |
230
- | `anyrouter.imageModel(modelId)` | `ImageModelV3` | Image generation model |
231
213
  | `anyrouter.client` | `AnyRouter` | Raw `@anyr/sdk` client (escape hatch) |
232
214
 
233
215
  ## Default export
package/dist/index.d.cts CHANGED
@@ -1,6 +1,83 @@
1
- import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, EmbeddingModelV3, EmbeddingModelV3CallOptions, EmbeddingModelV3Result, ImageModelV3, ImageModelV3CallOptions, ProviderV3 } from '@ai-sdk/provider';
1
+ import { SharedV4ProviderReference, LanguageModelV4, LanguageModelV4CallOptions, LanguageModelV4GenerateResult, LanguageModelV4StreamResult, EmbeddingModelV4, EmbeddingModelV4CallOptions, EmbeddingModelV4Result, FilesV4, FilesV4UploadFileCallOptions, FilesV4UploadFileResult, ProviderV4 } from '@ai-sdk/provider';
2
2
  import { AnyRouter } from '@anyr/sdk';
3
3
 
4
+ /**
5
+ * Identity of the client making the request. Mirrors the `X-AnyRouter-*`
6
+ * headers the gateway reads in `inference-telemetry.ts`.
7
+ */
8
+ interface AppAttribution {
9
+ /**
10
+ * Stable machine identifier, becomes `generations.app_source`. Use a slug
11
+ * (`anyr-cli`, `anyr-agent`), not a display name.
12
+ */
13
+ source?: string;
14
+ /** Human-readable name, becomes `generations.app_title`. */
15
+ title?: string;
16
+ /** Client version, becomes `generations.app_version`. */
17
+ version?: string;
18
+ /**
19
+ * Curation categories (e.g. `cli-agent`). The gateway allowlists these and
20
+ * keeps at most two per request; unknown values are dropped server-side.
21
+ */
22
+ categories?: string[];
23
+ /**
24
+ * Public URL identifying the app, sent as `HTTP-Referer`. Only meaningful for
25
+ * apps that want to appear in the public app rankings.
26
+ */
27
+ url?: string;
28
+ }
29
+ /** This provider's own identity, used when the caller supplies no `app`. */
30
+ declare const PROVIDER_ATTRIBUTION: AppAttribution;
31
+ /**
32
+ * Translate an {@link AppAttribution} into wire headers. Blank/whitespace-only
33
+ * values are omitted rather than sent empty, so a partially-filled identity
34
+ * never overwrites a good value with `""`.
35
+ *
36
+ * Returns `{}` when `app` is undefined, so callers that pass no `app` send no
37
+ * attribution headers by default. This matches the provider contract in
38
+ * `types.ts`: browser callers are attributed by Referer instead.
39
+ */
40
+ declare function buildAppAttributionHeaders(app: AppAttribution | undefined): Record<string, string>;
41
+
42
+ /**
43
+ * The resolved representation of a cached file — a URL string ready to drop
44
+ * into an OpenAI-compatible message part and the media type that accompanies it.
45
+ */
46
+ type ResolvedFileEntry = {
47
+ /** Ready-to-use string: a data URL (`data:<mime>;base64,…`) or an https URL. */
48
+ url: string;
49
+ mediaType: string;
50
+ };
51
+ /**
52
+ * In-session file reference cache.
53
+ *
54
+ * Files are keyed by a SHA-256 hex hash of their content. A single provider
55
+ * instance shares one cache, so the same binary content is never encoded or
56
+ * stored more than once within an agent loop — even across multiple `doGenerate`
57
+ * / `doStream` calls.
58
+ *
59
+ * This class is intentionally free of I/O and network calls. All async
60
+ * behaviour lives in the `hashFileData` helper below.
61
+ */
62
+ declare class FileReferenceCache {
63
+ private readonly store;
64
+ /**
65
+ * Look up a cached entry via a `SharedV4ProviderReference`.
66
+ * Returns `undefined` when the reference was not created by this cache.
67
+ */
68
+ lookup(reference: SharedV4ProviderReference): ResolvedFileEntry | undefined;
69
+ /** Add an entry and return the corresponding provider reference. */
70
+ set(hash: string, entry: ResolvedFileEntry): SharedV4ProviderReference;
71
+ /** Returns true when the content hash is already cached. */
72
+ has(hash: string): boolean;
73
+ /**
74
+ * Build a `SharedV4ProviderReference` for the given hash without writing
75
+ * to the cache. Use this to construct the return value of `uploadFile`
76
+ * after confirming the hash is already stored.
77
+ */
78
+ referenceFor(hash: string): SharedV4ProviderReference;
79
+ }
80
+
4
81
  /**
5
82
  * Settings for `createAnyRouter(...)`.
6
83
  */
@@ -11,6 +88,16 @@ interface AnyRouterProviderSettings {
11
88
  * Resolved lazily at request time.
12
89
  */
13
90
  apiKey?: string;
91
+ /**
92
+ * Skip API-key resolution entirely. When `true`, no `Authorization` header is
93
+ * derived from `apiKey`/`ANYROUTER_API_KEY` — requests rely on ambient auth
94
+ * such as same-origin session cookies (the AnyRouter Playground) or an
95
+ * `Authorization` header supplied via {@link headers}.
96
+ *
97
+ * Without this, `createAnyRouter()` throws at request time when no key is
98
+ * present. Defaults to `false`.
99
+ */
100
+ keyless?: boolean;
14
101
  /**
15
102
  * API base URL.
16
103
  * Defaults to `https://anyrouter.dev/api/v1`.
@@ -20,6 +107,17 @@ interface AnyRouterProviderSettings {
20
107
  * Extra headers merged into every request.
21
108
  */
22
109
  headers?: Record<string, string>;
110
+ /**
111
+ * Identify your app to AnyRouter, sent as the `X-AnyRouter-*` attribution
112
+ * headers so your traffic shows up under your own name in usage analytics.
113
+ *
114
+ * Opt-in rather than defaulted: unlike `@anyr/sdk`, this provider is
115
+ * routinely used from a browser, where the gateway already attributes the
116
+ * request from its `Referer`. A default `X-AnyRouter-Source` would override
117
+ * that (the explicit header wins server-side) and misattribute browser apps
118
+ * to the provider library.
119
+ */
120
+ app?: AppAttribution;
23
121
  /**
24
122
  * Custom fetch implementation.
25
123
  * Defaults to the global `fetch`.
@@ -41,6 +139,19 @@ interface AnyRouterProviderSettings {
41
139
  * Per-call `providerOptions.anyrouter.extraBody` takes precedence.
42
140
  */
43
141
  extraBody?: Record<string, unknown>;
142
+ /**
143
+ * Cache every response for N seconds via Cloudflare AI Gateway.
144
+ * Sent as the `cf-aig-cache-ttl` header. Min 60, max ~1 month (2,678,400s).
145
+ * Per-call `providerOptions.anyrouter.cacheTtl` takes precedence.
146
+ */
147
+ cacheTtl?: number;
148
+ /**
149
+ * Skip Cloudflare AI Gateway response caching for every request, even if a
150
+ * default cache policy would otherwise apply. Sent as
151
+ * `cf-aig-skip-cache: true`. Per-call `providerOptions.anyrouter.skipCache`
152
+ * takes precedence.
153
+ */
154
+ skipCache?: boolean;
44
155
  }
45
156
 
46
157
  interface AnyRouterChatConfig {
@@ -49,16 +160,22 @@ interface AnyRouterChatConfig {
49
160
  headers: () => Record<string, string | undefined>;
50
161
  fetch?: typeof globalThis.fetch;
51
162
  settings: AnyRouterProviderSettings;
163
+ /**
164
+ * Shared file reference cache for the provider instance.
165
+ * When present, `{ type: 'reference' }` file parts are resolved via the cache
166
+ * rather than throwing `UnsupportedFunctionalityError`.
167
+ */
168
+ fileCache?: FileReferenceCache;
52
169
  }
53
- declare class AnyRouterChatLanguageModel implements LanguageModelV3 {
54
- readonly specificationVersion: "v3";
170
+ declare class AnyRouterChatLanguageModel implements LanguageModelV4 {
171
+ readonly specificationVersion: "v4";
55
172
  readonly provider: string;
56
173
  readonly modelId: string;
57
174
  readonly supportedUrls: Record<string, RegExp[]>;
58
175
  private readonly config;
59
176
  constructor(modelId: string, config: AnyRouterChatConfig);
60
- doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult>;
61
- doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
177
+ doGenerate(options: LanguageModelV4CallOptions): Promise<LanguageModelV4GenerateResult>;
178
+ doStream(options: LanguageModelV4CallOptions): Promise<LanguageModelV4StreamResult>;
62
179
  }
63
180
 
64
181
  interface AnyRouterEmbeddingConfig {
@@ -67,8 +184,8 @@ interface AnyRouterEmbeddingConfig {
67
184
  headers: () => Record<string, string | undefined>;
68
185
  fetch?: typeof globalThis.fetch;
69
186
  }
70
- declare class AnyRouterEmbeddingModel implements EmbeddingModelV3 {
71
- readonly specificationVersion: "v3";
187
+ declare class AnyRouterEmbeddingModel implements EmbeddingModelV4 {
188
+ readonly specificationVersion: "v4";
72
189
  readonly provider: string;
73
190
  readonly modelId: string;
74
191
  /** No hard per-call limit imposed by the provider layer. */
@@ -76,39 +193,72 @@ declare class AnyRouterEmbeddingModel implements EmbeddingModelV3 {
76
193
  readonly supportsParallelCalls = true;
77
194
  private readonly config;
78
195
  constructor(modelId: string, config: AnyRouterEmbeddingConfig);
79
- doEmbed(options: EmbeddingModelV3CallOptions): Promise<EmbeddingModelV3Result>;
196
+ doEmbed(options: EmbeddingModelV4CallOptions): Promise<EmbeddingModelV4Result>;
80
197
  }
81
198
 
82
- interface AnyRouterImageConfig {
83
- provider: string;
84
- baseURL: string;
85
- headers: () => Record<string, string | undefined>;
86
- fetch?: typeof globalThis.fetch;
87
- }
88
- declare class AnyRouterImageModel implements ImageModelV3 {
89
- readonly specificationVersion: "v3";
199
+ /**
200
+ * `FilesV4` implementation for the AnyRouter provider.
201
+ *
202
+ * ## How it works
203
+ *
204
+ * `uploadFile()` computes a SHA-256 hash of the file content and stores the
205
+ * resolved data URL in a shared `FileReferenceCache`. It returns a
206
+ * `SharedV4ProviderReference` whose `anyrouter` key is that hash.
207
+ *
208
+ * When the same reference later appears as a `{ type: 'reference' }` file
209
+ * part in a multi-step prompt, `convertToAnyRouterChatMessages` looks up the
210
+ * hash in the cache and substitutes the stored URL — so the full file bytes
211
+ * are never re-encoded on subsequent calls within the same provider session.
212
+ *
213
+ * ## Limitations (Phase 2)
214
+ *
215
+ * The cache is in-memory and scoped to the provider instance. References do
216
+ * not persist across process restarts. A follow-up (Phase 3+) can wire this
217
+ * to the AnyRouter gateway's `/files` endpoint to get durable, cross-session
218
+ * file IDs that translate to `{ type: "file", file: { file_id: "…" } }` parts
219
+ * for providers that support it (e.g. OpenAI).
220
+ */
221
+ declare class AnyRouterFiles implements FilesV4 {
222
+ readonly specificationVersion: "v4";
90
223
  readonly provider: string;
91
- readonly modelId: string;
224
+ private readonly cache;
225
+ constructor(provider: string, cache: FileReferenceCache);
92
226
  /**
93
- * Most image generation APIs support only 1 image per call via the
94
- * standard `/images/generations` endpoint.
227
+ * Register a file in the in-session cache and return a provider reference.
228
+ *
229
+ * Calling this multiple times with the same file content is idempotent —
230
+ * the hash check prevents redundant re-encoding.
95
231
  */
96
- readonly maxImagesPerCall = 1;
97
- private readonly config;
98
- constructor(modelId: string, config: AnyRouterImageConfig);
99
- doGenerate(options: ImageModelV3CallOptions): Promise<Awaited<ReturnType<ImageModelV3["doGenerate"]>>>;
232
+ uploadFile(options: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult>;
100
233
  }
101
234
 
102
- interface AnyRouterProvider extends ProviderV3 {
235
+ interface AnyRouterProvider extends ProviderV4 {
103
236
  /** Create a chat language model by calling the provider directly. */
104
- (modelId: string): LanguageModelV3;
237
+ (modelId: string): LanguageModelV4;
105
238
  /** Create a chat language model (explicit method). */
106
- chat(modelId: string): LanguageModelV3;
239
+ chat(modelId: string): LanguageModelV4;
107
240
  /**
108
241
  * Low-level `@anyr/sdk` client instance.
109
242
  * Use this as an escape hatch when you need direct API access.
110
243
  */
111
244
  readonly client: AnyRouter;
245
+ /**
246
+ * File management interface (AI SDK v4 `FilesV4`).
247
+ *
248
+ * Call `uploadFile()` to register a file in the session cache. The returned
249
+ * `providerReference` can be used in subsequent model calls as a
250
+ * `{ type: 'file', data: { type: 'reference', reference } }` part — the
251
+ * provider resolves the reference from the cache without re-encoding the file.
252
+ *
253
+ * ```ts
254
+ * const ref = await anyrouter.files().uploadFile({
255
+ * data: { type: 'data', data: pdfBytes },
256
+ * mediaType: 'application/pdf',
257
+ * })
258
+ * // ref.providerReference === { anyrouter: '<sha256-hex>' }
259
+ * ```
260
+ */
261
+ files(): FilesV4;
112
262
  }
113
263
  /**
114
264
  * Create an AnyRouter provider for the Vercel AI SDK.
@@ -146,4 +296,4 @@ declare function createAnyRouter(options?: AnyRouterProviderSettings): AnyRouter
146
296
  */
147
297
  declare const anyrouter: AnyRouterProvider;
148
298
 
149
- export { type AnyRouterChatConfig, AnyRouterChatLanguageModel, type AnyRouterEmbeddingConfig, AnyRouterEmbeddingModel, type AnyRouterImageConfig, AnyRouterImageModel, type AnyRouterProvider, type AnyRouterProviderSettings, anyrouter, createAnyRouter };
299
+ export { type AnyRouterChatConfig, AnyRouterChatLanguageModel, type AnyRouterEmbeddingConfig, AnyRouterEmbeddingModel, AnyRouterFiles, type AnyRouterProvider, type AnyRouterProviderSettings, type AppAttribution, FileReferenceCache, PROVIDER_ATTRIBUTION, type ResolvedFileEntry, anyrouter, buildAppAttributionHeaders, createAnyRouter };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,83 @@
1
- import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, EmbeddingModelV3, EmbeddingModelV3CallOptions, EmbeddingModelV3Result, ImageModelV3, ImageModelV3CallOptions, ProviderV3 } from '@ai-sdk/provider';
1
+ import { SharedV4ProviderReference, LanguageModelV4, LanguageModelV4CallOptions, LanguageModelV4GenerateResult, LanguageModelV4StreamResult, EmbeddingModelV4, EmbeddingModelV4CallOptions, EmbeddingModelV4Result, FilesV4, FilesV4UploadFileCallOptions, FilesV4UploadFileResult, ProviderV4 } from '@ai-sdk/provider';
2
2
  import { AnyRouter } from '@anyr/sdk';
3
3
 
4
+ /**
5
+ * Identity of the client making the request. Mirrors the `X-AnyRouter-*`
6
+ * headers the gateway reads in `inference-telemetry.ts`.
7
+ */
8
+ interface AppAttribution {
9
+ /**
10
+ * Stable machine identifier, becomes `generations.app_source`. Use a slug
11
+ * (`anyr-cli`, `anyr-agent`), not a display name.
12
+ */
13
+ source?: string;
14
+ /** Human-readable name, becomes `generations.app_title`. */
15
+ title?: string;
16
+ /** Client version, becomes `generations.app_version`. */
17
+ version?: string;
18
+ /**
19
+ * Curation categories (e.g. `cli-agent`). The gateway allowlists these and
20
+ * keeps at most two per request; unknown values are dropped server-side.
21
+ */
22
+ categories?: string[];
23
+ /**
24
+ * Public URL identifying the app, sent as `HTTP-Referer`. Only meaningful for
25
+ * apps that want to appear in the public app rankings.
26
+ */
27
+ url?: string;
28
+ }
29
+ /** This provider's own identity, used when the caller supplies no `app`. */
30
+ declare const PROVIDER_ATTRIBUTION: AppAttribution;
31
+ /**
32
+ * Translate an {@link AppAttribution} into wire headers. Blank/whitespace-only
33
+ * values are omitted rather than sent empty, so a partially-filled identity
34
+ * never overwrites a good value with `""`.
35
+ *
36
+ * Returns `{}` when `app` is undefined, so callers that pass no `app` send no
37
+ * attribution headers by default. This matches the provider contract in
38
+ * `types.ts`: browser callers are attributed by Referer instead.
39
+ */
40
+ declare function buildAppAttributionHeaders(app: AppAttribution | undefined): Record<string, string>;
41
+
42
+ /**
43
+ * The resolved representation of a cached file — a URL string ready to drop
44
+ * into an OpenAI-compatible message part and the media type that accompanies it.
45
+ */
46
+ type ResolvedFileEntry = {
47
+ /** Ready-to-use string: a data URL (`data:<mime>;base64,…`) or an https URL. */
48
+ url: string;
49
+ mediaType: string;
50
+ };
51
+ /**
52
+ * In-session file reference cache.
53
+ *
54
+ * Files are keyed by a SHA-256 hex hash of their content. A single provider
55
+ * instance shares one cache, so the same binary content is never encoded or
56
+ * stored more than once within an agent loop — even across multiple `doGenerate`
57
+ * / `doStream` calls.
58
+ *
59
+ * This class is intentionally free of I/O and network calls. All async
60
+ * behaviour lives in the `hashFileData` helper below.
61
+ */
62
+ declare class FileReferenceCache {
63
+ private readonly store;
64
+ /**
65
+ * Look up a cached entry via a `SharedV4ProviderReference`.
66
+ * Returns `undefined` when the reference was not created by this cache.
67
+ */
68
+ lookup(reference: SharedV4ProviderReference): ResolvedFileEntry | undefined;
69
+ /** Add an entry and return the corresponding provider reference. */
70
+ set(hash: string, entry: ResolvedFileEntry): SharedV4ProviderReference;
71
+ /** Returns true when the content hash is already cached. */
72
+ has(hash: string): boolean;
73
+ /**
74
+ * Build a `SharedV4ProviderReference` for the given hash without writing
75
+ * to the cache. Use this to construct the return value of `uploadFile`
76
+ * after confirming the hash is already stored.
77
+ */
78
+ referenceFor(hash: string): SharedV4ProviderReference;
79
+ }
80
+
4
81
  /**
5
82
  * Settings for `createAnyRouter(...)`.
6
83
  */
@@ -11,6 +88,16 @@ interface AnyRouterProviderSettings {
11
88
  * Resolved lazily at request time.
12
89
  */
13
90
  apiKey?: string;
91
+ /**
92
+ * Skip API-key resolution entirely. When `true`, no `Authorization` header is
93
+ * derived from `apiKey`/`ANYROUTER_API_KEY` — requests rely on ambient auth
94
+ * such as same-origin session cookies (the AnyRouter Playground) or an
95
+ * `Authorization` header supplied via {@link headers}.
96
+ *
97
+ * Without this, `createAnyRouter()` throws at request time when no key is
98
+ * present. Defaults to `false`.
99
+ */
100
+ keyless?: boolean;
14
101
  /**
15
102
  * API base URL.
16
103
  * Defaults to `https://anyrouter.dev/api/v1`.
@@ -20,6 +107,17 @@ interface AnyRouterProviderSettings {
20
107
  * Extra headers merged into every request.
21
108
  */
22
109
  headers?: Record<string, string>;
110
+ /**
111
+ * Identify your app to AnyRouter, sent as the `X-AnyRouter-*` attribution
112
+ * headers so your traffic shows up under your own name in usage analytics.
113
+ *
114
+ * Opt-in rather than defaulted: unlike `@anyr/sdk`, this provider is
115
+ * routinely used from a browser, where the gateway already attributes the
116
+ * request from its `Referer`. A default `X-AnyRouter-Source` would override
117
+ * that (the explicit header wins server-side) and misattribute browser apps
118
+ * to the provider library.
119
+ */
120
+ app?: AppAttribution;
23
121
  /**
24
122
  * Custom fetch implementation.
25
123
  * Defaults to the global `fetch`.
@@ -41,6 +139,19 @@ interface AnyRouterProviderSettings {
41
139
  * Per-call `providerOptions.anyrouter.extraBody` takes precedence.
42
140
  */
43
141
  extraBody?: Record<string, unknown>;
142
+ /**
143
+ * Cache every response for N seconds via Cloudflare AI Gateway.
144
+ * Sent as the `cf-aig-cache-ttl` header. Min 60, max ~1 month (2,678,400s).
145
+ * Per-call `providerOptions.anyrouter.cacheTtl` takes precedence.
146
+ */
147
+ cacheTtl?: number;
148
+ /**
149
+ * Skip Cloudflare AI Gateway response caching for every request, even if a
150
+ * default cache policy would otherwise apply. Sent as
151
+ * `cf-aig-skip-cache: true`. Per-call `providerOptions.anyrouter.skipCache`
152
+ * takes precedence.
153
+ */
154
+ skipCache?: boolean;
44
155
  }
45
156
 
46
157
  interface AnyRouterChatConfig {
@@ -49,16 +160,22 @@ interface AnyRouterChatConfig {
49
160
  headers: () => Record<string, string | undefined>;
50
161
  fetch?: typeof globalThis.fetch;
51
162
  settings: AnyRouterProviderSettings;
163
+ /**
164
+ * Shared file reference cache for the provider instance.
165
+ * When present, `{ type: 'reference' }` file parts are resolved via the cache
166
+ * rather than throwing `UnsupportedFunctionalityError`.
167
+ */
168
+ fileCache?: FileReferenceCache;
52
169
  }
53
- declare class AnyRouterChatLanguageModel implements LanguageModelV3 {
54
- readonly specificationVersion: "v3";
170
+ declare class AnyRouterChatLanguageModel implements LanguageModelV4 {
171
+ readonly specificationVersion: "v4";
55
172
  readonly provider: string;
56
173
  readonly modelId: string;
57
174
  readonly supportedUrls: Record<string, RegExp[]>;
58
175
  private readonly config;
59
176
  constructor(modelId: string, config: AnyRouterChatConfig);
60
- doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult>;
61
- doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
177
+ doGenerate(options: LanguageModelV4CallOptions): Promise<LanguageModelV4GenerateResult>;
178
+ doStream(options: LanguageModelV4CallOptions): Promise<LanguageModelV4StreamResult>;
62
179
  }
63
180
 
64
181
  interface AnyRouterEmbeddingConfig {
@@ -67,8 +184,8 @@ interface AnyRouterEmbeddingConfig {
67
184
  headers: () => Record<string, string | undefined>;
68
185
  fetch?: typeof globalThis.fetch;
69
186
  }
70
- declare class AnyRouterEmbeddingModel implements EmbeddingModelV3 {
71
- readonly specificationVersion: "v3";
187
+ declare class AnyRouterEmbeddingModel implements EmbeddingModelV4 {
188
+ readonly specificationVersion: "v4";
72
189
  readonly provider: string;
73
190
  readonly modelId: string;
74
191
  /** No hard per-call limit imposed by the provider layer. */
@@ -76,39 +193,72 @@ declare class AnyRouterEmbeddingModel implements EmbeddingModelV3 {
76
193
  readonly supportsParallelCalls = true;
77
194
  private readonly config;
78
195
  constructor(modelId: string, config: AnyRouterEmbeddingConfig);
79
- doEmbed(options: EmbeddingModelV3CallOptions): Promise<EmbeddingModelV3Result>;
196
+ doEmbed(options: EmbeddingModelV4CallOptions): Promise<EmbeddingModelV4Result>;
80
197
  }
81
198
 
82
- interface AnyRouterImageConfig {
83
- provider: string;
84
- baseURL: string;
85
- headers: () => Record<string, string | undefined>;
86
- fetch?: typeof globalThis.fetch;
87
- }
88
- declare class AnyRouterImageModel implements ImageModelV3 {
89
- readonly specificationVersion: "v3";
199
+ /**
200
+ * `FilesV4` implementation for the AnyRouter provider.
201
+ *
202
+ * ## How it works
203
+ *
204
+ * `uploadFile()` computes a SHA-256 hash of the file content and stores the
205
+ * resolved data URL in a shared `FileReferenceCache`. It returns a
206
+ * `SharedV4ProviderReference` whose `anyrouter` key is that hash.
207
+ *
208
+ * When the same reference later appears as a `{ type: 'reference' }` file
209
+ * part in a multi-step prompt, `convertToAnyRouterChatMessages` looks up the
210
+ * hash in the cache and substitutes the stored URL — so the full file bytes
211
+ * are never re-encoded on subsequent calls within the same provider session.
212
+ *
213
+ * ## Limitations (Phase 2)
214
+ *
215
+ * The cache is in-memory and scoped to the provider instance. References do
216
+ * not persist across process restarts. A follow-up (Phase 3+) can wire this
217
+ * to the AnyRouter gateway's `/files` endpoint to get durable, cross-session
218
+ * file IDs that translate to `{ type: "file", file: { file_id: "…" } }` parts
219
+ * for providers that support it (e.g. OpenAI).
220
+ */
221
+ declare class AnyRouterFiles implements FilesV4 {
222
+ readonly specificationVersion: "v4";
90
223
  readonly provider: string;
91
- readonly modelId: string;
224
+ private readonly cache;
225
+ constructor(provider: string, cache: FileReferenceCache);
92
226
  /**
93
- * Most image generation APIs support only 1 image per call via the
94
- * standard `/images/generations` endpoint.
227
+ * Register a file in the in-session cache and return a provider reference.
228
+ *
229
+ * Calling this multiple times with the same file content is idempotent —
230
+ * the hash check prevents redundant re-encoding.
95
231
  */
96
- readonly maxImagesPerCall = 1;
97
- private readonly config;
98
- constructor(modelId: string, config: AnyRouterImageConfig);
99
- doGenerate(options: ImageModelV3CallOptions): Promise<Awaited<ReturnType<ImageModelV3["doGenerate"]>>>;
232
+ uploadFile(options: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult>;
100
233
  }
101
234
 
102
- interface AnyRouterProvider extends ProviderV3 {
235
+ interface AnyRouterProvider extends ProviderV4 {
103
236
  /** Create a chat language model by calling the provider directly. */
104
- (modelId: string): LanguageModelV3;
237
+ (modelId: string): LanguageModelV4;
105
238
  /** Create a chat language model (explicit method). */
106
- chat(modelId: string): LanguageModelV3;
239
+ chat(modelId: string): LanguageModelV4;
107
240
  /**
108
241
  * Low-level `@anyr/sdk` client instance.
109
242
  * Use this as an escape hatch when you need direct API access.
110
243
  */
111
244
  readonly client: AnyRouter;
245
+ /**
246
+ * File management interface (AI SDK v4 `FilesV4`).
247
+ *
248
+ * Call `uploadFile()` to register a file in the session cache. The returned
249
+ * `providerReference` can be used in subsequent model calls as a
250
+ * `{ type: 'file', data: { type: 'reference', reference } }` part — the
251
+ * provider resolves the reference from the cache without re-encoding the file.
252
+ *
253
+ * ```ts
254
+ * const ref = await anyrouter.files().uploadFile({
255
+ * data: { type: 'data', data: pdfBytes },
256
+ * mediaType: 'application/pdf',
257
+ * })
258
+ * // ref.providerReference === { anyrouter: '<sha256-hex>' }
259
+ * ```
260
+ */
261
+ files(): FilesV4;
112
262
  }
113
263
  /**
114
264
  * Create an AnyRouter provider for the Vercel AI SDK.
@@ -146,4 +296,4 @@ declare function createAnyRouter(options?: AnyRouterProviderSettings): AnyRouter
146
296
  */
147
297
  declare const anyrouter: AnyRouterProvider;
148
298
 
149
- export { type AnyRouterChatConfig, AnyRouterChatLanguageModel, type AnyRouterEmbeddingConfig, AnyRouterEmbeddingModel, type AnyRouterImageConfig, AnyRouterImageModel, type AnyRouterProvider, type AnyRouterProviderSettings, anyrouter, createAnyRouter };
299
+ export { type AnyRouterChatConfig, AnyRouterChatLanguageModel, type AnyRouterEmbeddingConfig, AnyRouterEmbeddingModel, AnyRouterFiles, type AnyRouterProvider, type AnyRouterProviderSettings, type AppAttribution, FileReferenceCache, PROVIDER_ATTRIBUTION, type ResolvedFileEntry, anyrouter, buildAppAttributionHeaders, createAnyRouter };