@ai-sdk/perplexity 3.0.62 → 3.1.0

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/dist/index.mjs CHANGED
@@ -15,13 +15,13 @@ import {
15
15
  } from "@ai-sdk/provider";
16
16
  import {
17
17
  combineHeaders as combineHeaders2,
18
- convertBase64ToUint8Array as convertBase64ToUint8Array2,
18
+ convertBase64ToUint8Array,
19
19
  createJsonErrorResponseHandler as createJsonErrorResponseHandler2,
20
20
  createJsonResponseHandler as createJsonResponseHandler2,
21
- parseProviderOptions,
21
+ parseProviderOptions as parseProviderOptions2,
22
22
  postJsonToApi as postJsonToApi2
23
23
  } from "@ai-sdk/provider-utils";
24
- import { z as z3 } from "zod/v4";
24
+ import { z as z4 } from "zod/v4";
25
25
 
26
26
  // src/perplexity-embedding-model-options.ts
27
27
  import { z } from "zod/v4";
@@ -42,18 +42,21 @@ var perplexityEmbeddingModelOptions = z.object({
42
42
  });
43
43
 
44
44
  // src/perplexity-language-model.ts
45
+ import {
46
+ APICallError
47
+ } from "@ai-sdk/provider";
45
48
  import {
46
49
  combineHeaders,
47
50
  createEventSourceResponseHandler,
48
51
  createJsonErrorResponseHandler,
49
52
  createJsonResponseHandler,
53
+ parseProviderOptions,
50
54
  postJsonToApi
51
55
  } from "@ai-sdk/provider-utils";
52
- import { z as z2 } from "zod/v4";
53
56
 
54
57
  // src/convert-perplexity-usage.ts
