@ai-sdk/perplexity 4.0.0-beta.8 → 4.0.0-canary.35

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/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@ai-sdk/perplexity",
3
- "version": "4.0.0-beta.8",
3
+ "version": "4.0.0-canary.35",
4
+ "type": "module",
4
5
  "license": "Apache-2.0",
5
6
  "sideEffects": false,
6
7
  "main": "./dist/index.js",
7
- "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist/**/*",
@@ -24,20 +24,20 @@
24
24
  "./package.json": "./package.json",
25
25
  ".": {
26
26
  "types": "./dist/index.d.ts",
27
- "import": "./dist/index.mjs",
28
- "require": "./dist/index.js"
27
+ "import": "./dist/index.js",
28
+ "default": "./dist/index.js"
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.0-beta.4",
33
- "@ai-sdk/provider-utils": "5.0.0-beta.6"
32
+ "@ai-sdk/provider": "4.0.0-canary.15",
33
+ "@ai-sdk/provider-utils": "5.0.0-canary.31"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "20.17.24",
37
37
  "tsup": "^8",
38
38
  "typescript": "5.8.3",
39
39
  "zod": "3.25.76",
40
- "@ai-sdk/test-server": "2.0.0-beta.0",
40
+ "@ai-sdk/test-server": "2.0.0-canary.4",
41
41
  "@vercel/ai-tsconfig": "0.0.0"
42
42
  },
43
43
  "peerDependencies": {
@@ -47,12 +47,14 @@
47
47
  "node": ">=18"
48
48
  },
49
49
  "publishConfig": {
50
- "access": "public"
50
+ "access": "public",
51
+ "provenance": true
51
52
  },
52
53
  "homepage": "https://ai-sdk.dev/docs",
53
54
  "repository": {
54
55
  "type": "git",
55
- "url": "git+https://github.com/vercel/ai.git"
56
+ "url": "https://github.com/vercel/ai",
57
+ "directory": "packages/perplexity"
56
58
  },
