@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.
@@ -0,0 +1,11 @@
1
+ export type PerplexityAgentPreset =
2
+ | 'fast'
3
+ | 'low'
4
+ | 'medium'
5
+ | 'high'
6
+ | 'xhigh';
7
+
8
+ export type PerplexityLanguageModelId =
9
+ | PerplexityAgentPreset
10
+ | 'perplexity/sonar'
11
+ | (string & {});
@@ -0,0 +1,48 @@
1
+ import type {
2
+ LanguageModelV3CallOptions,
3
+ SharedV3Warning,
4
+ } from '@ai-sdk/provider';
5
+ import type { PerplexityAgentTool } from './perplexity-agent-api';
6
+
7
+ export function preparePerplexityTools({
8
+ tools,
9
+ toolChoice,
10
+ }: {
11
+ tools: LanguageModelV3CallOptions['tools'];
12
+ toolChoice: LanguageModelV3CallOptions['toolChoice'];
13
+ }): {
14
+ tools: PerplexityAgentTool[];
15
+ warnings: SharedV3Warning[];
16
+ } {
17
+ const preparedTools: PerplexityAgentTool[] = [];
18
+ const warnings: SharedV3Warning[] = [];
19
+
20
+ for (const tool of tools ?? []) {
21
+ if (tool.type === 'provider') {
22
+ warnings.push({
23
+ type: 'unsupported',
24
+ feature: `provider-defined tool ${tool.name}`,
25
+ });
26
+ continue;
27
+ }
28
+
29
+ preparedTools.push({
30
+ type: 'function',
31
+ name: tool.name,
32
+ description: tool.description,
33
+ parameters: tool.inputSchema,
34
+ strict: tool.strict,
35
+ });
36
+ }
37
+
38
+ if (toolChoice != null && toolChoice.type !== 'auto') {
39
+ warnings.push({
40
+ type: 'unsupported',
41
+ feature: 'toolChoice',
42
+ details:
43
+ 'The Perplexity Agent API currently selects tools automatically.',
44
+ });
45
+ }
46
+
47
+ return { tools: preparedTools, warnings };
48
+ }
@@ -14,17 +14,17 @@ import {
14
14
  import { PerplexityEmbeddingModel } from './perplexity-embedding-model';
15
15
  import type { PerplexityEmbeddingModelId } from './perplexity-embedding-model-options';
16
16
  import { PerplexityLanguageModel } from './perplexity-language-model';
17
- import type { PerplexityLanguageModelId } from './perplexity-language-model-options';
17
+ import type { PerplexityLanguageModelId } from './perplexity-options';
18
18
  import { VERSION } from './version';
19
19
 
20
20
  export interface PerplexityProvider extends ProviderV3 {
21
21
  /**
22
- * Creates an Perplexity chat model for text generation.
22
+ * Creates a Perplexity Agent API model or preset for text generation.
23
23
  */
24
24
  (modelId: PerplexityLanguageModelId): LanguageModelV3;
25
25
 
26
26
  /**
27
- * Creates an Perplexity language model for text generation.
27
+ * Creates a Perplexity Agent API model or preset for text generation.
28
28
  */
29
29
  languageModel(modelId: PerplexityLanguageModelId): LanguageModelV3;
30
30
 
@@ -46,7 +46,7 @@ export interface PerplexityProvider extends ProviderV3 {
46
46
 
47
47
  export interface PerplexityProviderSettings {
48
48
  /**
49
- * Base URL for the perplexity API calls.
49
+ * Base URL for Perplexity API calls.
50
50
  */
51
51
  baseURL?: string;
52
52
 
@@ -1,174 +0,0 @@
1
- import {
2
- UnsupportedFunctionalityError,
3
- type LanguageModelV3Prompt,
4
- } from '@ai-sdk/provider';
5
- import type {
6
- PerplexityMessageContent,
7
- PerplexityPrompt,
8
- } from './perplexity-language-model-prompt';
9
- import {
10
- convertBase64ToUint8Array,
11
- convertUint8ArrayToBase64,
12
- } from '@ai-sdk/provider-utils';
13
-
14
- export function convertToPerplexityMessages(
15
- prompt: LanguageModelV3Prompt,
16
- ): PerplexityPrompt {
17
- const messages: PerplexityPrompt = [];
18
-
19
- for (const { role, content } of prompt) {
20
- switch (role) {
21
- case 'system': {
22
- messages.push({ role: 'system', content });
23
- break;
24
- }
25
-
26
- case 'user':
27
- case 'assistant': {
28
- const hasMultipartContent = content.some(
29
- part =>
30
- (part.type === 'file' && part.mediaType.startsWith('image/')) ||
31
- (part.type === 'file' &&
32
- getTopLevelMediaType(part.mediaType) === 'application'),
33
- );
34
-
35
- const messageContent = content
36
- .map((part, index) => {
37
- switch (part.type) {
38
- case 'text': {
39
- return {
40
- type: 'text',
41
- text: part.text,
42
- };
43
- }
44
- case 'file': {
45
- if (getTopLevelMediaType(part.mediaType) === 'application') {
46
- const fullMediaType = resolveApplicationMediaType(part);
47
-
48
- if (fullMediaType !== 'application/pdf') {
49
- throw new UnsupportedFunctionalityError({
50
- functionality: `file part media type ${fullMediaType}`,
51
- });
52
- }
53
-
54
- return part.data instanceof URL
55
- ? {
56
- type: 'file_url',
57
- file_url: {
58
- url: part.data.toString(),
59
- },
60
- file_name: part.filename,
61
- }
62
- : {
63
- type: 'file_url',
64
- file_url: {
65
- url:
66
- typeof part.data === 'string'
67
- ? part.data
68
- : convertUint8ArrayToBase64(part.data),
69
- },
70
- file_name: part.filename || `document-${index}.pdf`,
71
- };
72
- } else if (part.mediaType.startsWith('image/')) {
73
- return part.data instanceof URL
74
- ? {
75
- type: 'image_url',
76
- image_url: {
77
- url: part.data.toString(),
78
- },
79
- }
80
- : {
81
- type: 'image_url',
82
- image_url: {
83
- url: `data:${part.mediaType ?? 'image/jpeg'};base64,${
84
- typeof part.data === 'string'
85
- ? part.data
86
- : convertUint8ArrayToBase64(part.data)
87
- }`,
88
- },
89
- };
90
- }
91
- throw new UnsupportedFunctionalityError({
92
- functionality: `file part media type ${part.mediaType}`,
93
- });
94
- }
95
- }
96
- })
97
- .filter(Boolean) as PerplexityMessageContent[];
98
- messages.push({
99
- role,
100
- content: hasMultipartContent
101
- ? messageContent
102
- : messageContent
103
- .filter(part => part.type === 'text')
104
- .map(part => part.text)
105
- .join(''),
106
- });
107
- break;
108
- }
109
- case 'tool': {
110
- throw new UnsupportedFunctionalityError({
111
- functionality: 'Tool messages',
112
- });
113
- }
114
- default: {
115
- const _exhaustiveCheck: never = role;
116
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
117
- }
118
- }
119
- }
120
-
121
- return messages;
122
- }
123
-
124
- function getTopLevelMediaType(mediaType: string): string {
125
- const slashIndex = mediaType.indexOf('/');
126
- return slashIndex === -1 ? mediaType : mediaType.substring(0, slashIndex);
127
- }
128
-
129
- function isFullMediaType(mediaType: string): boolean {
130
- const slashIndex = mediaType.indexOf('/');
131
- if (slashIndex === -1) {
132
- return false;
133
- }
134
- const subtype = mediaType.substring(slashIndex + 1);
135
- return subtype.length > 0 && subtype !== '*';
136
- }
137
-
138
- function resolveApplicationMediaType(part: {
139
- mediaType: string;
140
- data: Uint8Array | string | URL;
141
- }): string {
142
- if (isFullMediaType(part.mediaType)) {
143
- return part.mediaType;
144
- }
145
-
146
- if (part.data instanceof URL) {
147
- throw new UnsupportedFunctionalityError({
148
- functionality: `file of media type "${part.mediaType}" must specify subtype since it is not passed as inline bytes`,
149
- });
150
- }
151
-
152
- if (isPdfData(part.data)) {
153
- return 'application/pdf';
154
- }
155
-
156
- throw new UnsupportedFunctionalityError({
157
- functionality: `file of media type "${part.mediaType}" must specify subtype since it could not be auto-detected`,
158
- });
159
- }
160
-
161
- function isPdfData(data: Uint8Array | string): boolean {
162
- const bytes =
163
- typeof data === 'string'
164
- ? convertBase64ToUint8Array(data.substring(0, Math.min(data.length, 8)))
165
- : data;
166
-
167
- return (
168
- bytes.length >= 4 &&
169
- bytes[0] === 0x25 &&
170
- bytes[1] === 0x50 &&
171
- bytes[2] === 0x44 &&
172
- bytes[3] === 0x46
173
- );
174
- }