@probeo/anymodel 0.3.1 → 0.4.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/dist/index.cjs CHANGED
@@ -1396,6 +1396,190 @@ function createGoogleAdapter(apiKey) {
1396
1396
  return adapter;
1397
1397
  }
1398
1398
 
1399
+ // src/providers/perplexity.ts
1400
+ var PERPLEXITY_API_BASE = "https://api.perplexity.ai";
1401
+ var SUPPORTED_PARAMS4 = /* @__PURE__ */ new Set([
1402
+ "temperature",
1403
+ "max_tokens",
1404
+ "top_p",
1405
+ "frequency_penalty",
1406
+ "presence_penalty",
1407
+ "stream",
1408
+ "stop",
1409
+ "response_format",
1410
+ "tools",
1411
+ "tool_choice"
1412
+ ]);
1413
+ var MODELS = [
1414
+ { id: "sonar", name: "Sonar", context: 128e3, maxOutput: 4096, modality: "text->text", inputModalities: ["text"] },
1415
+ { id: "sonar-pro", name: "Sonar Pro", context: 2e5, maxOutput: 8192, modality: "text->text", inputModalities: ["text"] },
1416
+ { id: "sonar-reasoning", name: "Sonar Reasoning", context: 128e3, maxOutput: 8192, modality: "text->text", inputModalities: ["text"] },
1417
+ { id: "sonar-reasoning-pro", name: "Sonar Reasoning Pro", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] },
1418
+ { id: "sonar-deep-research", name: "Sonar Deep Research", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] },
1419
+ { id: "r1-1776", name: "R1 1776", context: 128e3, maxOutput: 16384, modality: "text->text", inputModalities: ["text"] }
1420
+ ];
1421
+ function createPerplexityAdapter(apiKey) {
1422
+ async function makeRequest(path2, body, method = "POST") {
1423
+ const res = await fetch(`${PERPLEXITY_API_BASE}${path2}`, {
1424
+ method,
1425
+ headers: {
1426
+ "Content-Type": "application/json",
1427
+ "Authorization": `Bearer ${apiKey}`
1428
+ },
1429
+ body: body ? JSON.stringify(body) : void 0
1430
+ });
1431
+ if (!res.ok) {
1432
+ let errorBody;
1433
+ try {
1434
+ errorBody = await res.json();
1435
+ } catch {
1436
+ errorBody = { message: res.statusText };
1437
+ }
1438
+ const msg = errorBody?.error?.message || errorBody?.message || res.statusText;
1439
+ throw new AnyModelError(mapErrorCode(res.status), msg, {
1440
+ provider_name: "perplexity",
1441
+ raw: errorBody
1442
+ });
1443
+ }
1444
+ return res;
1445
+ }
1446
+ function mapErrorCode(status) {
1447
+ if (status === 401 || status === 403) return 401;
1448
+ if (status === 429) return 429;
1449
+ if (status === 400 || status === 422) return 400;
1450
+ if (status >= 500) return 502;
1451
+ return status;
1452
+ }
1453
+ function rePrefixId(id) {
1454
+ if (id && id.startsWith("chatcmpl-")) {
1455
+ return `gen-${id.substring(9)}`;
1456
+ }
1457
+ return id.startsWith("gen-") ? id : `gen-${id}`;
1458
+ }
1459
+ function buildRequestBody(request) {
1460
+ const body = {
1461
+ model: request.model,
1462
+ messages: request.messages
1463
+ };
1464
+ if (request.temperature !== void 0) body.temperature = request.temperature;
1465
+ if (request.max_tokens !== void 0) body.max_tokens = request.max_tokens;
1466
+ if (request.top_p !== void 0) body.top_p = request.top_p;
1467
+ if (request.frequency_penalty !== void 0) body.frequency_penalty = request.frequency_penalty;
1468
+ if (request.presence_penalty !== void 0) body.presence_penalty = request.presence_penalty;
1469
+ if (request.stop !== void 0) body.stop = request.stop;
1470
+ if (request.stream !== void 0) body.stream = request.stream;
1471
+ if (request.response_format !== void 0) body.response_format = request.response_format;
1472
+ if (request.tools !== void 0) body.tools = request.tools;
1473
+ if (request.tool_choice !== void 0) body.tool_choice = request.tool_choice;
1474
+ return body;
1475
+ }
1476
+ const adapter = {
1477
+ name: "perplexity",
1478
+ translateRequest(request) {
1479
+ return buildRequestBody(request);
1480
+ },
1481
+ translateResponse(response) {
1482
+ const r = response;
1483
+ const result = {
1484
+ id: rePrefixId(r.id),
1485
+ object: "chat.completion",
1486
+ created: r.created,
1487
+ model: `perplexity/${r.model}`,
1488
+ choices: r.choices,
1489
+ usage: r.usage
1490
+ };
1491
+ if (r.citations && result.choices?.[0]?.message) {
1492
+ result.citations = r.citations;
1493
+ }
1494
+ return result;
1495
+ },
1496
+ async *translateStream(stream) {
1497
+ const reader = stream.getReader();
1498
+ const decoder = new TextDecoder();
1499
+ let buffer = "";
1500
+ try {
1501
+ while (true) {
1502
+ const { done, value } = await reader.read();
1503
+ if (done) break;
1504
+ buffer += decoder.decode(value, { stream: true });
1505
+ const lines = buffer.split("\n");
1506
+ buffer = lines.pop() || "";
1507
+ for (const line of lines) {
1508
+ const trimmed = line.trim();
1509
+ if (!trimmed || trimmed.startsWith(":")) continue;
1510
+ if (trimmed === "data: [DONE]") return;
1511
+ if (trimmed.startsWith("data: ")) {
1512
+ const json = JSON.parse(trimmed.substring(6));
1513
+ json.id = rePrefixId(json.id);
1514
+ json.model = `perplexity/${json.model}`;
1515
+ yield json;
1516
+ }
1517
+ }
1518
+ }
1519
+ } finally {
1520
+ reader.releaseLock();
1521
+ }
1522
+ },
1523
+ translateError(error) {
1524
+ if (error instanceof AnyModelError) {
1525
+ return { code: error.code, message: error.message, metadata: error.metadata };
1526
+ }
1527
+ const err = error;
1528
+ const status = err?.status || err?.code || 500;
1529
+ return {
1530
+ code: mapErrorCode(status),
1531
+ message: err?.message || "Unknown Perplexity error",
1532
+ metadata: { provider_name: "perplexity", raw: error }
1533
+ };
1534
+ },
1535
+ async listModels() {
1536
+ return MODELS.map((m) => ({
1537
+ id: `perplexity/${m.id}`,
1538
+ name: m.name,
1539
+ created: 0,
1540
+ description: "",
1541
+ context_length: m.context,
1542
+ pricing: { prompt: "0", completion: "0" },
1543
+ architecture: {
1544
+ modality: m.modality,
1545
+ input_modalities: m.inputModalities,
1546
+ output_modalities: ["text"],
1547
+ tokenizer: "unknown"
1548
+ },
1549
+ top_provider: {
1550
+ context_length: m.context,
1551
+ max_completion_tokens: m.maxOutput,
1552
+ is_moderated: false
1553
+ },
1554
+ supported_parameters: Array.from(SUPPORTED_PARAMS4)
1555
+ }));
1556
+ },
1557
+ supportsParameter(param) {
1558
+ return SUPPORTED_PARAMS4.has(param);
1559
+ },
1560
+ supportsBatch() {
1561
+ return false;
1562
+ },
1563
+ async sendRequest(request) {
1564
+ const body = buildRequestBody(request);
1565
+ const res = await makeRequest("/chat/completions", body);
1566
+ const json = await res.json();
1567
+ return adapter.translateResponse(json);
1568
+ },
1569
+ async sendStreamingRequest(request) {
1570
+ const body = buildRequestBody({ ...request, stream: true });
1571
+ const res = await makeRequest("/chat/completions", body);
1572
+ if (!res.body) {
1573
+ throw new AnyModelError(502, "No response body for streaming request", {
1574
+ provider_name: "perplexity"
1575
+ });
1576
+ }
1577
+ return adapter.translateStream(res.body);
1578
+ }
1579
+ };
1580
+ return adapter;
1581
+ }
1582
+
1399
1583
  // src/providers/custom.ts
