@ai-sdk/perplexity 2.1.0-beta.9 → 2.1.1

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