@ai-sdk/perplexity 3.0.63 → 3.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.
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  title: Perplexity
3
- description: Learn how to use Perplexity's Sonar API with the AI SDK.
3
+ description: Learn how to use Perplexity's Agent API with the AI SDK.
4
4
  ---
5
5
 
6
6
  # Perplexity Provider
7
7
 
8
- The [Perplexity](https://sonar.perplexity.ai) provider offers access to Sonar API - a language model that uniquely combines real-time web search with natural language processing. Each response is grounded in current web data and includes detailed citations, making it ideal for research, fact-checking, and obtaining up-to-date information.
8
+ The [Perplexity](https://www.perplexity.ai) provider offers access to the
9
+ [Agent API](https://docs.perplexity.ai/docs/agent-api/quickstart). The Agent API
10
+ can route across models, search the web, call tools, and return cited answers.
9
11
 
10
12
  API keys can be obtained from the [Perplexity Platform](https://docs.perplexity.ai).
11
13
 
@@ -76,11 +78,20 @@ import { perplexity } from '@ai-sdk/perplexity';
76
78
  import { generateText } from 'ai';
77
79
 
78
80
  const { text } = await generateText({
79
- model: perplexity('sonar-pro'),
81
+ model: perplexity('low'),
80
82
  prompt: 'What are the latest developments in quantum computing?',
81
83
  });
82
84
  ```
83
85
 
86
+ The Agent API provides the `fast`, `low`, `medium`, `high`, and `xhigh`
87
+ presets. You can also pass an Agent API model ID directly, such as
88
+ `perplexity/sonar`.
89
+
90
+ Starting with version 3.1.0, language generation uses the Agent API
91
+ exclusively. Legacy Sonar model IDs and provider options are not mapped; see
92
+ [Migrating from Sonar to the Agent API](#migrating-from-sonar-to-the-agent-api)
93
+ before upgrading.
94
+
84
95
  ### Sources
85
96
 
86
97
  Websites that have been used to generate the response are included in the `sources` property of the result:
@@ -90,27 +101,101 @@ import { perplexity } from '@ai-sdk/perplexity';
90
101
  import { generateText } from 'ai';
91
102
 
92
103
  const { text, sources } = await generateText({
93
- model: perplexity('sonar-pro'),
104
+ model: perplexity('low'),
94
105
  prompt: 'What are the latest developments in quantum computing?',
95
106
  });
96
107
 
97
108
  console.log(sources);
98
109
  ```
99
110
 
100
- ### Provider Options & Metadata
111
+ ### Agent Tools
112
+
113
+ Pass native Agent API tools through `providerOptions.perplexity.tools`:
114
+
115
+ ```ts
116
+ import {
117
+ perplexity,
118
+ type PerplexityLanguageModelOptions,
119
+ } from '@ai-sdk/perplexity';
120
+ import { generateText } from 'ai';
121
+
122
+ const { text, sources } = await generateText({
123
+ model: perplexity('low'),
124
+ prompt: 'Summarize recent US federal AI policy from official sources.',
125
+ providerOptions: {
126
+ perplexity: {
127
+ tools: [
128
+ {
129
+ type: 'web_search',
130
+ filters: {
131
+ search_domain_filter: [
132
+ 'whitehouse.gov',
133
+ 'congress.gov',
134
+ 'federalregister.gov',
135
+ ],
136
+ search_recency_filter: 'month',
137
+ },
138
+ max_results: 10,
139
+ search_context_size: 'medium',
140
+ },
141
+ ],
142
+ } satisfies PerplexityLanguageModelOptions,
143
+ },
144
+ });
145
+ ```
146
+
147
+ Supported native tools are `web_search`, `fetch_url`, `people_search`,
148
+ `finance_search`, `sandbox`, `mcp`, and `connector`. Agent API presets include
149
+ preconfigured tools that remain enabled; the `tools` option can add explicit
150
+ tools or supply tools when using a direct model ID.
151
+
152
+ Search and fetch results are exposed as AI SDK sources. Other native tool traces,
153
+ including finance, sandbox, and MCP results, are available in `response.body`
154
+ and raw stream chunks (`includeRawChunks: true`). They are not exposed as
155
+ AI SDK client tool calls. Accounts with zero data retention may reject
156
+ file-capable tools such as `finance_search` and `sandbox`.
157
+
158
+ AI SDK function tools can be passed through the top-level `tools` option:
159
+
160
+ ```ts
161
+ import { perplexity } from '@ai-sdk/perplexity';
162
+ import { generateText, tool } from 'ai';
163
+ import { z } from 'zod';
164
+
165
+ const result = await generateText({
166
+ model: perplexity('low'),
167
+ prompt: 'What is the weather in San Francisco?',
168
+ tools: {
169
+ weather: tool({
170
+ description: 'Get the weather for a city',
171
+ inputSchema: z.object({ city: z.string() }),
172
+ execute: async ({ city }) => ({ city, temperature: 18 }),
173
+ }),
174
+ },
175
+ });
176
+ ```
177
+
178
+ ### Provider Options and Metadata
101
179
 
102
180
  The Perplexity provider includes additional metadata in the response through `providerMetadata`.
103
181
  Additional configuration options are available through `providerOptions`.
104
182
 
105
183
  ```ts
184
+ import {
185
+ perplexity,
186
+ type PerplexityLanguageModelOptions,
187
+ } from '@ai-sdk/perplexity';
188
+ import { generateText } from 'ai';
189
+
106
190
  const result = await generateText({
107
- model: perplexity('sonar-pro'),
191
+ model: perplexity('low'),
108
192
  prompt: 'What are the latest developments in quantum computing?',
109
193
  providerOptions: {
110
194
  perplexity: {
111
- return_images: true, // Enable image responses (Tier-2 Perplexity users only)
112
- search_recency_filter: 'week', // Filter search results by recency
113
- },
195
+ max_steps: 5,
196
+ store: true,
197
+ reasoning: { effort: 'low' },
198
+ } satisfies PerplexityLanguageModelOptions,
114
199
  },
115
200
  });
116
201
 
@@ -118,87 +203,161 @@ console.log(result.providerMetadata);
118
203
  // Example output:
119
204
  // {
120
205
  // perplexity: {
121
- // usage: { citationTokens: 5286, numSearchQueries: 1 },
122
- // images: [
123
- // { imageUrl: "https://example.com/image1.jpg", originUrl: "https://elsewhere.com/page1", height: 1280, width: 720 },
124
- // { imageUrl: "https://example.com/image2.jpg", originUrl: "https://elsewhere.com/page2", height: 1280, width: 720 }
125
- // ]
206
+ // usage: { citationTokens: null, numSearchQueries: 1 },
207
+ // images: null,
208
+ // cost: { totalCost: 0.006, currency: 'USD', ... },
209
+ // toolCalls: { search_web: { invocation: 1 } },
126
210
  // },
127
211
  // }
128
212
  ```
129
213
 
130
214
  #### Provider Options
131
215
 
132
- The following provider-specific options are available:
216
+ The following Agent API options are available:
217
+
218
+ - **instructions** _string_
219
+
220
+ Top-level instructions for the Agent API run.
221
+
222
+ - **tools** _array_
223
+
224
+ Native Agent API tools and their configuration.
133
225
 
134
- - **return_images** _boolean_
226
+ - **models** _string[]_
135
227
 
136
- Enable image responses. When set to `true`, the response may include relevant images. This feature is only available to Perplexity Tier-2 users and above.
228
+ A fallback model list for Agent API routing.
137
229
 
138
- - **search_recency_filter** _string_
230
+ - **max_steps** _number_
139
231
 
140
- Filter search results by recency. Possible values: `'hour'`, `'day'`, `'week'`, `'month'`. If not specified, defaults to all time.
232
+ The maximum number of agentic steps.
233
+
234
+ - **max_tool_calls** _number_
235
+
236
+ The maximum number of native tool calls. Setting this to `0` disables all
237
+ preset tools.
238
+
239
+ - **previous_response_id** _string_
240
+
241
+ Continue a conversation from an earlier Agent API response.
242
+
243
+ - **store** _boolean_
244
+
245
+ Whether the response can be retrieved later. Setting `store: false` hides it
246
+ from retrieval; it does not disable persistence, and the response can still
247
+ be used as a `previous_response_id` continuation source. See Perplexity's
248
+ [conversation state documentation](https://docs.perplexity.ai/docs/agent-api/conversation-state)
249
+ for retention behavior and account-specific zero data retention restrictions.
250
+
251
+ - **language_preference** _string_
252
+
253
+ Preferred response language as an ISO 639-1 language code.
254
+
255
+ - **reasoning** _object_
256
+
257
+ Reasoning configuration. `effort` supports `'minimal'`, `'low'`, `'medium'`,
258
+ `'high'`, and `'xhigh'`.
259
+
260
+ - **skills** _array_
261
+
262
+ Agent API skill configuration.
141
263
 
142
264
  <Note>
143
- Any other [Perplexity API
144
- parameters](https://docs.perplexity.ai/api-reference/chat-completions) can
145
- also be passed through `providerOptions.perplexity`.
265
+ See the [Perplexity Agent API
266
+ documentation](https://docs.perplexity.ai/docs/agent-api/quickstart) for
267
+ details about native request fields.
146
268
  </Note>
147
269
 
148
270
  #### Provider Metadata
149
271
 
150
272
  The response metadata includes:
151
273
 
152
- - `usage`: Object containing `citationTokens` and `numSearchQueries` metrics
153
- - `images`: Array of image objects when `return_images` is enabled (Tier-2 users only). Each image contains `imageUrl`, `originUrl`, `height`, and `width`.
274
+ - `usage`: `citationTokens` (always `null` for Agent API responses) and the
275
+ number of search queries
276
+ - `cost`: Token, tool, and total costs returned by Perplexity
277
+ - `toolCalls`: Invocation counts grouped by native tool
278
+ - `images`: Always `null`; the Agent API does not return Sonar image results
154
279
 
155
- ### PDF Support
280
+ ### Structured Output
156
281
 
157
- The Perplexity provider supports reading PDF files.
158
- You can pass PDF files as part of the message content using the `file` type:
282
+ `Output.object` and `Output.array` send an Agent API JSON schema response
283
+ format. JSON output without a schema is not supported.
159
284
 
160
- ```ts
161
- const result = await generateText({
162
- model: perplexity('sonar-pro'),
163
- messages: [
164
- {
165
- role: 'user',
166
- content: [
167
- {
168
- type: 'text',
169
- text: 'What is this document about?',
170
- },
171
- {
172
- type: 'file',
173
- data: fs.readFileSync('./data/ai.pdf'),
174
- mediaType: 'application/pdf',
175
- filename: 'ai.pdf', // optional
176
- },
177
- ],
178
- },
179
- ],
180
- });
181
- ```
285
+ ### Input Images
182
286
 
183
- You can also pass the URL of a PDF:
287
+ Image URL and data inputs are converted to Agent API `input_image` parts.
288
+ The Agent API does not provide a Sonar-equivalent PDF input field, so PDF file
289
+ parts are not supported.
184
290
 
185
- ```ts
186
- {
187
- type: 'file',
188
- data: new URL('https://example.com/document.pdf'),
189
- mediaType: 'application/pdf',
190
- filename: 'document.pdf', // optional
191
- }
192
- ```
193
-
194
- The model will have access to the contents of the PDF file and
195
- respond to questions about it.
291
+ ### Migrating from Sonar to the Agent API
196
292
 
197
293
  <Note>
198
- For more details about Perplexity's capabilities, see the [Perplexity chat
199
- completion docs](https://docs.perplexity.ai/api-reference/chat-completions).
294
+ Version 3.1.0 is a breaking migration from Sonar Chat Completions to the
295
+ Agent API. It does not provide legacy model aliases, translate Sonar provider
296
+ options, or emit migration warnings at runtime.
297
+ </Note>
298
+
299
+ <Note type="warning">
300
+ Perplexity supports Sonar Chat Completions only until September 27, 2026.
301
+ Upgrade language-generation applications to the Agent API before that date;
302
+ staying on version 3.0.63 or earlier does not preserve service after the
303
+ Sonar shutdown.
200
304
  </Note>
201
305
 
306
+ Replace each Sonar model ID with an Agent API preset or direct Agent API model
307
+ ID. These presets are suggested starting points, not equivalent aliases: a
308
+ preset can select different models and tools, so cost, latency, and output can
309
+ change.
310
+
311
+ | Sonar model | Suggested Agent API starting point |
312
+ | --------------------- | ---------------------------------- |
313
+ | `sonar` | `fast` |
314
+ | `sonar-pro` | `low` |
315
+ | `sonar-reasoning` | `medium` |
316
+ | `sonar-reasoning-pro` | `medium` |
317
+ | `sonar-deep-research` | `high` |
318
+
319
+ For example:
320
+
321
+ ```ts
322
+ // 3.0.63 and earlier (Sonar)
323
+ perplexity('sonar-pro');
324
+
325
+ // 3.1.0 and later (Agent API)
326
+ perplexity('low');
327
+ ```
328
+
329
+ Move Sonar search and reasoning options to their Agent API locations:
330
+
331
+ | Sonar provider option | Agent API option |
332
+ | ---------------------------------------- | -------------------------------------- |
333
+ | Domain, recency, and date filters | `tools[].filters` on `web_search` |
334
+ | `num_search_results` | `tools[].max_results` |
335
+ | `web_search_options.search_context_size` | `tools[].search_context_size` |
336
+ | `web_search_options.user_location` | `tools[].user_location` |
337
+ | `reasoning_effort` | `reasoning.effort` |
338
+ | `disable_search` | Omit `web_search` for direct model IDs |
339
+
340
+ Preset tools cannot be removed individually. Use a direct model ID without a
341
+ `web_search` tool when search must be disabled, or set `max_tool_calls: 0` to
342
+ disable all preset tool calls.
343
+
344
+ The Agent API has no equivalent for Sonar PDF or video inputs, image or video
345
+ results, `search_language_filter`, or `stream_mode`. Related questions require
346
+ prompting or structured output. Remove these options during migration.
347
+
348
+ Language requests now use `/v1/agent`. Custom `baseURL` proxies must route that
349
+ path. Raw responses and streams use the Agent API's typed output and SSE event
350
+ formats, and Perplexity provider metadata, usage, cost, and source identifiers
351
+ can differ. The embeddings API is unchanged.
352
+
353
+ For PDF inputs, extract the document text before sending it to the Agent API,
354
+ or choose another provider that supports PDF input. Move image/video retrieval
355
+ and language-filtered search to a separate service if your application requires
356
+ those features. Rework consumers of raw Sonar stream events for typed Agent
357
+ events. See Perplexity's [migration
358
+ guide](https://docs.perplexity.ai/docs/agent-api/migrate-from-sonar/how-to)
359
+ for the full API-level comparison.
360
+
202
361
  ## Embedding Models
203
362
 
204
363
  You can create models that call the [Perplexity embeddings API](https://docs.perplexity.ai/docs/embeddings/quickstart)
@@ -274,13 +433,13 @@ The following optional provider options are available for embedding models:
274
433
 
275
434
  ## Model Capabilities
276
435
 
277
- | Model | Image Input | Object Generation | Tool Usage | Tool Streaming |
278
- | --------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
279
- | `sonar-deep-research` | <Cross size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
280
- | `sonar-reasoning-pro` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
281
- | `sonar-reasoning` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
282
- | `sonar-pro` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
283
- | `sonar` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
436
+ | Model | Image Input | Object Generation | Tool Usage | Tool Streaming |
437
+ | -------- | ------------------- | ------------------- | ------------------- | ------------------- |
438
+ | `fast` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
439
+ | `low` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
440
+ | `medium` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
441
+ | `high` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
442
+ | `xhigh` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
284
443
 
285
444
  <Note>
286
445
  Please see the [Perplexity docs](https://docs.perplexity.ai) for detailed API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/perplexity",
3
- "version": "3.0.63",
3
+ "version": "3.1.1",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -29,8 +29,8 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "3.0.17",
33
- "@ai-sdk/provider-utils": "4.0.54"
32
+ "@ai-sdk/provider": "3.0.18",
33
+ "@ai-sdk/provider-utils": "4.0.56"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "20.17.24",
@@ -1,11 +1,20 @@
1
- import type { LanguageModelV3Usage } from '@ai-sdk/provider';
1
+ import type { JSONObject, LanguageModelV3Usage } from '@ai-sdk/provider';
2
2
 
3
3
  export function convertPerplexityUsage(
4
4
  usage:
5
5
  | {
6
- prompt_tokens?: number | null | undefined;
7
- completion_tokens?: number | null | undefined;
8
- reasoning_tokens?: number | null | undefined;
6
+ input_tokens?: number | null;
7
+ output_tokens?: number | null;
8
+ total_tokens?: number | null;
9
+ input_tokens_details?: {
10
+ cached_tokens?: number | null;
11
+ cache_creation_input_tokens?: number | null;
12
+ cache_read_input_tokens?: number | null;
13
+ } | null;
14
+ output_tokens_details?: {
15
+ reasoning_tokens?: number | null;
16
+ } | null;
17
+ [key: string]: unknown;
9
18
  }
10
19
  | undefined
11
20
  | null,
@@ -27,23 +36,28 @@ export function convertPerplexityUsage(
27
36
  };
28
37
  }
29
38
 
30
- const promptTokens = usage.prompt_tokens ?? 0;
31
- const completionTokens = usage.completion_tokens ?? 0;
32
- const reasoningTokens = usage.reasoning_tokens ?? 0;
39
+ const inputTokens = usage.input_tokens ?? 0;
40
+ const outputTokens = usage.output_tokens ?? 0;
41
+ const cacheReadTokens =
42
+ usage.input_tokens_details?.cache_read_input_tokens ??
43
+ usage.input_tokens_details?.cached_tokens ??
44
+ 0;
45
+ const cacheWriteTokens =
46
+ usage.input_tokens_details?.cache_creation_input_tokens ?? 0;
47
+ const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0;
33
48
 
34
49
  return {
35
50
  inputTokens: {
36
- total: promptTokens,
37
- noCache: promptTokens,
38
- cacheRead: undefined,
39
- cacheWrite: undefined,
51
+ total: inputTokens,
52
+ noCache: Math.max(0, inputTokens - cacheReadTokens - cacheWriteTokens),
53
+ cacheRead: cacheReadTokens,
54
+ cacheWrite: cacheWriteTokens,
40
55
  },
41
56
  outputTokens: {
42
- // Perplexity reports reasoning tokens separately from completion tokens.
43
- total: completionTokens + reasoningTokens,
44
- text: completionTokens,
57
+ total: outputTokens,
58
+ text: Math.max(0, outputTokens - reasoningTokens),
45
59
  reasoning: reasoningTokens,
46
60
  },
47
- raw: usage,
61
+ raw: usage as JSONObject,
48
62
  };
49
63
  }
@@ -0,0 +1,199 @@
1
+ import {
2
+ UnsupportedFunctionalityError,
3
+ type LanguageModelV3Prompt,
4
+ type LanguageModelV3ToolResultOutput,
5
+ type SharedV3Warning,
6
+ } from '@ai-sdk/provider';
7
+ import { convertUint8ArrayToBase64 } from '@ai-sdk/provider-utils';
8
+ import type {
9
+ PerplexityAgentInput,
10
+ PerplexityAgentInputContent,
11
+ } from './perplexity-language-model-prompt';
12
+
13
+ function serializeToolOutput(output: LanguageModelV3ToolResultOutput): string {
14
+ switch (output.type) {
15
+ case 'text':
16
+ case 'error-text':
17
+ return output.value;
18
+ case 'json':
19
+ case 'error-json':
20
+ return JSON.stringify(output.value);
21
+ case 'execution-denied':
22
+ return output.reason ?? 'Tool call execution denied.';
23
+ case 'content': {
24
+ if (output.value.some(part => part.type !== 'text')) {
25
+ throw new UnsupportedFunctionalityError({
26
+ functionality: 'file and custom tool result content',
27
+ });
28
+ }
29
+ return output.value
30
+ .map(part => (part.type === 'text' ? part.text : ''))
31
+ .join('');
32
+ }
33
+ default: {
34
+ const _exhaustiveCheck: never = output;
35
+ throw new Error(`Unsupported tool output: ${_exhaustiveCheck}`);
36
+ }
37
+ }
38
+ }
39
+
40
+ function getTopLevelMediaType(mediaType: string): string {
41
+ const slashIndex = mediaType.indexOf('/');
42
+ return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex);
43
+ }
44
+
45
+ function getThoughtSignature(
46
+ providerOptions:
47
+ | Record<string, Record<string, unknown> | undefined>
48
+ | undefined,
49
+ ): string | undefined {
50
+ const thoughtSignature = providerOptions?.perplexity?.thoughtSignature;
51
+ return typeof thoughtSignature === 'string' ? thoughtSignature : undefined;
52
+ }
53
+
54
+ export function convertToPerplexityInput(prompt: LanguageModelV3Prompt): {
55
+ input: PerplexityAgentInput;
56
+ warnings: SharedV3Warning[];
57
+ } {
58
+ const input: PerplexityAgentInput = [];
59
+ const warnings: SharedV3Warning[] = [];
60
+
61
+ for (const { role, content } of prompt) {
62
+ switch (role) {
63
+ case 'system': {
64
+ input.push({ type: 'message', role: 'system', content });
65
+ break;
66
+ }
67
+
68
+ case 'user': {
69
+ const convertedContent: PerplexityAgentInputContent[] = content.map(
70
+ part => {
71
+ switch (part.type) {
72
+ case 'text':
73
+ return { type: 'input_text', text: part.text };
74
+ case 'file': {
75
+ if (getTopLevelMediaType(part.mediaType) !== 'image') {
76
+ throw new UnsupportedFunctionalityError({
77
+ functionality: `file part media type ${part.mediaType}`,
78
+ });
79
+ }
80
+
81
+ if (part.data instanceof URL) {
82
+ return {
83
+ type: 'input_image',
84
+ image_url: part.data.toString(),
85
+ };
86
+ }
87
+
88
+ const mediaType =
89
+ part.mediaType === 'image/*' ? 'image/jpeg' : part.mediaType;
90
+
91
+ return {
92
+ type: 'input_image',
93
+ image_url: `data:${mediaType};base64,${
94
+ typeof part.data === 'string'
95
+ ? part.data
96
+ : convertUint8ArrayToBase64(part.data)
97
+ }`,
98
+ };
99
+ }
100
+ }
101
+ },
102
+ );
103
+
104
+ const isTextOnly = convertedContent.every(
105
+ part => part.type === 'input_text',
106
+ );
107
+ input.push({
108
+ type: 'message',
109
+ role: 'user',
110
+ content: isTextOnly
111
+ ? convertedContent
112
+ .map(part => (part.type === 'input_text' ? part.text : ''))
113
+ .join('')
114
+ : convertedContent,
115
+ });
116
+ break;
117
+ }
118
+
119
+ case 'assistant': {
120
+ const text = content
121
+ .filter(part => part.type === 'text')
122
+ .map(part => part.text)
123
+ .join('');
124
+
125
+ if (text.length > 0) {
126
+ input.push({ type: 'message', role: 'assistant', content: text });
127
+ }
128
+
129
+ for (const part of content) {
130
+ switch (part.type) {
131
+ case 'text':
132
+ break;
133
+ case 'tool-call':
134
+ input.push({
135
+ type: 'function_call',
136
+ call_id: part.toolCallId,
137
+ name: part.toolName,
138
+ arguments: JSON.stringify(part.input ?? {}),
139
+ thought_signature: getThoughtSignature(part.providerOptions),
140
+ });
141
+ break;
142
+ case 'tool-result':
143
+ input.push({
144
+ type: 'function_call_output',
145
+ call_id: part.toolCallId,
146
+ name: part.toolName,
147
+ output: serializeToolOutput(part.output),
148
+ thought_signature: getThoughtSignature(part.providerOptions),
149
+ });
150
+ break;
151
+ case 'reasoning':
152
+ warnings.push({
153
+ type: 'unsupported',
154
+ feature: 'reasoning content in prompt',
155
+ });
156
+ break;
157
+ case 'file':
158
+ throw new UnsupportedFunctionalityError({
159
+ functionality: `assistant ${part.type} parts`,
160
+ });
161
+ default: {
162
+ const _exhaustiveCheck: never = part;
163
+ throw new Error(
164
+ `Unsupported assistant part: ${_exhaustiveCheck}`,
165
+ );
166
+ }
167
+ }
168
+ }
169
+ break;
170
+ }
171
+
172
+ case 'tool': {
173
+ for (const part of content) {
174
+ if (part.type === 'tool-approval-response') {
175
+ throw new UnsupportedFunctionalityError({
176
+ functionality: 'tool approval responses',
177
+ });
178
+ }
179
+
180
+ input.push({
181
+ type: 'function_call_output',
182
+ call_id: part.toolCallId,
183
+ name: part.toolName,
184
+ output: serializeToolOutput(part.output),
185
+ thought_signature: getThoughtSignature(part.providerOptions),
186
+ });
187
+ }
188
+ break;
189
+ }
190
+
191
+ default: {
192
+ const _exhaustiveCheck: never = role;
193
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
194
+ }
195
+ }
196
+ }
197
+
198
+ return { input, warnings };
199
+ }
package/src/index.ts CHANGED
@@ -3,6 +3,11 @@ export type {
3
3
  PerplexityProvider,
4
4
  PerplexityProviderSettings,
5
5
  } from './perplexity-provider';
6
+ export type { PerplexityLanguageModelOptions } from './perplexity-language-model-options';
7
+ export type {
8
+ PerplexityAgentPreset,
9
+ PerplexityLanguageModelId,
10
+ } from './perplexity-options';
6
11
  export type {
7
12
  PerplexityEmbeddingModelId,
8
13
  PerplexityEmbeddingModelOptions,