57
59
  "bugs": {
58
60
  "url": "https://github.com/vercel/ai/issues"
@@ -1,4 +1,4 @@
1
- import { LanguageModelV4Usage } from '@ai-sdk/provider';
1
+ import type { LanguageModelV4Usage } from '@ai-sdk/provider';
2
2
 
3
3
  export function convertPerplexityUsage(
4
4
  usage:
@@ -1,12 +1,16 @@
1
1
  import {
2
- LanguageModelV4Prompt,
3
2
  UnsupportedFunctionalityError,
3
+ type LanguageModelV4Prompt,
4
4
  } from '@ai-sdk/provider';
5
- import {
5
+ import type {
6
6
  PerplexityMessageContent,
7
7
  PerplexityPrompt,
8
8
  } from './perplexity-language-model-prompt';
9
- import { convertUint8ArrayToBase64 } from '@ai-sdk/provider-utils';
9
+ import {
10
+ convertUint8ArrayToBase64,
11
+ getTopLevelMediaType,
12
+ resolveFullMediaType,
13
+ } from '@ai-sdk/provider-utils';
10
14
 
11
15
  export function convertToPerplexityMessages(
12
16
  prompt: LanguageModelV4Prompt,
@@ -24,8 +28,10 @@ export function convertToPerplexityMessages(
24
28
  case 'assistant': {
25
29
  const hasMultipartContent = content.some(
26
30
  part =>
27
- (part.type === 'file' && part.mediaType.startsWith('image/')) ||
28
- (part.type === 'file' && part.mediaType === 'application/pdf'),
31
+ (part.type === 'file' &&
32
+ getTopLevelMediaType(part.mediaType) === 'image') ||
33
+ (part.type === 'file' &&
34
+ getTopLevelMediaType(part.mediaType) === 'application'),
29
35
  );
30
36
 
31
37
  const messageContent = content
@@ -38,43 +44,61 @@ export function convertToPerplexityMessages(
38
44
  };
39
45
  }
40
46
  case 'file': {
41
- if (part.mediaType === 'application/pdf') {
42
- return part.data instanceof URL
43
- ? {
44
- type: 'file_url',
45
- file_url: {
46
- url: part.data.toString(),
47
- },
48
- file_name: part.filename,
49
- }
50
- : {
51
- type: 'file_url',
52
- file_url: {
53
- url:
54
- typeof part.data === 'string'
55
- ? part.data
56
- : convertUint8ArrayToBase64(part.data),
57
- },
58
- file_name: part.filename || `document-${index}.pdf`,
59
- };
60
- } else if (part.mediaType.startsWith('image/')) {
61
- return part.data instanceof URL
62
- ? {
63
- type: 'image_url',
64
- image_url: {
65
- url: part.data.toString(),
66
- },
67
- }
68
- : {
69
- type: 'image_url',
70
- image_url: {
71
- url: `data:${part.mediaType ?? 'image/jpeg'};base64,${
72
- typeof part.data === 'string'
73
- ? part.data
74
- : convertUint8ArrayToBase64(part.data)
75
- }`,
76
- },
77
- };
47
+ switch (part.data.type) {
48
+ case 'reference': {
49
+ throw new UnsupportedFunctionalityError({
50
+ functionality: 'file parts with provider references',
51
+ });
52
+ }
53
+ case 'text': {
54
+ throw new UnsupportedFunctionalityError({
55
+ functionality: 'text file parts',
56
+ });
57
+ }
58
+ case 'url':
59
+ case 'data': {
60
+ if (part.mediaType === 'application/pdf') {
61
+ return part.data.type === 'url'
62
+ ? {
63
+ type: 'file_url',
64
+ file_url: {
65
+ url: part.data.url.toString(),
66
+ },
67
+ file_name: part.filename,
68
+ }
69
+ : {
70
+ type: 'file_url',
71
+ file_url: {
72
+ url:
73
+ typeof part.data.data === 'string'
74
+ ? part.data.data
75
+ : convertUint8ArrayToBase64(part.data.data),
76
+ },
77
+ file_name: part.filename || `document-${index}.pdf`,
78
+ };
79
+ } else if (
80
+ getTopLevelMediaType(part.mediaType) === 'image'
81
+ ) {
82
+ return part.data.type === 'url'
83
+ ? {
84
+ type: 'image_url',
85
+ image_url: {
86
+ url: part.data.url.toString(),
87
+ },
88
+ }
89
+ : {
90
+ type: 'image_url',
91
+ image_url: {
92
+ url: `data:${resolveFullMediaType({ part })};base64,${
93
+ typeof part.data.data === 'string'
94
+ ? part.data.data
95
+ : convertUint8ArrayToBase64(part.data.data)
96
+ }`,
97
+ },
98
+ };
99
+ }
100
+ return undefined;
101
+ }
78
102
  }
79
103
  }
80
104
  }
@@ -1,4 +1,4 @@
1
- import { LanguageModelV4FinishReason } from '@ai-sdk/provider';
1
+ import type { LanguageModelV4FinishReason } from '@ai-sdk/provider';
2
2
 
3
3
  export function mapPerplexityFinishReason(
4
4
  finishReason: string | null | undefined,
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  LanguageModelV4,
3
3
  LanguageModelV4CallOptions,
4
4
  LanguageModelV4Content,
@@ -9,24 +9,27 @@ import {
9
9
  SharedV4Warning,
10
10
  } from '@ai-sdk/provider';
11
11
  import {
12
- FetchFunction,
13
- ParseResult,
14
12
  combineHeaders,
15
13
  createEventSourceResponseHandler,
16
14
  createJsonErrorResponseHandler,
17
15
  createJsonResponseHandler,
18
16
  isCustomReasoning,
19
17
  postJsonToApi,
18
+ serializeModelOptions,
19
+ WORKFLOW_SERIALIZE,
20
+ WORKFLOW_DESERIALIZE,
21
+ type FetchFunction,
22
+ type ParseResult,
20
23
  } from '@ai-sdk/provider-utils';
21
24
  import { z } from 'zod/v4';
22
25
  import { convertPerplexityUsage } from './convert-perplexity-usage';
23
26
  import { convertToPerplexityMessages } from './convert-to-perplexity-messages';
24
27
  import { mapPerplexityFinishReason } from './map-perplexity-finish-reason';
25
- import { PerplexityLanguageModelId } from './perplexity-language-model-options';
28
+ import type { PerplexityLanguageModelId } from './perplexity-options';
26
29
 
27
30
  type PerplexityChatConfig = {
28
31
  baseURL: string;
29
- headers: () => Record<string, string | undefined>;
32
+ headers?: () => Record<string, string | undefined>;
30
33
  generateId: () => string;
31
34
  fetch?: FetchFunction;
32
35
  };
@@ -39,6 +42,20 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
39
42
 
40
43
  private readonly config: PerplexityChatConfig;
41
44
 
45
+ static [WORKFLOW_SERIALIZE](model: PerplexityLanguageModel) {
46
+ return serializeModelOptions({
47
+ modelId: model.modelId,
48
+ config: model.config,
49
+ });
50
+ }
51
+
52
+ static [WORKFLOW_DESERIALIZE](options: {
53
+ modelId: PerplexityLanguageModelId;
54
+ config: PerplexityChatConfig;
55
+ }) {
56
+ return new PerplexityLanguageModel(options.modelId, options.config);
57
+ }
58
+
42
59
  constructor(
43
60
  modelId: PerplexityLanguageModelId,
44
61
  config: PerplexityChatConfig,
@@ -130,7 +147,7 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
130
147
  rawValue: rawResponse,
131
148
  } = await postJsonToApi({
132
149
  url: `${this.config.baseURL}/chat/completions`,
133
- headers: combineHeaders(this.config.headers(), options.headers),
150
+ headers: combineHeaders(this.config.headers?.(), options.headers),
134
151
  body,
135
152
  failedResponseHandler: createJsonErrorResponseHandler({
136
153
  errorSchema: perplexityErrorSchema,
@@ -191,6 +208,15 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
191
208
  citationTokens: response.usage?.citation_tokens ?? null,
192
209
  numSearchQueries: response.usage?.num_search_queries ?? null,
193
210
  },
211
+ cost: response.usage?.cost
212
+ ? {
213
+ inputTokensCost: response.usage.cost.input_tokens_cost ?? null,
214
+ outputTokensCost:
215
+ response.usage.cost.output_tokens_cost ?? null,
216
+ requestCost: response.usage.cost.request_cost ?? null,
217
+ totalCost: response.usage.cost.total_cost ?? null,
218
+ }
219
+ : null,
194
220
  },
195
221
  },
196
222
  };
@@ -205,7 +231,7 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
205
231
 
206
232
  const { responseHeaders, value: response } = await postJsonToApi({
207
233
  url: `${this.config.baseURL}/chat/completions`,
208
- headers: combineHeaders(this.config.headers(), options.headers),
234
+ headers: combineHeaders(this.config.headers?.(), options.headers),
209
235
  body,
210
236
  failedResponseHandler: createJsonErrorResponseHandler({
211
237
  errorSchema: perplexityErrorSchema,
@@ -236,6 +262,12 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
236
262
  citationTokens: number | null;
237
263
  numSearchQueries: number | null;
238
264
  };
265
+ cost: {
266
+ inputTokensCost: number | null;
267
+ outputTokensCost: number | null;
268
+ requestCost: number | null;
269
+ totalCost: number | null;
270
+ } | null;
239
271
  images: Array<{
240
272
  imageUrl: string;
241
273
  originUrl: string;
@@ -249,6 +281,7 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
249
281
  citationTokens: null,
250
282
  numSearchQueries: null,
251
283
  },
284
+ cost: null,
252
285
  images: null,
253
286
  },
254
287
  };
@@ -305,6 +338,16 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
305
338
  citationTokens: value.usage.citation_tokens ?? null,
306
339
  numSearchQueries: value.usage.num_search_queries ?? null,
307
340
  };
341
+
342
+ providerMetadata.perplexity.cost = value.usage.cost
343
+ ? {
344
+ inputTokensCost: value.usage.cost.input_tokens_cost ?? null,
345
+ outputTokensCost:
346
+ value.usage.cost.output_tokens_cost ?? null,
347
+ requestCost: value.usage.cost.request_cost ?? null,
348
+ totalCost: value.usage.cost.total_cost ?? null,
349
+ }
350
+ : null;
308
351
  }
309
352
 
310
353
  if (value.images != null) {
@@ -381,6 +424,13 @@ function getResponseMetadata({
381
424
  };
382
425
  }
383
426
 
427
+ const perplexityCostSchema = z.object({
428
+ input_tokens_cost: z.number().nullish(),
429
+ output_tokens_cost: z.number().nullish(),
430
+ request_cost: z.number().nullish(),
431
+ total_cost: z.number().nullish(),
432
+ });
433
+
384
434
  const perplexityUsageSchema = z.object({
385
435
  prompt_tokens: z.number(),
386
436
  completion_tokens: z.number(),
@@ -388,6 +438,7 @@ const perplexityUsageSchema = z.object({
388
438
  citation_tokens: z.number().nullish(),
389
439
  num_search_queries: z.number().nullish(),
390
440
  reasoning_tokens: z.number().nullish(),
441
+ cost: perplexityCostSchema.nullish(),
391
442
  });
392
443
 
393
444
  export const perplexityImageSchema = z.object({
@@ -1,17 +1,17 @@
1
1
  import {
2
- LanguageModelV4,
3
2
  NoSuchModelError,
4
- ProviderV4,
3
+ type LanguageModelV4,
4
+ type ProviderV4,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
- FetchFunction,
8
7
  generateId,
9
8
  loadApiKey,
10
9
  withoutTrailingSlash,
11
10
  withUserAgentSuffix,
11
+ type FetchFunction,
12
12
  } from '@ai-sdk/provider-utils';
13
13
  import { PerplexityLanguageModel } from './perplexity-language-model';
14
- import { PerplexityLanguageModelId } from './perplexity-language-model-options';
14
+ import type { PerplexityLanguageModelId } from './perplexity-options';
15
15
  import { VERSION } from './version';
16
16
 
17
17
  export interface PerplexityProvider extends ProviderV4 {
package/dist/index.d.mts DELETED
@@ -1,44 +0,0 @@
1
- import { ProviderV4, LanguageModelV4 } from '@ai-sdk/provider';
2
- import { FetchFunction } from '@ai-sdk/provider-utils';
3
-
4
- type PerplexityLanguageModelId = 'sonar-deep-research' | 'sonar-reasoning-pro' | 'sonar-reasoning' | 'sonar-pro' | 'sonar' | (string & {});
5
-
6
- interface PerplexityProvider extends ProviderV4 {
7
- /**
8
- * Creates an Perplexity chat model for text generation.
9
- */
10
- (modelId: PerplexityLanguageModelId): LanguageModelV4;
11
- /**
12
- * Creates an Perplexity language model for text generation.
13
- */
14
- languageModel(modelId: PerplexityLanguageModelId): LanguageModelV4;
15
- /**
16
- * @deprecated Use `embeddingModel` instead.
17
- */
18
- textEmbeddingModel(modelId: string): never;
19
- }
20
- interface PerplexityProviderSettings {
21
- /**
22
- * Base URL for the perplexity API calls.
23
- */
24
- baseURL?: string;
25
- /**
26
- * API key for authenticating requests.
27
- */
28
- apiKey?: string;
29
- /**
30
- * Custom headers to include in the requests.
31
- */
32
- headers?: Record<string, string>;
33
- /**
34
- * Custom fetch implementation. You can use it as a middleware to intercept requests,
35
- * or to provide a custom fetch implementation for e.g. testing.
36
- */
37
- fetch?: FetchFunction;
38
- }
39
- declare function createPerplexity(options?: PerplexityProviderSettings): PerplexityProvider;
40
- declare const perplexity: PerplexityProvider;
41
-
42
- declare const VERSION: string;
43
-
44
- export { type PerplexityProvider, type PerplexityProviderSettings, VERSION, createPerplexity, perplexity };