@ai-sdk/perplexity 2.1.0-beta.8 → 2.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 +231 -45
- package/README.md +20 -9
- package/dist/index.d.mts +117 -9
- package/dist/index.d.ts +117 -9
- package/dist/index.js +993 -258
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +990 -252
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
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-
|
|
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
|
|
28
|
-
|
|
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
|
-
|
|
89
|
+
input.push({ type: "message", role: "system", content });
|
|
33
90
|
break;
|
|
34
91
|
}
|
|
35
|
-
case "user":
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
|
194
|
+
return { input, warnings };
|
|
82
195
|
}
|
|
83
196
|
|
|
84
197
|
// src/map-perplexity-finish-reason.ts
|
|
85
|
-
function mapPerplexityFinishReason(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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 "
|
|
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 = "
|
|
613
|
+
this.specificationVersion = "v2";
|
|
99
614
|
this.provider = "perplexity";
|
|
100
615
|
this.supportedUrls = {
|
|
101
|
-
|
|
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: "
|
|
649
|
+
setting: "frequencyPenalty"
|
|
125
650
|
});
|
|
126
651
|
}
|
|
127
|
-
if (
|
|
652
|
+
if (presencePenalty != null) {
|
|
128
653
|
warnings.push({
|
|
129
654
|
type: "unsupported-setting",
|
|
130
|
-
setting: "
|
|
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: "
|
|
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
|
|
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
|
|
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
|
-
|
|
718
|
+
perplexityAgentResponseSchema
|
|
180
719
|
),
|
|
181
720
|
abortSignal: options.abortSignal,
|
|
182
721
|
fetch: this.config.fetch
|
|
183
722
|
});
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
191
|
-
|
|
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: "
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
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}/
|
|
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
|
-
|
|
830
|
+
perplexityAgentChunkSchema
|
|
244
831
|
),
|
|
245
832
|
abortSignal: options.abortSignal,
|
|
246
833
|
fetch: this.config.fetch
|
|
247
834
|
});
|
|
248
835
|
let finishReason = "unknown";
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
|
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
|
-
|
|
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: "
|
|
285
|
-
|
|
937
|
+
type: "tool-input-start",
|
|
938
|
+
id: item.call_id,
|
|
939
|
+
toolName: item.name
|
|
286
940
|
});
|
|
287
|
-
|
|
288
|
-
|
|
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:
|
|
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
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
318
|
-
|
|
1129
|
+
},
|
|
1130
|
+
flush(controller) {
|
|
1131
|
+
for (const source of pendingSourcesByUrl.values()) {
|
|
1132
|
+
controller.enqueue(source);
|
|
319
1133
|
}
|
|
320
|
-
|
|
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: "
|
|
329
|
-
id:
|
|
330
|
-
delta: textContent
|
|
1136
|
+
type: "reasoning-end",
|
|
1137
|
+
id: activeReasoningId
|
|
331
1138
|
});
|
|
332
1139
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
|
1161
|
+
var VERSION = true ? "2.1.0" : "0.0.0-test";
|
|
424
1162
|
|
|
425
1163
|
// src/perplexity-provider.ts
|
|
426
1164
|
function createPerplexity(options = {}) {
|