1400
1584
  function createCustomAdapter(name, config) {
1401
1585
  const openaiAdapter = createOpenAIAdapter(config.apiKey || "", config.baseURL);
@@ -2608,14 +2792,17 @@ var AnyModel = class {
2608
2792
  if (googleKey) {
2609
2793
  this.registry.register("google", createGoogleAdapter(googleKey));
2610
2794
  }
2795
+ const perplexityKey = config.perplexity?.apiKey || process.env.PERPLEXITY_API_KEY;
2796
+ if (perplexityKey) {
2797
+ this.registry.register("perplexity", createPerplexityAdapter(perplexityKey));
2798
+ }
2611
2799
  const builtinProviders = [
2612
2800
  { name: "mistral", baseURL: "https://api.mistral.ai/v1", configKey: "mistral", envVar: "MISTRAL_API_KEY" },
2613
2801
  { name: "groq", baseURL: "https://api.groq.com/openai/v1", configKey: "groq", envVar: "GROQ_API_KEY" },
2614
2802
  { name: "deepseek", baseURL: "https://api.deepseek.com", configKey: "deepseek", envVar: "DEEPSEEK_API_KEY" },
2615
2803
  { name: "xai", baseURL: "https://api.x.ai/v1", configKey: "xai", envVar: "XAI_API_KEY" },
2616
2804
  { name: "together", baseURL: "https://api.together.xyz/v1", configKey: "together", envVar: "TOGETHER_API_KEY" },
2617
- { name: "fireworks", baseURL: "https://api.fireworks.ai/inference/v1", configKey: "fireworks", envVar: "FIREWORKS_API_KEY" },
2618
- { name: "perplexity", baseURL: "https://api.perplexity.ai", configKey: "perplexity", envVar: "PERPLEXITY_API_KEY" }
2805
+ { name: "fireworks", baseURL: "https://api.fireworks.ai/inference/v1", configKey: "fireworks", envVar: "FIREWORKS_API_KEY" }
2619
2806
  ];
2620
2807
  for (const { name, baseURL, configKey, envVar } of builtinProviders) {
2621
2808
  const providerConfig = config[configKey];