55
58
  function convertPerplexityUsage(usage) {
56
- var _a, _b, _c;
59
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
57
60
  if (usage == null) {
58
61
  return {
59
62
  inputTokens: {
@@ -70,106 +73,176 @@ function convertPerplexityUsage(usage) {
70
73
  raw: void 0
71
74
  };
72
75
  }
73
- const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0;
74
- const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
75
- const reasoningTokens = (_c = usage.reasoning_tokens) != null ? _c : 0;
76
+ const inputTokens = (_a = usage.input_tokens) != null ? _a : 0;
77
+ const outputTokens = (_b = usage.output_tokens) != null ? _b : 0;
78
+ const cacheReadTokens = (_f = (_e = (_c = usage.input_tokens_details) == null ? void 0 : _c.cache_read_input_tokens) != null ? _e : (_d = usage.input_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _f : 0;
79
+ const cacheWriteTokens = (_h = (_g = usage.input_tokens_details) == null ? void 0 : _g.cache_creation_input_tokens) != null ? _h : 0;
80
+ const reasoningTokens = (_j = (_i = usage.output_tokens_details) == null ? void 0 : _i.reasoning_tokens) != null ? _j : 0;
76
81
  return {
77
82
  inputTokens: {
78
- total: promptTokens,
79
- noCache: promptTokens,
80
- cacheRead: void 0,
81
- cacheWrite: void 0
83
+ total: inputTokens,
84
+ noCache: Math.max(0, inputTokens - cacheReadTokens - cacheWriteTokens),
85
+ cacheRead: cacheReadTokens,
86
+ cacheWrite: cacheWriteTokens
82
87
  },
83
88
  outputTokens: {
84
- // Perplexity reports reasoning tokens separately from completion tokens.
85
- total: completionTokens + reasoningTokens,
86
- text: completionTokens,
89
+ total: outputTokens,
90
+ text: Math.max(0, outputTokens - reasoningTokens),
87
91
  reasoning: reasoningTokens
88
92
  },
89
93
  raw: usage
90
94
  };
91
95
  }
92
96
 
93
- // src/convert-to-perplexity-messages.ts
97
+ // src/convert-to-perplexity-input.ts
94
98
  import {
95
99
  UnsupportedFunctionalityError
96
100
  } from "@ai-sdk/provider";
97
- import {
98
- convertBase64ToUint8Array,
99
- convertUint8ArrayToBase64
100
- } from "@ai-sdk/provider-utils";
101
- function convertToPerplexityMessages(prompt) {
102
- const messages = [];
101
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
102
+ function serializeToolOutput(output) {
103
+ var _a;
104
+ switch (output.type) {
105
+ case "text":
106
+ case "error-text":
107
+ return output.value;
108
+ case "json":
109
+ case "error-json":
110
+ return JSON.stringify(output.value);
111
+ case "execution-denied":
112
+ return (_a = output.reason) != null ? _a : "Tool call execution denied.";
113
+ case "content": {
114
+ if (output.value.some((part) => part.type !== "text")) {
115
+ throw new UnsupportedFunctionalityError({
116
+ functionality: "file and custom tool result content"
117
+ });
118
+ }
119
+ return output.value.map((part) => part.type === "text" ? part.text : "").join("");
120
+ }
121
+ default: {
122
+ const _exhaustiveCheck = output;
123
+ throw new Error(`Unsupported tool output: ${_exhaustiveCheck}`);
124
+ }
125
+ }
126
+ }
127
+ function getTopLevelMediaType(mediaType) {
128
+ const slashIndex = mediaType.indexOf("/");
129
+ return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex);
130
+ }
131
+ function getThoughtSignature(providerOptions) {
132
+ var _a;
133
+ const thoughtSignature = (_a = providerOptions == null ? void 0 : providerOptions.perplexity) == null ? void 0 : _a.thoughtSignature;
134
+ return typeof thoughtSignature === "string" ? thoughtSignature : void 0;
135
+ }
136
+ function convertToPerplexityInput(prompt) {
137
+ var _a;
138
+ const input = [];
139
+ const warnings = [];
103
140
  for (const { role, content } of prompt) {
104
141
  switch (role) {
105
142
  case "system": {
106
- messages.push({ role: "system", content });
143
+ input.push({ type: "message", role: "system", content });
107
144
  break;
108
145
  }
109
- case "user":
110
- case "assistant": {
111
- const hasMultipartContent = content.some(
112
- (part) => part.type === "file" && part.mediaType.startsWith("image/") || part.type === "file" && getTopLevelMediaType(part.mediaType) === "application"
113
- );
114
- const messageContent = content.map((part, index) => {
115
- var _a;
116
- switch (part.type) {
117
- case "text": {
118
- return {
119
- type: "text",
120
- text: part.text
121
- };
122
- }
123
- case "file": {
124
- if (getTopLevelMediaType(part.mediaType) === "application") {
125
- const fullMediaType = resolveApplicationMediaType(part);
126
- if (fullMediaType !== "application/pdf") {
146
+ case "user": {
147
+ const convertedContent = content.map(
148
+ (part) => {
149
+ switch (part.type) {
150
+ case "text":
151
+ return { type: "input_text", text: part.text };
152
+ case "file": {
153
+ if (getTopLevelMediaType(part.mediaType) !== "image") {
127
154
  throw new UnsupportedFunctionalityError({
128
- functionality: `file part media type ${fullMediaType}`
155
+ functionality: `file part media type ${part.mediaType}`
129
156
  });
130
157
  }
131
- return part.data instanceof URL ? {
132
- type: "file_url",
133
- file_url: {
134
- url: part.data.toString()
135
- },
136
- file_name: part.filename
137
- } : {
138
- type: "file_url",
139
- file_url: {
140
- url: typeof part.data === "string" ? part.data : convertUint8ArrayToBase64(part.data)
141
- },
142
- file_name: part.filename || `document-${index}.pdf`
143
- };
144
- } else if (part.mediaType.startsWith("image/")) {
145
- return part.data instanceof URL ? {
146
- type: "image_url",
147
- image_url: {
148
- url: part.data.toString()
149
- }
150
- } : {
151
- type: "image_url",
152
- image_url: {
153
- url: `data:${(_a = part.mediaType) != null ? _a : "image/jpeg"};base64,${typeof part.data === "string" ? part.data : convertUint8ArrayToBase64(part.data)}`
154
- }
158
+ if (part.data instanceof URL) {
159
+ return {
160
+ type: "input_image",
161
+ image_url: part.data.toString()
162
+ };
163
+ }
164
+ const mediaType = part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
165
+ return {
166
+ type: "input_image",
167
+ image_url: `data:${mediaType};base64,${typeof part.data === "string" ? part.data : convertUint8ArrayToBase64(part.data)}`
155
168
  };
156
169
  }
170
+ }
171
+ }
172
+ );
173
+ const isTextOnly = convertedContent.every(
174
+ (part) => part.type === "input_text"
175
+ );
176
+ input.push({
177
+ type: "message",
178
+ role: "user",
179
+ content: isTextOnly ? convertedContent.map((part) => part.type === "input_text" ? part.text : "").join("") : convertedContent
180
+ });
181
+ break;
182
+ }
183
+ case "assistant": {
184
+ const text = content.filter((part) => part.type === "text").map((part) => part.text).join("");
185
+ if (text.length > 0) {
186
+ input.push({ type: "message", role: "assistant", content: text });
187
+ }
188
+ for (const part of content) {
189
+ switch (part.type) {
190
+ case "text":
191
+ break;
192
+ case "tool-call":
193
+ input.push({
194
+ type: "function_call",
195
+ call_id: part.toolCallId,
196
+ name: part.toolName,
197
+ arguments: JSON.stringify((_a = part.input) != null ? _a : {}),
198
+ thought_signature: getThoughtSignature(part.providerOptions)
199
+ });
200
+ break;
201
+ case "tool-result":
202
+ input.push({
203
+ type: "function_call_output",
204
+ call_id: part.toolCallId,
205
+ name: part.toolName,
206
+ output: serializeToolOutput(part.output),
207
+ thought_signature: getThoughtSignature(part.providerOptions)
208
+ });
209
+ break;
210
+ case "reasoning":
211
+ warnings.push({
212
+ type: "unsupported",
213
+ feature: "reasoning content in prompt"
214
+ });
215
+ break;
216
+ case "file":
157
217
  throw new UnsupportedFunctionalityError({
158
- functionality: `file part media type ${part.mediaType}`
218
+ functionality: `assistant ${part.type} parts`
159
219
  });
220
+ default: {
221
+ const _exhaustiveCheck = part;
222
+ throw new Error(
223
+ `Unsupported assistant part: ${_exhaustiveCheck}`
224
+ );
160
225
  }
161
226
  }
162
- }).filter(Boolean);
163
- messages.push({
164
- role,
165
- content: hasMultipartContent ? messageContent : messageContent.filter((part) => part.type === "text").map((part) => part.text).join("")
166
- });
227
+ }
167
228
  break;
168
229
  }
169
230
  case "tool": {
170
- throw new UnsupportedFunctionalityError({
171
- functionality: "Tool messages"
172
- });
231
+ for (const part of content) {
232
+ if (part.type === "tool-approval-response") {
233
+ throw new UnsupportedFunctionalityError({
234
+ functionality: "tool approval responses"
235
+ });
236
+ }
237
+ input.push({
238
+ type: "function_call_output",
239
+ call_id: part.toolCallId,
240
+ name: part.toolName,
241
+ output: serializeToolOutput(part.output),
242
+ thought_signature: getThoughtSignature(part.providerOptions)
243
+ });
244
+ }
245
+ break;
173
246
  }
174
247
  default: {
175
248
  const _exhaustiveCheck = role;
@@ -177,64 +250,438 @@ function convertToPerplexityMessages(prompt) {
177
250
  }
178
251
  }
179
252
  }
180
- return messages;
181
- }
182
- function getTopLevelMediaType(mediaType) {
183
- const slashIndex = mediaType.indexOf("/");
184
- return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex);
253
+ return { input, warnings };
185
254
  }
186
- function isFullMediaType(mediaType) {
187
- const slashIndex = mediaType.indexOf("/");
188
- if (slashIndex === -1) {
189
- return false;
255
+
256
+ // src/map-perplexity-finish-reason.ts
257
+ function mapPerplexityFinishReason({
258
+ status,
259
+ incompleteReason,
260
+ hasFunctionCall
261
+ }) {
262
+ switch (incompleteReason) {
263
+ case "max_output_tokens":
264
+ return "length";
265
+ case "content_filter":
266
+ return "content-filter";
267
+ }
268
+ switch (status) {
269
+ case "completed":
270
+ return hasFunctionCall ? "tool-calls" : "stop";
271
+ case "requires_action":
272
+ return "tool-calls";
273
+ case "failed":
274
+ return "error";
275
+ case "cancelled":
276
+ case "queued":
277
+ case "in_progress":
278
+ default:
279
+ return hasFunctionCall ? "tool-calls" : "other";
190
280
  }
191
- const subtype = mediaType.substring(slashIndex + 1);
192
- return subtype.length > 0 && subtype !== "*";
193
281
  }
194
- function resolveApplicationMediaType(part) {
195
- if (isFullMediaType(part.mediaType)) {
196
- return part.mediaType;
282
+
283
+ // src/perplexity-agent-api.ts
284
+ import { z as z2 } from "zod/v4";
285
+ var perplexitySearchResultSchema = z2.looseObject({
286
+ id: z2.number().optional(),
287
+ title: z2.string(),
288
+ url: z2.string(),
289
+ snippet: z2.string().optional(),
290
+ date: z2.string().nullish(),
291
+ last_updated: z2.string().nullish(),
292
+ source: z2.string().optional()
293
+ });
294
+ var perplexityFetchedContentSchema = z2.looseObject({
295
+ title: z2.string(),
296
+ url: z2.string(),
297
+ snippet: z2.string().optional()
298
+ });
299
+ var perplexityContentPartSchema = z2.looseObject({
300
+ type: z2.string(),
301
+ text: z2.string().optional(),
302
+ annotations: z2.array(
303
+ z2.looseObject({
304
+ type: z2.string().optional(),
305
+ url: z2.string().optional(),
306
+ title: z2.string().optional()
307
+ })
308
+ ).nullish()
309
+ });
310
+ var handledOutputTypes = [
311
+ "message",
312
+ "search_results",
313
+ "fetch_url_results",
314
+ "function_call"
315
+ ];
316
+ var perplexityOutputItemSchema = z2.union([
317
+ z2.looseObject({
318
+ type: z2.literal("message"),
319
+ id: z2.string().nullish(),
320
+ content: z2.array(perplexityContentPartSchema).nullish()
321
+ }),
322
+ z2.looseObject({
323
+ type: z2.literal("search_results"),
324
+ results: z2.array(perplexitySearchResultSchema).nullish()
325
+ }),
326
+ z2.looseObject({
327
+ type: z2.literal("fetch_url_results"),
328
+ contents: z2.array(perplexityFetchedContentSchema).nullish()
329
+ }),
330
+ z2.looseObject({
331
+ type: z2.literal("function_call"),
332
+ id: z2.string().nullish(),
333
+ call_id: z2.string().nullish(),
334
+ name: z2.string().nullish(),
335
+ arguments: z2.string().nullish(),
336
+ thought_signature: z2.string().nullish()
337
+ }),
338
+ // Native tool traces remain available in raw responses and raw stream chunks.
339
+ // Their fields (e.g. finance_results.results) have different shapes. Do not
340
+ // validate them as search results, or let malformed handled items fall back.
341
+ z2.object({
342
+ type: z2.string().refine((type) => !handledOutputTypes.includes(type))
343
+ }).transform(() => ({ type: "unhandled" }))
344
+ ]);
345
+ var perplexityCostSchema = z2.looseObject({
346
+ currency: z2.string().optional(),
347
+ input_cost: z2.number().optional(),
348
+ output_cost: z2.number().optional(),
349
+ total_cost: z2.number().optional(),
350
+ cache_creation_cost: z2.number().nullish(),
351
+ cache_read_cost: z2.number().nullish(),
352
+ tool_calls_cost: z2.number().nullish()
353
+ });
354
+ var perplexityUsageSchema = z2.looseObject({
355
+ input_tokens: z2.number(),
356
+ output_tokens: z2.number(),
357
+ total_tokens: z2.number(),
358
+ input_tokens_details: z2.looseObject({
359
+ cached_tokens: z2.number().optional(),
360
+ cache_creation_input_tokens: z2.number().optional(),
361
+ cache_read_input_tokens: z2.number().optional()
362
+ }).nullish(),
363
+ output_tokens_details: z2.looseObject({
364
+ reasoning_tokens: z2.number().optional()
365
+ }).nullish(),
366
+ tool_calls_details: z2.record(
367
+ z2.string(),
368
+ z2.looseObject({
369
+ invocation: z2.number().optional()
370
+ })
371
+ ).nullish(),
372
+ cost: perplexityCostSchema.nullish()
373
+ });
374
+ var perplexityAgentResponseSchema = z2.looseObject({
375
+ id: z2.string(),
376
+ created_at: z2.number(),
377
+ model: z2.string(),
378
+ object: z2.literal("response"),
379
+ output: z2.array(perplexityOutputItemSchema),
380
+ status: z2.string(),
381
+ incomplete_details: z2.looseObject({
382
+ reason: z2.string()
383
+ }).nullish(),
384
+ error: z2.looseObject({
385
+ code: z2.string().optional(),
386
+ message: z2.string(),
387
+ type: z2.string().optional()
388
+ }).nullish(),
389
+ usage: perplexityUsageSchema.nullish()
390
+ });
391
+ var perplexityAgentChunkSchema = z2.looseObject({
392
+ type: z2.string(),
393
+ sequence_number: z2.number().nullish(),
394
+ response: perplexityAgentResponseSchema.nullish(),
395
+ item: perplexityOutputItemSchema.nullish(),
396
+ output_index: z2.number().nullish(),
397
+ item_id: z2.string().nullish(),
398
+ content_index: z2.number().nullish(),
399
+ delta: z2.string().nullish(),
400
+ text: z2.string().nullish(),
401
+ thought: z2.string().nullish(),
402
+ queries: z2.array(z2.string()).nullish(),
403
+ urls: z2.array(z2.string()).nullish(),
404
+ results: z2.array(perplexitySearchResultSchema).nullish(),
405
+ contents: z2.array(perplexityFetchedContentSchema).nullish(),
406
+ error: z2.looseObject({
407
+ code: z2.string().nullish(),
408
+ message: z2.string(),
409
+ type: z2.string().nullish()
410
+ }).nullish()
411
+ });
412
+ var perplexityErrorSchema = z2.looseObject({
413
+ error: z2.union([
414
+ z2.string(),
415
+ z2.looseObject({
416
+ code: z2.union([z2.string(), z2.number()]).optional(),
417
+ message: z2.string().nullish(),
418
+ type: z2.string().nullish()
419
+ })
420
+ ]).optional(),
421
+ detail: z2.union([
422
+ z2.string(),
423
+ z2.array(
424
+ z2.looseObject({
425
+ msg: z2.string()
426
+ })
427
+ )
428
+ ]).optional(),
429
+ message: z2.string().optional()
430
+ });
431
+ function perplexityErrorToMessage(data) {
432
+ var _a, _b, _c;
433
+ if (typeof data.error === "string") {
434
+ return data.error;
197
435
  }
198
- if (part.data instanceof URL) {
199
- throw new UnsupportedFunctionalityError({
200
- functionality: `file of media type "${part.mediaType}" must specify subtype since it is not passed as inline bytes`
201
- });
436
+ if (data.error != null) {
437
+ return (_b = (_a = data.error.message) != null ? _a : data.error.type) != null ? _b : "unknown error";
202
438
  }
203
- if (isPdfData(part.data)) {
204
- return "application/pdf";
439
+ if (typeof data.detail === "string") {
440
+ return data.detail;
205
441
  }
206
- throw new UnsupportedFunctionalityError({
207
- functionality: `file of media type "${part.mediaType}" must specify subtype since it could not be auto-detected`
208
- });
209
- }
210
- function isPdfData(data) {
211
- const bytes = typeof data === "string" ? convertBase64ToUint8Array(data.substring(0, Math.min(data.length, 8))) : data;
212
- return bytes.length >= 4 && bytes[0] === 37 && bytes[1] === 80 && bytes[2] === 68 && bytes[3] === 70;
442
+ if (Array.isArray(data.detail)) {
443
+ return data.detail.map((detail) => detail.msg).join(", ");
444
+ }
445
+ return (_c = data.message) != null ? _c : "unknown error";
213
446
  }
214
447
 
215
- // src/map-perplexity-finish-reason.ts
216
- function mapPerplexityFinishReason(finishReason) {
217
- switch (finishReason) {
218
- case "stop":
219
- case "length":
220
- return finishReason;
221
- default:
222
- return "other";
448
+ // src/perplexity-language-model-options.ts
449
+ import { z as z3 } from "zod/v4";
450
+ var userLocationSchema = z3.looseObject({
451
+ latitude: z3.number().optional(),
452
+ longitude: z3.number().optional(),
453
+ country: z3.string().optional(),
454
+ city: z3.string().optional(),
455
+ region: z3.string().optional()
456
+ });
457
+ var webSearchFiltersSchema = z3.looseObject({
458
+ search_domain_filter: z3.array(z3.string()).optional(),
459
+ search_recency_filter: z3.enum(["hour", "day", "week", "month", "year"]).optional(),
460
+ search_after_date_filter: z3.string().optional(),
461
+ search_before_date_filter: z3.string().optional(),
462
+ last_updated_after_filter: z3.string().optional(),
463
+ last_updated_before_filter: z3.string().optional()
464
+ });
465
+ var webSearchToolSchema = z3.looseObject({
466
+ type: z3.literal("web_search"),
467
+ filters: webSearchFiltersSchema.optional(),
468
+ max_results: z3.number().int().positive().optional(),
469
+ max_tokens: z3.number().optional(),
470
+ max_tokens_per_page: z3.number().optional(),
471
+ search_context_size: z3.enum(["low", "medium", "high"]).optional(),
472
+ user_location: userLocationSchema.optional()
473
+ });
474
+ var nativeToolSchema = z3.union([
475
+ webSearchToolSchema,
476
+ z3.looseObject({
477
+ type: z3.literal("fetch_url"),
478
+ max_urls: z3.number().optional()
479
+ }),
480
+ z3.looseObject({ type: z3.literal("people_search") }),
481
+ z3.looseObject({ type: z3.literal("finance_search") }),
482
+ z3.looseObject({ type: z3.literal("sandbox") }),
483
+ z3.looseObject({
484
+ type: z3.literal("mcp"),
485
+ server_label: z3.string(),
486
+ server_url: z3.string(),
487
+ allowed_tools: z3.array(z3.string()).optional(),
488
+ authorization: z3.string().optional(),
489
+ defer_loading: z3.boolean().optional(),
490
+ headers: z3.record(z3.string(), z3.string()).optional()
491
+ }),
492
+ z3.looseObject({
493
+ type: z3.literal("connector"),
494
+ id: z3.string(),
495
+ server_label: z3.string(),
496
+ server_description: z3.string().optional(),
497
+ allowed_tools: z3.array(z3.string()).optional()
498
+ })
499
+ ]);
500
+ var perplexityLanguageModelOptions = z3.looseObject({
501
+ /** Top-level Agent API instructions. */
502
+ instructions: z3.string().optional(),
503
+ /**
504
+ * Native Agent API tools. AI SDK function tools can also be supplied through
505
+ * the top-level `tools` option on `generateText` and `streamText`.
506
+ */
507
+ tools: z3.array(nativeToolSchema).optional(),
508
+ /** A fallback model list for Agent API routing. */
509
+ models: z3.array(z3.string()).optional(),
510
+ /** Maximum number of agentic steps. */
511
+ max_steps: z3.number().int().positive().optional(),
512
+ /** Maximum number of native tool calls. */
513
+ max_tool_calls: z3.number().int().nonnegative().optional(),
514
+ /** Continue a conversation from an earlier Agent API response. */
515
+ previous_response_id: z3.string().optional(),
516
+ /**
517
+ * Whether the response can be retrieved later. Setting this to false does
518
+ * not disable persistence or prevent previous_response_id continuations.
519
+ */
520
+ store: z3.boolean().optional(),
521
+ /** Preferred response language as an ISO 639-1 language code. */
522
+ language_preference: z3.string().optional(),
523
+ /** Agent API reasoning configuration. */
524
+ reasoning: z3.looseObject({
525
+ effort: z3.enum(["minimal", "low", "medium", "high", "xhigh"]).optional()
526
+ }).optional(),
527
+ /** Agent API skill configuration. */
528
+ skills: z3.array(
529
+ z3.union([
530
+ z3.looseObject({
531
+ type: z3.literal("builtin"),
532
+ name: z3.enum([
533
+ "office",
534
+ "office/docx",
535
+ "office/pdf",
536
+ "office/pptx",
537
+ "office/xlsx"
538
+ ])
539
+ }),
540
+ z3.looseObject({
541
+ type: z3.literal("inline"),
542
+ name: z3.string(),
543
+ description: z3.string(),
544
+ instructions: z3.string()
545
+ })
546
+ ])
547
+ ).optional()
548
+ });
549
+
550
+ // src/perplexity-prepare-tools.ts
551
+ function preparePerplexityTools({
552
+ tools,
553
+ toolChoice
554
+ }) {
555
+ const preparedTools = [];
556
+ const warnings = [];
557
+ for (const tool of tools != null ? tools : []) {
558
+ if (tool.type === "provider") {
559
+ warnings.push({
560
+ type: "unsupported",
561
+ feature: `provider-defined tool ${tool.name}`
562
+ });
563
+ continue;
564
+ }
565
+ preparedTools.push({
566
+ type: "function",
567
+ name: tool.name,
568
+ description: tool.description,
569
+ parameters: tool.inputSchema,
570
+ strict: tool.strict
571
+ });
223
572
  }
573
+ if (toolChoice != null && toolChoice.type !== "auto") {
574
+ warnings.push({
575
+ type: "unsupported",
576
+ feature: "toolChoice",
577
+ details: "The Perplexity Agent API currently selects tools automatically."
578
+ });
579
+ }
580
+ return { tools: preparedTools, warnings };
224
581
  }
225
582
 
226
583
  // src/perplexity-language-model.ts
584
+ var presetIds = /* @__PURE__ */ new Set([
585
+ "fast",
586
+ "low",
587
+ "medium",
588
+ "high",
589
+ "xhigh"
590
+ ]);
591
+ function getModelSelection(modelId) {
592
+ if (presetIds.has(modelId)) {
593
+ return { preset: modelId };
594
+ }
595
+ return { model: modelId };
596
+ }
597
+ function getResponseMetadata(response) {
598
+ var _a, _b;
599
+ return {
600
+ id: (_a = response.id) != null ? _a : void 0,
601
+ modelId: (_b = response.model) != null ? _b : void 0,
602
+ timestamp: response.created_at != null ? new Date(response.created_at * 1e3) : void 0
603
+ };
604
+ }
605
+ function getProviderMetadata(usage) {
606
+ var _a, _b, _c, _d, _e, _f, _g;
607
+ const cost = usage == null ? void 0 : usage.cost;
608
+ const numSearchQueries = (usage == null ? void 0 : usage.tool_calls_details) ? Object.entries(usage.tool_calls_details).filter(([name]) => name.includes("search")).reduce((total, [, details]) => {
609
+ var _a2;
610
+ return total + ((_a2 = details.invocation) != null ? _a2 : 0);
611
+ }, 0) : null;
612
+ return {
613
+ perplexity: {
614
+ usage: {
615
+ citationTokens: null,
616
+ numSearchQueries
617
+ },
618
+ images: null,
619
+ cost: cost == null ? null : {
620
+ inputTokensCost: (_a = cost.input_cost) != null ? _a : null,
621
+ outputTokensCost: (_b = cost.output_cost) != null ? _b : null,
622
+ requestCost: null,
623
+ totalCost: (_c = cost.total_cost) != null ? _c : null,
624
+ currency: (_d = cost.currency) != null ? _d : null,
625
+ cacheCreationCost: (_e = cost.cache_creation_cost) != null ? _e : null,
626
+ cacheReadCost: (_f = cost.cache_read_cost) != null ? _f : null,
627
+ toolCallsCost: (_g = cost.tool_calls_cost) != null ? _g : null
628
+ },
629
+ toolCalls: (usage == null ? void 0 : usage.tool_calls_details) == null ? null : Object.fromEntries(
630
+ Object.entries(usage.tool_calls_details).map(
631
+ ([name, details]) => {
632
+ var _a2;
633
+ return [
634
+ name,
635
+ { invocation: (_a2 = details.invocation) != null ? _a2 : null }
636
+ ];
637
+ }
638
+ )
639
+ )
640
+ }
641
+ };
642
+ }
643
+ function createSource(result, generateId2) {
644
+ var _a, _b, _c, _d, _e;
645
+ return {
646
+ type: "source",
647
+ sourceType: "url",
648
+ id: result.id == null ? generateId2() : String(result.id),
649
+ url: result.url,
650
+ title: result.title,
651
+ providerMetadata: {
652
+ perplexity: {
653
+ resultId: (_a = result.id) != null ? _a : null,
654
+ snippet: (_b = result.snippet) != null ? _b : null,
655
+ date: (_c = result.date) != null ? _c : null,
656
+ lastUpdated: (_d = result.last_updated) != null ? _d : null,
657
+ source: (_e = result.source) != null ? _e : null
658
+ }
659
+ }
660
+ };
661
+ }
662
+ function hasSearchResultId(source) {
663
+ var _a, _b;
664
+ return typeof ((_b = (_a = source.providerMetadata) == null ? void 0 : _a.perplexity) == null ? void 0 : _b.resultId) === "number";
665
+ }
666
+ function getSearchResults(item) {
667
+ var _a;
668
+ return item.type === "search_results" ? (_a = item.results) != null ? _a : [] : [];
669
+ }
670
+ function getFetchedSources(item) {
671
+ var _a;
672
+ return item.type === "fetch_url_results" ? (_a = item.contents) != null ? _a : [] : [];
673
+ }
227
674
  var PerplexityLanguageModel = class {
228
675
  constructor(modelId, config) {
229
676
  this.specificationVersion = "v3";
230
677
  this.provider = "perplexity";
231
678
  this.supportedUrls = {
232
- // No URLs are supported.
679
+ "image/*": [/^https?:\/\/.*$/]
233
680
  };
234
681
  this.modelId = modelId;
235
682
  this.config = config;
236
683
  }
237
- getArgs({
684
+ async getArgs({
238
685
  prompt,
239
686
  maxOutputTokens,
240
687
  temperature,
@@ -245,85 +692,176 @@ var PerplexityLanguageModel = class {
245
692
  stopSequences,
246
693
  responseFormat,
247
694
  seed,
248
- providerOptions
695
+ providerOptions,
696
+ tools,
697
+ toolChoice
249
698
  }) {
250
- var _a;
699
+ var _a, _b;
251
700
  const warnings = [];
701
+ const perplexityOptions = (_a = await parseProviderOptions({
702
+ provider: "perplexity",
703
+ providerOptions,
704
+ schema: perplexityLanguageModelOptions
705
+ })) != null ? _a : {};
252
706
  if (topK != null) {
253
707
  warnings.push({ type: "unsupported", feature: "topK" });
254
708
  }
709
+ if (frequencyPenalty != null) {
710
+ warnings.push({ type: "unsupported", feature: "frequencyPenalty" });
711
+ }
712
+ if (presencePenalty != null) {
713
+ warnings.push({ type: "unsupported", feature: "presencePenalty" });
714
+ }
255
715
  if (stopSequences != null) {
256
716
  warnings.push({ type: "unsupported", feature: "stopSequences" });
257
717
  }
258
718
  if (seed != null) {
259
719
  warnings.push({ type: "unsupported", feature: "seed" });
260
720
  }
261
- return {
262
- args: {
263
- // model id:
264
- model: this.modelId,
265
- // standardized settings:
266
- frequency_penalty: frequencyPenalty,
267
- max_tokens: maxOutputTokens,
268
- presence_penalty: presencePenalty,
269
- temperature,
270
- top_k: topK,
271
- top_p: topP,
272
- // response format:
273
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? {
274
- type: "json_schema",
275
- json_schema: { schema: responseFormat.schema }
276
- } : void 0,
277
- // provider extensions
278
- ...(_a = providerOptions == null ? void 0 : providerOptions.perplexity) != null ? _a : {},
279
- // messages:
280
- messages: convertToPerplexityMessages(prompt)
281
- },
282
- warnings
721
+ const { tools: nativeTools, ...agentOptions } = perplexityOptions;
722
+ const modelSelection = getModelSelection(this.modelId);
723
+ const { input, warnings: inputWarnings } = convertToPerplexityInput(prompt);
724
+ warnings.push(...inputWarnings);
725
+ const { tools: functionTools, warnings: toolWarnings } = preparePerplexityTools({ tools, toolChoice });
726
+ warnings.push(...toolWarnings);
727
+ const agentTools = [
728
+ ...nativeTools != null ? nativeTools : [],
729
+ ...functionTools
730
+ ];
731
+ const body = {
732
+ ...agentOptions,
733
+ ...modelSelection,
734
+ input,
735
+ max_output_tokens: maxOutputTokens,
736
+ temperature,
737
+ top_p: topP,
738
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
739
+ type: "json_schema",
740
+ json_schema: {
741
+ name: (_b = responseFormat.name) != null ? _b : "response",
742
+ description: responseFormat.description,
743
+ schema: responseFormat.schema,
744
+ strict: true
745
+ }
746
+ } : void 0,
747
+ tools: agentTools.length > 0 ? agentTools : void 0
283
748
  };
749
+ if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema == null) {
750
+ warnings.push({
751
+ type: "unsupported",
752
+ feature: "JSON response format without a schema"
753
+ });
754
+ }
755
+ return { args: body, warnings };
284
756
  }
285
757
  async doGenerate(options) {
286
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
287
- const { args: body, warnings } = this.getArgs(options);
758
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
759
+ const { args: body, warnings } = await this.getArgs(options);
760
+ const url = `${this.config.baseURL}/v1/agent`;
288
761
  const {
289
762
  responseHeaders,
290
763
  value: response,
291
764
  rawValue: rawResponse
292
765
  } = await postJsonToApi({
293
- url: `${this.config.baseURL}/chat/completions`,
294
- headers: combineHeaders(this.config.headers(), options.headers),
766
+ url,
767
+ headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
295
768
  body,
296
769
  failedResponseHandler: createJsonErrorResponseHandler({
297
770
  errorSchema: perplexityErrorSchema,
298
- errorToMessage
771
+ errorToMessage: perplexityErrorToMessage
299
772
  }),
300
773
  successfulResponseHandler: createJsonResponseHandler(
301
- perplexityResponseSchema
774
+ perplexityAgentResponseSchema
302
775
  ),
303
776
  abortSignal: options.abortSignal,
304
777
  fetch: this.config.fetch
305
778
  });
306
- const choice = response.choices[0];
307
- const content = [];
308
- const text = choice.message.content;
309
- if (text.length > 0) {
310
- content.push({ type: "text", text });
779
+ if (response.error != null || response.status === "failed") {
780
+ throw new APICallError({
781
+ message: (_d = (_c = response.error) == null ? void 0 : _c.message) != null ? _d : "Perplexity response failed",
782
+ url,
783
+ requestBodyValues: body,
784
+ statusCode: 400,
785
+ responseHeaders,
786
+ responseBody: rawResponse,
787
+ isRetryable: false
788
+ });
311
789
  }
312
- if (response.citations != null) {
313
- for (const url of response.citations) {
790
+ const content = [];
791
+ const sourceIndexesByUrl = /* @__PURE__ */ new Map();
792
+ let hasFunctionCall = false;
793
+ const addSource = (source) => {
794
+ const existingIndex = sourceIndexesByUrl.get(source.url);
795
+ if (existingIndex == null) {
796
+ sourceIndexesByUrl.set(source.url, content.length);
797
+ content.push(source);
798
+ } else if (hasSearchResultId(source) && !hasSearchResultId(content[existingIndex])) {
799
+ content[existingIndex] = source;
800
+ }
801
+ };
802
+ for (const item of response.output) {
803
+ if (item.type === "message") {
804
+ for (const part of (_e = item.content) != null ? _e : []) {
805
+ if (part.type === "output_text" && part.text != null) {
806
+ content.push({ type: "text", text: part.text });
807
+ }
808
+ for (const annotation of (_f = part.annotations) != null ? _f : []) {
809
+ if (annotation.url != null) {
810
+ addSource({
811
+ type: "source",
812
+ sourceType: "url",
813
+ id: this.config.generateId(),
814
+ url: annotation.url,
815
+ title: annotation.title
816
+ });
817
+ }
818
+ }
819
+ }
820
+ } else if (item.type === "search_results") {
821
+ for (const result of getSearchResults(item)) {
822
+ addSource(createSource(result, this.config.generateId));
823
+ }
824
+ } else if (item.type === "fetch_url_results") {
825
+ for (const result of getFetchedSources(item)) {
826
+ addSource({
827
+ type: "source",
828
+ sourceType: "url",
829
+ id: this.config.generateId(),
830
+ url: result.url,
831
+ title: result.title,
832
+ providerMetadata: {
833
+ perplexity: { snippet: (_g = result.snippet) != null ? _g : null }
834
+ }
835
+ });
836
+ }
837
+ } else if (item.type === "function_call" && item.call_id != null && item.name != null && item.arguments != null) {
838
+ hasFunctionCall = true;
314
839
  content.push({
315
- type: "source",
316
- sourceType: "url",
317
- id: this.config.generateId(),
318
- url
840
+ type: "tool-call",
841
+ toolCallId: item.call_id,
842
+ toolName: item.name,
843
+ input: item.arguments,
844
+ providerMetadata: {
845
+ perplexity: {
846
+ itemId: (_h = item.id) != null ? _h : null,
847
+ ...item.thought_signature != null && {
848
+ thoughtSignature: item.thought_signature
849
+ }
850
+ }
851
+ }
319
852
  });
320
853
  }
321
854
  }
855
+ const finishReason = (_j = (_i = response.incomplete_details) == null ? void 0 : _i.reason) != null ? _j : response.status;
322
856
  return {
323
857
  content,
324
858
  finishReason: {
325
- unified: mapPerplexityFinishReason(choice.finish_reason),
326
- raw: (_a = choice.finish_reason) != null ? _a : void 0
859
+ unified: mapPerplexityFinishReason({
860
+ status: response.status,
861
+ incompleteReason: (_k = response.incomplete_details) == null ? void 0 : _k.reason,
862
+ hasFunctionCall
863
+ }),
864
+ raw: finishReason
327
865
  },
328
866
  usage: convertPerplexityUsage(response.usage),
329
867
  request: { body },
@@ -333,41 +871,23 @@ var PerplexityLanguageModel = class {
333
871
  body: rawResponse
334
872
  },
335
873
  warnings,
336
- providerMetadata: {
337
- perplexity: {
338
- images: (_c = (_b = response.images) == null ? void 0 : _b.map((image) => ({
339
- imageUrl: image.image_url,
340
- originUrl: image.origin_url,
341
- height: image.height,
342
- width: image.width
343
- }))) != null ? _c : null,
344
- usage: {
345
- citationTokens: (_e = (_d = response.usage) == null ? void 0 : _d.citation_tokens) != null ? _e : null,
346
- numSearchQueries: (_g = (_f = response.usage) == null ? void 0 : _f.num_search_queries) != null ? _g : null
347
- },
348
- cost: ((_h = response.usage) == null ? void 0 : _h.cost) ? {
349
- inputTokensCost: (_i = response.usage.cost.input_tokens_cost) != null ? _i : null,
350
- outputTokensCost: (_j = response.usage.cost.output_tokens_cost) != null ? _j : null,
351
- requestCost: (_k = response.usage.cost.request_cost) != null ? _k : null,
352
- totalCost: (_l = response.usage.cost.total_cost) != null ? _l : null
353
- } : null
354
- }
355
- }
874
+ providerMetadata: getProviderMetadata(response.usage)
356
875
  };
357
876
  }
358
877
  async doStream(options) {
359
- const { args, warnings } = this.getArgs(options);
878
+ var _a, _b;
879
+ const { args, warnings } = await this.getArgs(options);
360
880
  const body = { ...args, stream: true };
361
881
  const { responseHeaders, value: response } = await postJsonToApi({
362
- url: `${this.config.baseURL}/chat/completions`,
363
- headers: combineHeaders(this.config.headers(), options.headers),
882
+ url: `${this.config.baseURL}/v1/agent`,
883
+ headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
364
884
  body,
365
885
  failedResponseHandler: createJsonErrorResponseHandler({
366
886
  errorSchema: perplexityErrorSchema,
367
- errorToMessage
887
+ errorToMessage: perplexityErrorToMessage
368
888
  }),
369
889
  successfulResponseHandler: createEventSourceResponseHandler(
370
- perplexityChunkSchema
890
+ perplexityAgentChunkSchema
371
891
  ),
372
892
  abortSignal: options.abortSignal,
373
893
  fetch: this.config.fetch
@@ -376,20 +896,15 @@ var PerplexityLanguageModel = class {
376
896
  unified: "other",
377
897
  raw: void 0
378
898
  };
379
- let usage = void 0;
380
- const providerMetadata = {
381
- perplexity: {
382
- usage: {
383
- citationTokens: null,
384
- numSearchQueries: null
385
- },
386
- cost: null,
387
- images: null
388
- }
389
- };
390
- let isFirstChunk = true;
391
- let isActive = false;
392
- const self = this;
899
+ let usage;
900
+ let hasFunctionCall = false;
901
+ let hasResponseMetadata = false;
902
+ let activeReasoningId;
903
+ const textStates = /* @__PURE__ */ new Map();
904
+ const emittedSourceUrls = /* @__PURE__ */ new Set();
905
+ const pendingSourcesByUrl = /* @__PURE__ */ new Map();
906
+ const seenFunctionCalls = /* @__PURE__ */ new Set();
907
+ const generateId2 = this.config.generateId;
393
908
  return {
394
909
  stream: response.pipeThrough(
395
910
  new TransformStream({
@@ -397,84 +912,308 @@ var PerplexityLanguageModel = class {
397
912
  controller.enqueue({ type: "stream-start", warnings });
398
913
  },
399
914
  transform(chunk, controller) {
400
- var _a, _b, _c, _d, _e, _f, _g;
915
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
401
916
  if (options.includeRawChunks) {
402
917
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
403
918
  }
404
919
  if (!chunk.success) {
920
+ finishReason = { unified: "error", raw: void 0 };
405
921
  controller.enqueue({ type: "error", error: chunk.error });
406
922
  return;
407
923
  }
408
924
  const value = chunk.value;
409
- if (isFirstChunk) {
925
+ const getTextId = (itemId, outputIndex, contentIndex = 0) => {
926
+ const id = itemId != null ? itemId : String(outputIndex != null ? outputIndex : "text");
927
+ return contentIndex == null || contentIndex === 0 ? id : `${id}:${contentIndex}`;
928
+ };
929
+ const emitTextDelta = (id, delta) => {
930
+ let state = textStates.get(id);
931
+ if (state == null ? void 0 : state.ended) {
932
+ return;
933
+ }
934
+ if (state == null) {
935
+ state = { text: "", ended: false };
936
+ textStates.set(id, state);
937
+ controller.enqueue({ type: "text-start", id });
938
+ }
939
+ state.text += delta;
940
+ controller.enqueue({ type: "text-delta", id, delta });
941
+ };
942
+ const finishText = (id, text) => {
943
+ var _a3;
944
+ const state = textStates.get(id);
945
+ if (state == null ? void 0 : state.ended) {
946
+ return;
947
+ }
948
+ const emittedText = (_a3 = state == null ? void 0 : state.text) != null ? _a3 : "";
949
+ if (text != null && text.startsWith(emittedText) && text.length > emittedText.length) {
950
+ emitTextDelta(id, text.slice(emittedText.length));
951
+ }
952
+ const finalState = textStates.get(id);
953
+ if (finalState != null) {
954
+ finalState.ended = true;
955
+ controller.enqueue({ type: "text-end", id });
956
+ }
957
+ };
958
+ const finishOutputText = (item, outputIndex) => {
959
+ var _a3;
960
+ if (item.type === "message") {
961
+ for (const [contentIndex, part] of ((_a3 = item.content) != null ? _a3 : []).entries()) {
962
+ if (part.type === "output_text") {
963
+ finishText(
964
+ getTextId(item.id, outputIndex, contentIndex),
965
+ part.text
966
+ );
967
+ }
968
+ }
969
+ }
970
+ };
971
+ const emitSource = (source) => {
972
+ if (emittedSourceUrls.has(source.url)) {
973
+ return;
974
+ }
975
+ if (hasSearchResultId(source)) {
976
+ pendingSourcesByUrl.delete(source.url);
977
+ emittedSourceUrls.add(source.url);
978
+ controller.enqueue(source);
979
+ } else if (!pendingSourcesByUrl.has(source.url)) {
980
+ pendingSourcesByUrl.set(source.url, source);
981
+ }
982
+ };
983
+ const emitReasoningThought = (thought) => {
984
+ if (activeReasoningId != null && thought != null) {
985
+ controller.enqueue({
986
+ type: "reasoning-delta",
987
+ id: activeReasoningId,
988
+ delta: thought
989
+ });
990
+ }
991
+ };
992
+ const emitFunctionCall = (item) => {
993
+ var _a3;
994
+ if (item.type !== "function_call" || item.call_id == null || item.name == null || item.arguments == null || seenFunctionCalls.has(item.call_id)) {
995
+ return;
996
+ }
997
+ seenFunctionCalls.add(item.call_id);
998
+ hasFunctionCall = true;
410
999
  controller.enqueue({
411
- type: "response-metadata",
412
- ...getResponseMetadata(value)
1000
+ type: "tool-input-start",
1001
+ id: item.call_id,
1002
+ toolName: item.name
413
1003
  });
414
- (_a = value.citations) == null ? void 0 : _a.forEach((url) => {
415
- controller.enqueue({
1004
+ controller.enqueue({
1005
+ type: "tool-input-delta",
1006
+ id: item.call_id,
1007
+ delta: item.arguments
1008
+ });
1009
+ controller.enqueue({ type: "tool-input-end", id: item.call_id });
1010
+ controller.enqueue({
1011
+ type: "tool-call",
1012
+ toolCallId: item.call_id,
1013
+ toolName: item.name,
1014
+ input: item.arguments,
1015
+ providerMetadata: {
1016
+ perplexity: {
1017
+ itemId: (_a3 = item.id) != null ? _a3 : null,
1018
+ ...item.thought_signature != null && {
1019
+ thoughtSignature: item.thought_signature
1020
+ }
1021
+ }
1022
+ }
1023
+ });
1024
+ };
1025
+ const emitOutputSources = (item) => {
1026
+ var _a3, _b3, _c2;
1027
+ if (item.type === "message") {
1028
+ for (const part of (_a3 = item.content) != null ? _a3 : []) {
1029
+ for (const annotation of (_b3 = part.annotations) != null ? _b3 : []) {
1030
+ if (annotation.url != null) {
1031
+ emitSource({
1032
+ type: "source",
1033
+ sourceType: "url",
1034
+ id: generateId2(),
1035
+ url: annotation.url,
1036
+ title: annotation.title
1037
+ });
1038
+ }
1039
+ }
1040
+ }
1041
+ }
1042
+ for (const result of getSearchResults(item)) {
1043
+ emitSource(createSource(result, generateId2));
1044
+ }
1045
+ for (const result of getFetchedSources(item)) {
1046
+ emitSource({
416
1047
  type: "source",
417
1048
  sourceType: "url",
418
- id: self.config.generateId(),
419
- url
1049
+ id: generateId2(),
1050
+ url: result.url,
1051
+ title: result.title,
1052
+ providerMetadata: {
1053
+ perplexity: { snippet: (_c2 = result.snippet) != null ? _c2 : null }
1054
+ }
420
1055
  });
421
- });
422
- isFirstChunk = false;
423
- }
424
- if (value.usage != null) {
425
- usage = value.usage;
426
- providerMetadata.perplexity.usage = {
427
- citationTokens: (_b = value.usage.citation_tokens) != null ? _b : null,
428
- numSearchQueries: (_c = value.usage.num_search_queries) != null ? _c : null
429
- };
430
- providerMetadata.perplexity.cost = value.usage.cost ? {
431
- inputTokensCost: (_d = value.usage.cost.input_tokens_cost) != null ? _d : null,
432
- outputTokensCost: (_e = value.usage.cost.output_tokens_cost) != null ? _e : null,
433
- requestCost: (_f = value.usage.cost.request_cost) != null ? _f : null,
434
- totalCost: (_g = value.usage.cost.total_cost) != null ? _g : null
435
- } : null;
436
- }
437
- if (value.images != null) {
438
- providerMetadata.perplexity.images = value.images.map((image) => ({
439
- imageUrl: image.image_url,
440
- originUrl: image.origin_url,
441
- height: image.height,
442
- width: image.width
443
- }));
444
- }
445
- const choice = value.choices[0];
446
- if ((choice == null ? void 0 : choice.finish_reason) != null) {
447
- finishReason = {
448
- unified: mapPerplexityFinishReason(choice.finish_reason),
449
- raw: choice.finish_reason
450
- };
1056
+ }
1057
+ };
1058
+ switch (value.type) {
1059
+ case "response.created":
1060
+ case "response.in_progress": {
1061
+ if (!hasResponseMetadata && value.response != null) {
1062
+ controller.enqueue({
1063
+ type: "response-metadata",
1064
+ ...getResponseMetadata(value.response)
1065
+ });
1066
+ hasResponseMetadata = true;
1067
+ }
1068
+ break;
1069
+ }
1070
+ case "response.output_text.delta": {
1071
+ if (value.delta != null) {
1072
+ emitTextDelta(
1073
+ getTextId(
1074
+ value.item_id,
1075
+ value.output_index,
1076
+ value.content_index
1077
+ ),
1078
+ value.delta
1079
+ );
1080
+ }
1081
+ break;
1082
+ }
1083
+ case "response.output_text.done": {
1084
+ finishText(
1085
+ getTextId(
1086
+ value.item_id,
1087
+ value.output_index,
1088
+ value.content_index
1089
+ ),
1090
+ value.text
1091
+ );
1092
+ break;
1093
+ }
1094
+ case "response.reasoning.started": {
1095
+ if (activeReasoningId != null) {
1096
+ controller.enqueue({
1097
+ type: "reasoning-end",
1098
+ id: activeReasoningId
1099
+ });
1100
+ }
1101
+ activeReasoningId = `reasoning-${(_a2 = value.sequence_number) != null ? _a2 : generateId2()}`;
1102
+ controller.enqueue({
1103
+ type: "reasoning-start",
1104
+ id: activeReasoningId
1105
+ });
1106
+ emitReasoningThought(value.thought);
1107
+ break;
1108
+ }
1109
+ case "response.reasoning.search_queries":
1110
+ case "response.reasoning.fetch_url_queries": {
1111
+ emitReasoningThought(value.thought);
1112
+ break;
1113
+ }
1114
+ case "response.reasoning.search_results": {
1115
+ emitReasoningThought(value.thought);
1116
+ for (const result of (_b2 = value.results) != null ? _b2 : []) {
1117
+ emitSource(createSource(result, generateId2));
1118
+ }
1119
+ break;
1120
+ }
1121
+ case "response.reasoning.fetch_url_results": {
1122
+ emitReasoningThought(value.thought);
1123
+ for (const result of (_c = value.contents) != null ? _c : []) {
1124
+ emitSource({
1125
+ type: "source",
1126
+ sourceType: "url",
1127
+ id: generateId2(),
1128
+ url: result.url,
1129
+ title: result.title,
1130
+ providerMetadata: {
1131
+ perplexity: { snippet: (_d = result.snippet) != null ? _d : null }
1132
+ }
1133
+ });
1134
+ }
1135
+ break;
1136
+ }
1137
+ case "response.reasoning.stopped": {
1138
+ emitReasoningThought(value.thought);
1139
+ if (activeReasoningId != null) {
1140
+ controller.enqueue({
1141
+ type: "reasoning-end",
1142
+ id: activeReasoningId
1143
+ });
1144
+ activeReasoningId = void 0;
1145
+ }
1146
+ break;
1147
+ }
1148
+ case "response.output_item.done": {
1149
+ if (value.item != null) {
1150
+ finishOutputText(value.item, value.output_index);
1151
+ emitOutputSources(value.item);
1152
+ emitFunctionCall(value.item);
1153
+ }
1154
+ break;
1155
+ }
1156
+ case "response.completed":
1157
+ case "response.incomplete": {
1158
+ if (value.response != null) {
1159
+ if (!hasResponseMetadata) {
1160
+ controller.enqueue({
1161
+ type: "response-metadata",
1162
+ ...getResponseMetadata(value.response)
1163
+ });
1164
+ hasResponseMetadata = true;
1165
+ }
1166
+ for (const [
1167
+ outputIndex,
1168
+ item
1169
+ ] of value.response.output.entries()) {
1170
+ finishOutputText(item, outputIndex);
1171
+ emitOutputSources(item);
1172
+ emitFunctionCall(item);
1173
+ }
1174
+ usage = (_e = value.response.usage) != null ? _e : void 0;
1175
+ const rawFinishReason = (_g = (_f = value.response.incomplete_details) == null ? void 0 : _f.reason) != null ? _g : value.response.status;
1176
+ finishReason = {
1177
+ unified: mapPerplexityFinishReason({
1178
+ status: value.response.status,
1179
+ incompleteReason: (_h = value.response.incomplete_details) == null ? void 0 : _h.reason,
1180
+ hasFunctionCall
1181
+ }),
1182
+ raw: rawFinishReason
1183
+ };
1184
+ }
1185
+ break;
1186
+ }
1187
+ case "response.failed": {
1188
+ finishReason = { unified: "error", raw: "failed" };
1189
+ controller.enqueue({
1190
+ type: "error",
1191
+ error: (_i = value.error) != null ? _i : new Error("Perplexity response failed")
1192
+ });
1193
+ break;
1194
+ }
451
1195
  }
452
- if ((choice == null ? void 0 : choice.delta) == null) {
453
- return;
1196
+ },
1197
+ flush(controller) {
1198
+ for (const source of pendingSourcesByUrl.values()) {
1199
+ controller.enqueue(source);
454
1200
  }
455
- const delta = choice.delta;
456
- const textContent = delta.content;
457
- if (textContent != null) {
458
- if (!isActive) {
459
- controller.enqueue({ type: "text-start", id: "0" });
460
- isActive = true;
461
- }
1201
+ if (activeReasoningId != null) {
462
1202
  controller.enqueue({
463
- type: "text-delta",
464
- id: "0",
465
- delta: textContent
1203
+ type: "reasoning-end",
1204
+ id: activeReasoningId
466
1205
  });
467
1206
  }
468
- },
469
- flush(controller) {
470
- if (isActive) {
471
- controller.enqueue({ type: "text-end", id: "0" });
1207
+ for (const [id, state] of textStates) {
1208
+ if (!state.ended) {
1209
+ controller.enqueue({ type: "text-end", id });
1210
+ }
472
1211
  }
473
1212
  controller.enqueue({
474
1213
  type: "finish",
475
1214
  finishReason,
476
1215
  usage: convertPerplexityUsage(usage),
477
- providerMetadata
1216
+ providerMetadata: getProviderMetadata(usage)
478
1217
  });
479
1218
  }
480
1219
  })
@@ -484,87 +1223,6 @@ var PerplexityLanguageModel = class {
484
1223
  };
485
1224
  }
486
1225
  };
487
- function getResponseMetadata({
488
- id,
489
- model,
490
- created
491
- }) {
492
- return {
493
- id,
494
- modelId: model,
495
- timestamp: new Date(created * 1e3)
496
- };
497
- }
498
- var perplexityCostSchema = z2.object({
499
- input_tokens_cost: z2.number().nullish(),
500
- output_tokens_cost: z2.number().nullish(),
501
- reasoning_tokens_cost: z2.number().nullish(),
502
- request_cost: z2.number().nullish(),
503
- citation_tokens_cost: z2.number().nullish(),
504
- search_queries_cost: z2.number().nullish(),
505
- total_cost: z2.number().nullish()
506
- }).catchall(z2.json());
507
- var perplexityUsageSchema = z2.object({
508
- prompt_tokens: z2.number(),
509
- completion_tokens: z2.number(),
510
- total_tokens: z2.number().nullish(),
511
- search_context_size: z2.enum(["low", "medium", "high"]).nullish(),
512
- citation_tokens: z2.number().nullish(),
513
- num_search_queries: z2.number().nullish(),
514
- reasoning_tokens: z2.number().nullish(),
515
- cost: perplexityCostSchema.nullish()
516
- }).catchall(z2.json());
517
- var perplexityImageSchema = z2.object({
518
- image_url: z2.string(),
519
- origin_url: z2.string(),
520
- height: z2.number(),
521
- width: z2.number()
522
- });
523
- var perplexityResponseSchema = z2.object({
524
- id: z2.string(),
525
- created: z2.number(),
526
- model: z2.string(),
527
- choices: z2.array(
528
- z2.object({
529
- message: z2.object({
530
- role: z2.literal("assistant"),
531
- content: z2.string()
532
- }),
533
- finish_reason: z2.string().nullish()
534
- })
535
- ),
536
- citations: z2.array(z2.string()).nullish(),
537
- images: z2.array(perplexityImageSchema).nullish(),
538
- usage: perplexityUsageSchema.nullish()
539
- });
540
- var perplexityChunkSchema = z2.object({
541
- id: z2.string(),
542
- created: z2.number(),
543
- model: z2.string(),
544
- choices: z2.array(
545
- z2.object({
546
- delta: z2.object({
547
- role: z2.literal("assistant").optional(),
548
- content: z2.string().nullish()
549
- }),
550
- finish_reason: z2.string().nullish()
551
- })
552
- ),
553
- citations: z2.array(z2.string()).nullish(),
554
- images: z2.array(perplexityImageSchema).nullish(),
555
- usage: perplexityUsageSchema.nullish()
556
- });
557
- var perplexityErrorSchema = z2.object({
558
- error: z2.object({
559
- code: z2.number(),
560
- message: z2.string().nullish(),
561
- type: z2.string().nullish()
562
- })
563
- });
564
- var errorToMessage = (data) => {
565
- var _a, _b;
566
- return (_b = (_a = data.error.message) != null ? _a : data.error.type) != null ? _b : "unknown error";
567
- };
568
1226
 
569
1227
  // src/perplexity-embedding-model.ts
570
1228
  var PerplexityEmbeddingModel = class {
@@ -594,7 +1252,7 @@ var PerplexityEmbeddingModel = class {
594
1252
  values
595
1253
  });
596
1254
  }
597
- const perplexityOptions = (_a = await parseProviderOptions({
1255
+ const perplexityOptions = (_a = await parseProviderOptions2({
598
1256
  provider: "perplexity",
599
1257
  providerOptions,
600
1258
  schema: perplexityEmbeddingModelOptions
@@ -615,10 +1273,7 @@ var PerplexityEmbeddingModel = class {
615
1273
  },
616
1274
  failedResponseHandler: createJsonErrorResponseHandler2({
617
1275
  errorSchema: perplexityErrorSchema,
618
- errorToMessage: (data) => {
619
- var _a2;
620
- return (_a2 = data.error.message) != null ? _a2 : "Unknown error";
621
- }
1276
+ errorToMessage: perplexityErrorToMessage
622
1277
  }),
623
1278
  successfulResponseHandler: createJsonResponseHandler2(
624
1279
  perplexityEmbeddingResponseSchema
@@ -647,7 +1302,7 @@ var PerplexityEmbeddingModel = class {
647
1302
  }
648
1303
  };
649
1304
  function decodeEmbedding(base64, encodingFormat) {
650
- const bytes = convertBase64ToUint8Array2(base64);
1305
+ const bytes = convertBase64ToUint8Array(base64);
651
1306
  if (encodingFormat === "base64_int8") {
652
1307
  const int8 = new Int8Array(
653
1308
  bytes.buffer,
@@ -658,20 +1313,20 @@ function decodeEmbedding(base64, encodingFormat) {
658
1313
  }
659
1314
  return Array.from(bytes);
660
1315
  }
661
- var perplexityEmbeddingResponseSchema = z3.object({
662
- data: z3.array(z3.object({ embedding: z3.string() })),
663
- usage: z3.object({
664
- prompt_tokens: z3.number(),
665
- cost: z3.object({
666
- input_cost: z3.number().nullish(),
667
- total_cost: z3.number().nullish(),
668
- currency: z3.string().nullish()
1316
+ var perplexityEmbeddingResponseSchema = z4.object({
1317
+ data: z4.array(z4.object({ embedding: z4.string() })),
1318
+ usage: z4.object({
1319
+ prompt_tokens: z4.number(),
1320
+ cost: z4.object({
1321
+ input_cost: z4.number().nullish(),
1322
+ total_cost: z4.number().nullish(),
1323
+ currency: z4.string().nullish()
669
1324
  }).nullish()
670
1325
  }).nullish()
671
1326
  });
672
1327
 
673
1328
  // src/version.ts
674
- var VERSION = true ? "3.0.62" : "0.0.0-test";
1329
+ var VERSION = true ? "3.1.0" : "0.0.0-test";
675
1330
 
676
1331
  // src/perplexity-provider.ts
677
1332
  function createPerplexity(options = {}) {