@ai-sdk/perplexity 4.0.0-beta.22 → 4.0.0-beta.24

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.22",
3
+ "version": "4.0.0-beta.24",
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.10",
33
- "@ai-sdk/provider-utils": "5.0.0-beta.18"
32
+ "@ai-sdk/provider": "4.0.0-beta.12",
33
+ "@ai-sdk/provider-utils": "5.0.0-beta.20"
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-beta.1",
41
41
  "@vercel/ai-tsconfig": "0.0.0"
42
42
  },
43
43
  "peerDependencies": {
@@ -17,6 +17,9 @@ import {
17
17
  createJsonResponseHandler,
18
18
  isCustomReasoning,
19
19
  postJsonToApi,
20
+ serializeModelOptions,
21
+ WORKFLOW_SERIALIZE,
22
+ WORKFLOW_DESERIALIZE,
20
23
  } from '@ai-sdk/provider-utils';
21
24
  import { z } from 'zod/v4';
22
25
  import { convertPerplexityUsage } from './convert-perplexity-usage';
@@ -26,7 +29,7 @@ import { PerplexityLanguageModelId } from './perplexity-language-model-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,
@@ -214,7 +231,7 @@ export class PerplexityLanguageModel implements LanguageModelV4 {
214
231
 
215
232
  const { responseHeaders, value: response } = await postJsonToApi({
216
233
  url: `${this.config.baseURL}/chat/completions`,
217
- headers: combineHeaders(this.config.headers(), options.headers),
234
+ headers: combineHeaders(this.config.headers?.(), options.headers),
218
235
  body,
219
236
  failedResponseHandler: createJsonErrorResponseHandler({
220
237
  errorSchema: perplexityErrorSchema,
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 };
package/dist/index.mjs DELETED
@@ -1,550 +0,0 @@
1
- // src/perplexity-provider.ts
2
- import {
3
- NoSuchModelError
4
- } from "@ai-sdk/provider";
5
- import {
6
- generateId,
7
- loadApiKey,
8
- withoutTrailingSlash,
9
- withUserAgentSuffix
10
- } from "@ai-sdk/provider-utils";
11
-
12
- // src/perplexity-language-model.ts
13
- import {
14
- combineHeaders,
15
- createEventSourceResponseHandler,
16
- createJsonErrorResponseHandler,
17
- createJsonResponseHandler,
18
- isCustomReasoning,
19
- postJsonToApi
20
- } from "@ai-sdk/provider-utils";
21
- import { z } from "zod/v4";
22
-
23
- // src/convert-perplexity-usage.ts
24
- function convertPerplexityUsage(usage) {
25
- var _a, _b, _c;
26
- if (usage == null) {
27
- return {
28
- inputTokens: {
29
- total: void 0,
30
- noCache: void 0,
31
- cacheRead: void 0,
32
- cacheWrite: void 0
33
- },
34
- outputTokens: {
35
- total: void 0,
36
- text: void 0,
37
- reasoning: void 0
38
- },
39
- raw: void 0
40
- };
41
- }
42
- const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0;
43
- const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
44
- const reasoningTokens = (_c = usage.reasoning_tokens) != null ? _c : 0;
45
- return {
46
- inputTokens: {
47
- total: promptTokens,
48
- noCache: promptTokens,
49
- cacheRead: void 0,
50
- cacheWrite: void 0
51
- },
52
- outputTokens: {
53
- total: completionTokens,
54
- text: completionTokens - reasoningTokens,
55
- reasoning: reasoningTokens
56
- },
57
- raw: usage
58
- };
59
- }
60
-
61
- // src/convert-to-perplexity-messages.ts
62
- import {
63
- UnsupportedFunctionalityError
64
- } from "@ai-sdk/provider";
65
- import {
66
- convertUint8ArrayToBase64,
67
- isProviderReference
68
- } from "@ai-sdk/provider-utils";
69
- function convertToPerplexityMessages(prompt) {
70
- const messages = [];
71
- for (const { role, content } of prompt) {
72
- switch (role) {
73
- case "system": {
74
- messages.push({ role: "system", content });
75
- break;
76
- }
77
- case "user":
78
- case "assistant": {
79
- const hasMultipartContent = content.some(
80
- (part) => part.type === "file" && part.mediaType.startsWith("image/") || part.type === "file" && part.mediaType === "application/pdf"
81
- );
82
- const messageContent = content.map((part, index) => {
83
- var _a;
84
- switch (part.type) {
85
- case "text": {
86
- return {
87
- type: "text",
88
- text: part.text
89
- };
90
- }
91
- case "file": {
92
- if (isProviderReference(part.data)) {
93
- throw new UnsupportedFunctionalityError({
94
- functionality: "file parts with provider references"
95
- });
96
- }
97
- if (part.mediaType === "application/pdf") {
98
- return part.data instanceof URL ? {
99
- type: "file_url",
100
- file_url: {
101
- url: part.data.toString()
102
- },
103
- file_name: part.filename
104
- } : {
105
- type: "file_url",
106
- file_url: {
107
- url: typeof part.data === "string" ? part.data : convertUint8ArrayToBase64(part.data)
108
- },
109
- file_name: part.filename || `document-${index}.pdf`
110
- };
111
- } else if (part.mediaType.startsWith("image/")) {
112
- return part.data instanceof URL ? {
113
- type: "image_url",
114
- image_url: {
115
- url: part.data.toString()
116
- }
117
- } : {
118
- type: "image_url",
119
- image_url: {
120
- url: `data:${(_a = part.mediaType) != null ? _a : "image/jpeg"};base64,${typeof part.data === "string" ? part.data : convertUint8ArrayToBase64(part.data)}`
121
- }
122
- };
123
- }
124
- }
125
- }
126
- }).filter(Boolean);
127
- messages.push({
128
- role,
129
- content: hasMultipartContent ? messageContent : messageContent.filter((part) => part.type === "text").map((part) => part.text).join("")
130
- });
131
- break;
132
- }
133
- case "tool": {
134
- throw new UnsupportedFunctionalityError({
135
- functionality: "Tool messages"
136
- });
137
- }
138
- default: {
139
- const _exhaustiveCheck = role;
140
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
141
- }
142
- }
143
- }
144
- return messages;
145
- }
146
-
147
- // src/map-perplexity-finish-reason.ts
148
- function mapPerplexityFinishReason(finishReason) {
149
- switch (finishReason) {
150
- case "stop":
151
- case "length":
152
- return finishReason;
153
- default:
154
- return "other";
155
- }
156
- }
157
-
158
- // src/perplexity-language-model.ts
159
- var PerplexityLanguageModel = class {
160
- constructor(modelId, config) {
161
- this.specificationVersion = "v4";
162
- this.provider = "perplexity";
163
- this.supportedUrls = {
164
- // No URLs are supported.
165
- };
166
- this.modelId = modelId;
167
- this.config = config;
168
- }
169
- getArgs({
170
- prompt,
171
- maxOutputTokens,
172
- temperature,
173
- topP,
174
- topK,
175
- frequencyPenalty,
176
- presencePenalty,
177
- stopSequences,
178
- reasoning,
179
- responseFormat,
180
- seed,
181
- providerOptions
182
- }) {
183
- var _a;
184
- const warnings = [];
185
- if (topK != null) {
186
- warnings.push({ type: "unsupported", feature: "topK" });
187
- }
188
- if (stopSequences != null) {
189
- warnings.push({ type: "unsupported", feature: "stopSequences" });
190
- }
191
- if (seed != null) {
192
- warnings.push({ type: "unsupported", feature: "seed" });
193
- }
194
- if (isCustomReasoning(reasoning)) {
195
- warnings.push({
196
- type: "unsupported",
197
- feature: "reasoning",
198
- details: "This provider does not support reasoning configuration."
199
- });
200
- }
201
- return {
202
- args: {
203
- // model id:
204
- model: this.modelId,
205
- // standardized settings:
206
- frequency_penalty: frequencyPenalty,
207
- max_tokens: maxOutputTokens,
208
- presence_penalty: presencePenalty,
209
- temperature,
210
- top_k: topK,
211
- top_p: topP,
212
- // response format:
213
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? {
214
- type: "json_schema",
215
- json_schema: { schema: responseFormat.schema }
216
- } : void 0,
217
- // provider extensions
218
- ...(_a = providerOptions == null ? void 0 : providerOptions.perplexity) != null ? _a : {},
219
- // messages:
220
- messages: convertToPerplexityMessages(prompt)
221
- },
222
- warnings
223
- };
224
- }
225
- async doGenerate(options) {
226
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
227
- const { args: body, warnings } = this.getArgs(options);
228
- const {
229
- responseHeaders,
230
- value: response,
231
- rawValue: rawResponse
232
- } = await postJsonToApi({
233
- url: `${this.config.baseURL}/chat/completions`,
234
- headers: combineHeaders(this.config.headers(), options.headers),
235
- body,
236
- failedResponseHandler: createJsonErrorResponseHandler({
237
- errorSchema: perplexityErrorSchema,
238
- errorToMessage
239
- }),
240
- successfulResponseHandler: createJsonResponseHandler(
241
- perplexityResponseSchema
242
- ),
243
- abortSignal: options.abortSignal,
244
- fetch: this.config.fetch
245
- });
246
- const choice = response.choices[0];
247
- const content = [];
248
- const text = choice.message.content;
249
- if (text.length > 0) {
250
- content.push({ type: "text", text });
251
- }
252
- if (response.citations != null) {
253
- for (const url of response.citations) {
254
- content.push({
255
- type: "source",
256
- sourceType: "url",
257
- id: this.config.generateId(),
258
- url
259
- });
260
- }
261
- }
262
- return {
263
- content,
264
- finishReason: {
265
- unified: mapPerplexityFinishReason(choice.finish_reason),
266
- raw: (_a = choice.finish_reason) != null ? _a : void 0
267
- },
268
- usage: convertPerplexityUsage(response.usage),
269
- request: { body },
270
- response: {
271
- ...getResponseMetadata(response),
272
- headers: responseHeaders,
273
- body: rawResponse
274
- },
275
- warnings,
276
- providerMetadata: {
277
- perplexity: {
278
- images: (_c = (_b = response.images) == null ? void 0 : _b.map((image) => ({
279
- imageUrl: image.image_url,
280
- originUrl: image.origin_url,
281
- height: image.height,
282
- width: image.width
283
- }))) != null ? _c : null,
284
- usage: {
285
- citationTokens: (_e = (_d = response.usage) == null ? void 0 : _d.citation_tokens) != null ? _e : null,
286
- numSearchQueries: (_g = (_f = response.usage) == null ? void 0 : _f.num_search_queries) != null ? _g : null
287
- },
288
- cost: ((_h = response.usage) == null ? void 0 : _h.cost) ? {
289
- inputTokensCost: (_i = response.usage.cost.input_tokens_cost) != null ? _i : null,
290
- outputTokensCost: (_j = response.usage.cost.output_tokens_cost) != null ? _j : null,
291
- requestCost: (_k = response.usage.cost.request_cost) != null ? _k : null,
292
- totalCost: (_l = response.usage.cost.total_cost) != null ? _l : null
293
- } : null
294
- }
295
- }
296
- };
297
- }
298
- async doStream(options) {
299
- const { args, warnings } = this.getArgs(options);
300
- const body = { ...args, stream: true };
301
- const { responseHeaders, value: response } = await postJsonToApi({
302
- url: `${this.config.baseURL}/chat/completions`,
303
- headers: combineHeaders(this.config.headers(), options.headers),
304
- body,
305
- failedResponseHandler: createJsonErrorResponseHandler({
306
- errorSchema: perplexityErrorSchema,
307
- errorToMessage
308
- }),
309
- successfulResponseHandler: createEventSourceResponseHandler(
310
- perplexityChunkSchema
311
- ),
312
- abortSignal: options.abortSignal,
313
- fetch: this.config.fetch
314
- });
315
- let finishReason = {
316
- unified: "other",
317
- raw: void 0
318
- };
319
- let usage = void 0;
320
- const providerMetadata = {
321
- perplexity: {
322
- usage: {
323
- citationTokens: null,
324
- numSearchQueries: null
325
- },
326
- cost: null,
327
- images: null
328
- }
329
- };
330
- let isFirstChunk = true;
331
- let isActive = false;
332
- const self = this;
333
- return {
334
- stream: response.pipeThrough(
335
- new TransformStream({
336
- start(controller) {
337
- controller.enqueue({ type: "stream-start", warnings });
338
- },
339
- transform(chunk, controller) {
340
- var _a, _b, _c, _d, _e, _f, _g;
341
- if (options.includeRawChunks) {
342
- controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
343
- }
344
- if (!chunk.success) {
345
- controller.enqueue({ type: "error", error: chunk.error });
346
- return;
347
- }
348
- const value = chunk.value;
349
- if (isFirstChunk) {
350
- controller.enqueue({
351
- type: "response-metadata",
352
- ...getResponseMetadata(value)
353
- });
354
- (_a = value.citations) == null ? void 0 : _a.forEach((url) => {
355
- controller.enqueue({
356
- type: "source",
357
- sourceType: "url",
358
- id: self.config.generateId(),
359
- url
360
- });
361
- });
362
- isFirstChunk = false;
363
- }
364
- if (value.usage != null) {
365
- usage = value.usage;
366
- providerMetadata.perplexity.usage = {
367
- citationTokens: (_b = value.usage.citation_tokens) != null ? _b : null,
368
- numSearchQueries: (_c = value.usage.num_search_queries) != null ? _c : null
369
- };
370
- providerMetadata.perplexity.cost = value.usage.cost ? {
371
- inputTokensCost: (_d = value.usage.cost.input_tokens_cost) != null ? _d : null,
372
- outputTokensCost: (_e = value.usage.cost.output_tokens_cost) != null ? _e : null,
373
- requestCost: (_f = value.usage.cost.request_cost) != null ? _f : null,
374
- totalCost: (_g = value.usage.cost.total_cost) != null ? _g : null
375
- } : null;
376
- }
377
- if (value.images != null) {
378
- providerMetadata.perplexity.images = value.images.map((image) => ({
379
- imageUrl: image.image_url,
380
- originUrl: image.origin_url,
381
- height: image.height,
382
- width: image.width
383
- }));
384
- }
385
- const choice = value.choices[0];
386
- if ((choice == null ? void 0 : choice.finish_reason) != null) {
387
- finishReason = {
388
- unified: mapPerplexityFinishReason(choice.finish_reason),
389
- raw: choice.finish_reason
390
- };
391
- }
392
- if ((choice == null ? void 0 : choice.delta) == null) {
393
- return;
394
- }
395
- const delta = choice.delta;
396
- const textContent = delta.content;
397
- if (textContent != null) {
398
- if (!isActive) {
399
- controller.enqueue({ type: "text-start", id: "0" });
400
- isActive = true;
401
- }
402
- controller.enqueue({
403
- type: "text-delta",
404
- id: "0",
405
- delta: textContent
406
- });
407
- }
408
- },
409
- flush(controller) {
410
- if (isActive) {
411
- controller.enqueue({ type: "text-end", id: "0" });
412
- }
413
- controller.enqueue({
414
- type: "finish",
415
- finishReason,
416
- usage: convertPerplexityUsage(usage),
417
- providerMetadata
418
- });
419
- }
420
- })
421
- ),
422
- request: { body },
423
- response: { headers: responseHeaders }
424
- };
425
- }
426
- };
427
- function getResponseMetadata({
428
- id,
429
- model,
430
- created
431
- }) {
432
- return {
433
- id,
434
- modelId: model,
435
- timestamp: new Date(created * 1e3)
436
- };
437
- }
438
- var perplexityCostSchema = z.object({
439
- input_tokens_cost: z.number().nullish(),
440
- output_tokens_cost: z.number().nullish(),
441
- request_cost: z.number().nullish(),
442
- total_cost: z.number().nullish()
443
- });
444
- var perplexityUsageSchema = z.object({
445
- prompt_tokens: z.number(),
446
- completion_tokens: z.number(),
447
- total_tokens: z.number().nullish(),
448
- citation_tokens: z.number().nullish(),
449
- num_search_queries: z.number().nullish(),
450
- reasoning_tokens: z.number().nullish(),
451
- cost: perplexityCostSchema.nullish()
452
- });
453
- var perplexityImageSchema = z.object({
454
- image_url: z.string(),
455
- origin_url: z.string(),
456
- height: z.number(),
457
- width: z.number()
458
- });
459
- var perplexityResponseSchema = z.object({
460
- id: z.string(),
461
- created: z.number(),
462
- model: z.string(),
463
- choices: z.array(
464
- z.object({
465
- message: z.object({
466
- role: z.literal("assistant"),
467
- content: z.string()
468
- }),
469
- finish_reason: z.string().nullish()
470
- })
471
- ),
472
- citations: z.array(z.string()).nullish(),
473
- images: z.array(perplexityImageSchema).nullish(),
474
- usage: perplexityUsageSchema.nullish()
475
- });
476
- var perplexityChunkSchema = z.object({
477
- id: z.string(),
478
- created: z.number(),
479
- model: z.string(),
480
- choices: z.array(
481
- z.object({
482
- delta: z.object({
483
- role: z.literal("assistant"),
484
- content: z.string()
485
- }),
486
- finish_reason: z.string().nullish()
487
- })
488
- ),
489
- citations: z.array(z.string()).nullish(),
490
- images: z.array(perplexityImageSchema).nullish(),
491
- usage: perplexityUsageSchema.nullish()
492
- });
493
- var perplexityErrorSchema = z.object({
494
- error: z.object({
495
- code: z.number(),
496
- message: z.string().nullish(),
497
- type: z.string().nullish()
498
- })
499
- });
500
- var errorToMessage = (data) => {
501
- var _a, _b;
502
- return (_b = (_a = data.error.message) != null ? _a : data.error.type) != null ? _b : "unknown error";
503
- };
504
-
505
- // src/version.ts
506
- var VERSION = true ? "4.0.0-beta.22" : "0.0.0-test";
507
-
508
- // src/perplexity-provider.ts
509
- function createPerplexity(options = {}) {
510
- const getHeaders = () => withUserAgentSuffix(
511
- {
512
- Authorization: `Bearer ${loadApiKey({
513
- apiKey: options.apiKey,
514
- environmentVariableName: "PERPLEXITY_API_KEY",
515
- description: "Perplexity"
516
- })}`,
517
- ...options.headers
518
- },
519
- `ai-sdk/perplexity/${VERSION}`
520
- );
521
- const createLanguageModel = (modelId) => {
522
- var _a;
523
- return new PerplexityLanguageModel(modelId, {
524
- baseURL: withoutTrailingSlash(
525
- (_a = options.baseURL) != null ? _a : "https://api.perplexity.ai"
526
- ),
527
- headers: getHeaders,
528
- generateId,
529
- fetch: options.fetch
530
- });
531
- };
532
- const provider = (modelId) => createLanguageModel(modelId);
533
- provider.specificationVersion = "v4";
534
- provider.languageModel = createLanguageModel;
535
- provider.embeddingModel = (modelId) => {
536
- throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
537
- };
538
- provider.textEmbeddingModel = provider.embeddingModel;
539
- provider.imageModel = (modelId) => {
540
- throw new NoSuchModelError({ modelId, modelType: "imageModel" });
541
- };
542
- return provider;
543
- }
544
- var perplexity = createPerplexity();
545
- export {
546
- VERSION,
547
- createPerplexity,
548
- perplexity
549
- };
550
- //# sourceMappingURL=index.mjs.map