@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/CHANGELOG.md +22 -0
- package/README.md +18 -9
- package/dist/index.d.mts +112 -5
- package/dist/index.d.ts +112 -5
- package/dist/index.js +996 -341
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1000 -345
- package/dist/index.mjs.map +1 -1
- package/docs/70-perplexity.mdx +229 -70
- package/package.json +3 -3
- package/src/convert-perplexity-usage.ts +29 -15
- package/src/convert-to-perplexity-input.ts +199 -0
- package/src/index.ts +5 -0
- package/src/map-perplexity-finish-reason.ts +27 -8
- package/src/perplexity-agent-api.ts +206 -0
- package/src/perplexity-embedding-model.ts +5 -2
- package/src/perplexity-language-model-options.ts +124 -8
- package/src/perplexity-language-model-prompt.ts +25 -18
- package/src/perplexity-language-model.ts +653 -305
- package/src/perplexity-options.ts +11 -0
- package/src/perplexity-prepare-tools.ts +48 -0
- package/src/perplexity-provider.ts +4 -4
- package/src/convert-to-perplexity-messages.ts +0 -174
|
@@ -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-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
}
|