├── .gitignore ├── .npmignore ├── DefaultApi.md ├── LICENSE ├── README.md ├── apis ├── DefaultApi.ts ├── baseapi.ts └── exception.ts ├── auth └── auth.ts ├── configuration.ts ├── git_push.sh ├── http ├── http.ts └── isomorphic-fetch.ts ├── index.ts ├── middleware.ts ├── models ├── ChatCompletionResponse.ts ├── ChatCompletionResponseChoicesInner.ts ├── ChatCompletionResponseChoicesInnerDelta.ts ├── ChatCompletionResponseUsage.ts ├── ChatCompletionsPostRequest.ts ├── ChatCompletionsPostRequestMessagesInner.ts ├── ErrorResponse.ts ├── ErrorResponseError.ts ├── ObjectSerializer.ts └── all.ts ├── package.json ├── rxjsStub.ts ├── servers.ts ├── tsconfig.json ├── types ├── ObjectParamAPI.ts ├── ObservableAPI.ts └── PromiseAPI.ts ├── util.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | bump 20 | 21 | # OpenAPI Generator 22 | .openapi-generator/VERSION 23 | .openapi-generator/FILES 24 | .openapi-generator-ignore 25 | 26 | # Directory for instrumented libs generated by jscoverage/JSCover 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | coverage 31 | *.lcov 32 | 33 | # nyc test coverage 34 | .nyc_output 35 | 36 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | bower_components 41 | 42 | # node-waf configuration 43 | .lock-wscript 44 | 45 | # Compiled binary addons (https://nodejs.org/api/addons.html) 46 | build/Release 47 | 48 | # Dependency directories 49 | node_modules/ 50 | jspm_packages/ 51 | 52 | # Snowpack dependency directory (https://snowpack.dev/) 53 | web_modules/ 54 | 55 | # TypeScript cache 56 | *.tsbuildinfo 57 | 58 | # Optional npm cache directory 59 | .npm 60 | 61 | # Optional eslint cache 62 | .eslintcache 63 | 64 | # Optional stylelint cache 65 | .stylelintcache 66 | 67 | # Microbundle cache 68 | .rpt2_cache/ 69 | .rts2_cache_cjs/ 70 | .rts2_cache_es/ 71 | .rts2_cache_umd/ 72 | 73 | # Optional REPL history 74 | .node_repl_history 75 | 76 | # Output of 'npm pack' 77 | *.tgz 78 | 79 | # Yarn Integrity file 80 | .yarn-integrity 81 | 82 | # dotenv environment variable files 83 | .env 84 | .env.development.local 85 | .env.test.local 86 | .env.production.local 87 | .env.local 88 | 89 | # parcel-bundler cache (https://parceljs.org/) 90 | .cache 91 | .parcel-cache 92 | 93 | # Next.js build output 94 | .next 95 | out 96 | 97 | # Nuxt.js build / generate output 98 | .nuxt 99 | dist 100 | 101 | # Gatsby files 102 | .cache/ 103 | # Comment in the public line in if your project uses Gatsby and not Next.js 104 | # https://nextjs.org/blog/next-9-1#public-directory-support 105 | # public 106 | 107 | # vuepress build output 108 | .vuepress/dist 109 | 110 | # vuepress v2.x temp and cache directory 111 | .temp 112 | .cache 113 | 114 | # Docusaurus cache and generated files 115 | .docusaurus 116 | 117 | # Serverless directories 118 | .serverless/ 119 | 120 | # FuseBox cache 121 | .fusebox/ 122 | 123 | # DynamoDB Local files 124 | .dynamodb/ 125 | 126 | # TernJS port file 127 | .tern-port 128 | 129 | # Stores VSCode versions used for testing VSCode extensions 130 | .vscode-test 131 | 132 | # yarn v2 133 | .yarn/cache 134 | .yarn/unplugged 135 | .yarn/build-state.yml 136 | .yarn/install-state.gz 137 | .pnp.* 138 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | 93 | # Gatsby files 94 | .cache/ 95 | # Comment in the public line in if your project uses Gatsby and not Next.js 96 | # https://nextjs.org/blog/next-9-1#public-directory-support 97 | # public 98 | 99 | # vuepress build output 100 | .vuepress/dist 101 | 102 | # vuepress v2.x temp and cache directory 103 | .temp 104 | .cache 105 | 106 | # Docusaurus cache and generated files 107 | .docusaurus 108 | 109 | # Serverless directories 110 | .serverless/ 111 | 112 | # FuseBox cache 113 | .fusebox/ 114 | 115 | # DynamoDB Local files 116 | .dynamodb/ 117 | 118 | # TernJS port file 119 | .tern-port 120 | 121 | # Stores VSCode versions used for testing VSCode extensions 122 | .vscode-test 123 | 124 | # yarn v2 125 | .yarn/cache 126 | .yarn/unplugged 127 | .yarn/build-state.yml 128 | .yarn/install-state.gz 129 | .pnp.* 130 | -------------------------------------------------------------------------------- /DefaultApi.md: -------------------------------------------------------------------------------- 1 | # .DefaultApi 2 | 3 | All URIs are relative to *https://api.perplexity.ai* 4 | 5 | Method | HTTP request | Description 6 | ------------- | ------------- | ------------- 7 | [**chatCompletionsPost**](DefaultApi.md#chatCompletionsPost) | **POST** /chat/completions | Generates a model\'s response for the given chat conversation 8 | 9 | 10 | # **chatCompletionsPost** 11 | > ChatCompletionResponse chatCompletionsPost() 12 | 13 | 14 | ### Example 15 | 16 | 17 | ```typescript 18 | import { } from ''; 19 | import * as fs from 'fs'; 20 | 21 | const configuration = .createConfiguration(); 22 | const apiInstance = new .DefaultApi(configuration); 23 | 24 | let body:.DefaultApiChatCompletionsPostRequest = { 25 | // ChatCompletionsPostRequest (optional) 26 | chatCompletionsPostRequest: { 27 | model: "pplx-7b-chat", 28 | messages: [ 29 | { 30 | role: "role_example", 31 | content: "content_example", 32 | }, 33 | ], 34 | maxTokens: 1, 35 | temperature: 3.14, 36 | topP: 3.14, 37 | topK: 3.14, 38 | stream: true, 39 | presencePenalty: 3.14, 40 | frequencyPenalty: 3.14, 41 | }, 42 | }; 43 | 44 | apiInstance.chatCompletionsPost(body).then((data:any) => { 45 | console.log('API called successfully. Returned data: ' + data); 46 | }).catch((error:any) => console.error(error)); 47 | ``` 48 | 49 | 50 | ### Parameters 51 | 52 | Name | Type | Description | Notes 53 | ------------- | ------------- | ------------- | ------------- 54 | **chatCompletionsPostRequest** | **ChatCompletionsPostRequest**| | 55 | 56 | 57 | ### Return type 58 | 59 | **ChatCompletionResponse** 60 | 61 | ### Authorization 62 | 63 | [BearerAuth](README.md#BearerAuth) 64 | 65 | ### HTTP request headers 66 | 67 | - **Content-Type**: application/json 68 | - **Accept**: application/json 69 | 70 | 71 | ### HTTP response details 72 | | Status code | Description | Response headers | 73 | |-------------|-------------|------------------| 74 | **200** | Successful response | - | 75 | **400** | Bad request | - | 76 | **401** | Unauthorized | - | 77 | **403** | Forbidden | - | 78 | **404** | Not found | - | 79 | **500** | Internal server error | - | 80 | 81 | [[Back to top]](#) [[Back to API list]](README.md#documentation-for-api-endpoints) [[Back to Model list]](README.md#documentation-for-models) [[Back to README]](README.md) 82 | 83 | 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Rodrigo Gomez-Palacio 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to Perplexity.ai SDK 👋

2 |

3 | 4 | Version 5 | 6 | 7 | Documentation 8 | 9 | 10 | Maintenance 11 | 12 |

13 | 14 | > The Perplexity.ai SDK is a powerful tool for integrating advanced AI capabilities into your applications. With a simple and intuitive API, you can leverage the power of Perplexity's AI models for chat completions, instructions, and more. 15 | 16 | * 🏠 [Homepage](https://perplexity.ai) 17 | * 🖤 [npm](https://www.npmjs.com/package/perplexity-sdk) 18 | 19 | ## Overview 20 | This Unofficial SDK is designed to provide developers with easy access to Perplexity's powerful AI models. It simplifies the process of sending requests and handling responses from various models including pplx-7b-chat, pplx-70b-chat, pplx-7b-online, pplx-70b-online, and others. The SDK is highly versatile, catering to a wide range of AI-driven applications. 21 | 22 | Typescript supported. 23 | 24 | ## Supported Models: 25 | | Model | Context Length | Model Type | 26 | |-------------------------|----------------|-----------------| 27 | | `codellama-34b-instruct` | 16384 | Chat Completion | 28 | | `codellama-70b-instruct` | 16384 | Chat Completion | 29 | | `llama-2-70b-chat` | 4096 | Chat Completion | 30 | | `mistral-7b-instruct` | 4096 | Chat Completion | 31 | | `mixtral-8x7b-instruct` | 4096 | Chat Completion | 32 | | `pplx-7b-chat` | 8192 | Chat Completion | 33 | | `pplx-70b-chat` | 4096 | Chat Completion | 34 | | `pplx-7b-online` | 4096 | Chat Completion | 35 | | `pplx-70b-online` | 4096 | Chat Completion | 36 | 37 | --- 38 | 39 | ## Install 40 | You can easily install the Perplexity.ai SDK via npm or yarn. 41 | 42 | ```sh 43 | # npm 44 | npm install perplexity-sdk 45 | 46 | # yarn 47 | yarn add perplexity-sdk 48 | ``` 49 | 50 | ## Configuration 51 | To use the SDK, you need to configure it with your API key. Here's a simple setup: 52 | 53 | ```ts 54 | import Perplexity from 'perplexity-sdk'; 55 | 56 | const config = { 57 | apiKey: process.env.PERPLEXITY_API_KEY || '' 58 | }; 59 | 60 | const perplexity = new Perplexity(config).client(); 61 | ``` 62 | 63 | ## Usage 64 | Here's how you can use the SDK to send a request to Perplexity's AI models: 65 | 66 | ```ts 67 | import { ChatCompletionsPostRequestModelEnum } from 'perplexity-sdk'; 68 | 69 | const result = await perplexity.chatCompletionsPost({ 70 | model: ChatCompletionsPostRequestModelEnum.Mistral7bInstruct, 71 | messages: [{ 72 | "role": "user", 73 | "content": "Your prompt here" 74 | }], 75 | }); 76 | 77 | console.log(result); 78 | ``` 79 | 80 | ### Versioning 81 | Make sure to keep your SDK version updated to leverage new features and improvements. The current version can be found on the npm page. 82 | 83 | ## API 84 | Visit [Perplexity Labs' Official API Reference](https://docs.perplexity.ai/reference/post_chat_completions). 85 | 86 | ## 🤝 Contributing 87 | 88 | Contributions, issues, and feature requests are welcome! Feel free to check [issues page](https://github.com/PerplexityAI/perplexity-sdk/issues). 89 | 90 | ## Show your support 91 | 92 | Give a ⭐️ if this project helped you! 93 | 94 | ## Donate 95 | 96 | Bitcoin: bc1qhp9havdzfzqr9mzdc3257txmegrpryhx3kdpyz 97 | 98 | Strike: rodrigo 99 | 100 | ## 📝 License 101 | 102 | This project is [MIT](https://github.com/PerplexityAI/perplexity-sdk/blob/main/LICENSE) licensed. 103 | -------------------------------------------------------------------------------- /apis/DefaultApi.ts: -------------------------------------------------------------------------------- 1 | // TODO: better import syntax? 2 | import {BaseAPIRequestFactory, RequiredError, COLLECTION_FORMATS} from './baseapi'; 3 | import {Configuration} from '../configuration'; 4 | import {RequestContext, HttpMethod, ResponseContext, HttpFile, HttpInfo} from '../http/http'; 5 | import * as FormData from "form-data"; 6 | import { URLSearchParams } from 'url'; 7 | import {ObjectSerializer} from '../models/ObjectSerializer'; 8 | import {ApiException} from './exception'; 9 | import {canConsumeForm, isCodeInRange} from '../util'; 10 | import {SecurityAuthentication} from '../auth/auth'; 11 | 12 | 13 | import { ChatCompletionResponse } from '../models/ChatCompletionResponse'; 14 | import { ChatCompletionsPostRequest } from '../models/ChatCompletionsPostRequest'; 15 | import { ErrorResponse } from '../models/ErrorResponse'; 16 | 17 | /** 18 | * no description 19 | */ 20 | export class DefaultApiRequestFactory extends BaseAPIRequestFactory { 21 | 22 | /** 23 | * Generates a model\'s response for the given chat conversation 24 | * @param chatCompletionsPostRequest 25 | */ 26 | public async chatCompletionsPost(chatCompletionsPostRequest?: ChatCompletionsPostRequest, _options?: Configuration): Promise { 27 | let _config = _options || this.configuration; 28 | 29 | 30 | // Path Params 31 | const localVarPath = '/chat/completions'; 32 | 33 | // Make Request Context 34 | const requestContext = _config.baseServer.makeRequestContext(localVarPath, HttpMethod.POST); 35 | requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8") 36 | 37 | 38 | // Body Params 39 | const contentType = ObjectSerializer.getPreferredMediaType([ 40 | "application/json" 41 | ]); 42 | requestContext.setHeaderParam("Content-Type", contentType); 43 | const serializedBody = ObjectSerializer.stringify( 44 | ObjectSerializer.serialize(chatCompletionsPostRequest, "ChatCompletionsPostRequest", ""), 45 | contentType 46 | ); 47 | requestContext.setBody(serializedBody); 48 | 49 | let authMethod: SecurityAuthentication | undefined; 50 | // Apply auth methods 51 | authMethod = _config.authMethods["BearerAuth"] 52 | if (authMethod?.applySecurityAuthentication) { 53 | await authMethod?.applySecurityAuthentication(requestContext); 54 | } 55 | 56 | const defaultAuth: SecurityAuthentication | undefined = _options?.authMethods?.default || this.configuration?.authMethods?.default 57 | if (defaultAuth?.applySecurityAuthentication) { 58 | await defaultAuth?.applySecurityAuthentication(requestContext); 59 | } 60 | 61 | return requestContext; 62 | } 63 | 64 | } 65 | 66 | export class DefaultApiResponseProcessor { 67 | 68 | /** 69 | * Unwraps the actual response sent by the server from the response context and deserializes the response content 70 | * to the expected objects 71 | * 72 | * @params response Response returned by the server for a request to chatCompletionsPost 73 | * @throws ApiException if the response code was not in [200, 299] 74 | */ 75 | public async chatCompletionsPostWithHttpInfo(response: ResponseContext): Promise> { 76 | const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]); 77 | if (isCodeInRange("200", response.httpStatusCode)) { 78 | const body: ChatCompletionResponse = ObjectSerializer.deserialize( 79 | ObjectSerializer.parse(await response.body.text(), contentType), 80 | "ChatCompletionResponse", "" 81 | ) as ChatCompletionResponse; 82 | return new HttpInfo(response.httpStatusCode, response.headers, response.body, body); 83 | } 84 | if (isCodeInRange("400", response.httpStatusCode)) { 85 | const body: ErrorResponse = ObjectSerializer.deserialize( 86 | ObjectSerializer.parse(await response.body.text(), contentType), 87 | "ErrorResponse", "" 88 | ) as ErrorResponse; 89 | throw new ApiException(response.httpStatusCode, "Bad request", body, response.headers); 90 | } 91 | if (isCodeInRange("401", response.httpStatusCode)) { 92 | const body: ErrorResponse = ObjectSerializer.deserialize( 93 | ObjectSerializer.parse(await response.body.text(), contentType), 94 | "ErrorResponse", "" 95 | ) as ErrorResponse; 96 | throw new ApiException(response.httpStatusCode, "Unauthorized", body, response.headers); 97 | } 98 | if (isCodeInRange("403", response.httpStatusCode)) { 99 | const body: ErrorResponse = ObjectSerializer.deserialize( 100 | ObjectSerializer.parse(await response.body.text(), contentType), 101 | "ErrorResponse", "" 102 | ) as ErrorResponse; 103 | throw new ApiException(response.httpStatusCode, "Forbidden", body, response.headers); 104 | } 105 | if (isCodeInRange("404", response.httpStatusCode)) { 106 | const body: ErrorResponse = ObjectSerializer.deserialize( 107 | ObjectSerializer.parse(await response.body.text(), contentType), 108 | "ErrorResponse", "" 109 | ) as ErrorResponse; 110 | throw new ApiException(response.httpStatusCode, "Not found", body, response.headers); 111 | } 112 | if (isCodeInRange("500", response.httpStatusCode)) { 113 | const body: ErrorResponse = ObjectSerializer.deserialize( 114 | ObjectSerializer.parse(await response.body.text(), contentType), 115 | "ErrorResponse", "" 116 | ) as ErrorResponse; 117 | throw new ApiException(response.httpStatusCode, "Internal server error", body, response.headers); 118 | } 119 | 120 | // Work around for missing responses in specification, e.g. for petstore.yaml 121 | if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { 122 | const body: ChatCompletionResponse = ObjectSerializer.deserialize( 123 | ObjectSerializer.parse(await response.body.text(), contentType), 124 | "ChatCompletionResponse", "" 125 | ) as ChatCompletionResponse; 126 | return new HttpInfo(response.httpStatusCode, response.headers, response.body, body); 127 | } 128 | 129 | throw new ApiException(response.httpStatusCode, "Unknown API Status Code!", await response.getBodyAsAny(), response.headers); 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /apis/baseapi.ts: -------------------------------------------------------------------------------- 1 | import { Configuration } from '../configuration' 2 | 3 | /** 4 | * 5 | * @export 6 | */ 7 | export const COLLECTION_FORMATS = { 8 | csv: ",", 9 | ssv: " ", 10 | tsv: "\t", 11 | pipes: "|", 12 | }; 13 | 14 | 15 | /** 16 | * 17 | * @export 18 | * @class BaseAPI 19 | */ 20 | export class BaseAPIRequestFactory { 21 | 22 | constructor(protected configuration: Configuration) { 23 | } 24 | }; 25 | 26 | /** 27 | * 28 | * @export 29 | * @class RequiredError 30 | * @extends {Error} 31 | */ 32 | export class RequiredError extends Error { 33 | name: "RequiredError" = "RequiredError"; 34 | constructor(public api: string, public method: string, public field: string) { 35 | super("Required parameter " + field + " was null or undefined when calling " + api + "." + method + "."); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apis/exception.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents an error caused by an api call i.e. it has attributes for a HTTP status code 3 | * and the returned body object. 4 | * 5 | * Example 6 | * API returns a ErrorMessageObject whenever HTTP status code is not in [200, 299] 7 | * => ApiException(404, someErrorMessageObject) 8 | * 9 | */ 10 | export class ApiException extends Error { 11 | public constructor(public code: number, message: string, public body: T, public headers: { [key: string]: string; }) { 12 | super("HTTP-Code: " + code + "\nMessage: " + message + "\nBody: " + JSON.stringify(body) + "\nHeaders: " + 13 | JSON.stringify(headers)) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /auth/auth.ts: -------------------------------------------------------------------------------- 1 | import { RequestContext } from "../http/http"; 2 | 3 | /** 4 | * Interface authentication schemes. 5 | */ 6 | export interface SecurityAuthentication { 7 | /* 8 | * @return returns the name of the security authentication as specified in OAI 9 | */ 10 | getName(): string; 11 | 12 | /** 13 | * Applies the authentication scheme to the request context 14 | * 15 | * @params context the request context which should use this authentication scheme 16 | */ 17 | applySecurityAuthentication(context: RequestContext): void | Promise; 18 | } 19 | 20 | export interface TokenProvider { 21 | getToken(): Promise | string; 22 | } 23 | 24 | /** 25 | * Applies http authentication to the request context. 26 | */ 27 | export class BearerAuthAuthentication implements SecurityAuthentication { 28 | /** 29 | * Configures the http authentication with the required details. 30 | * 31 | * @param tokenProvider service that can provide the up-to-date token when needed 32 | */ 33 | public constructor(private tokenProvider: TokenProvider) {} 34 | 35 | public getName(): string { 36 | return "BearerAuth"; 37 | } 38 | 39 | public async applySecurityAuthentication(context: RequestContext) { 40 | context.setHeaderParam("Authorization", "Bearer " + await this.tokenProvider.getToken()); 41 | } 42 | } 43 | 44 | 45 | export type AuthMethods = { 46 | "default"?: SecurityAuthentication, 47 | "BearerAuth"?: SecurityAuthentication 48 | } 49 | 50 | export type ApiKeyConfiguration = string; 51 | export type HttpBasicConfiguration = { "username": string, "password": string }; 52 | export type HttpBearerConfiguration = { tokenProvider: TokenProvider }; 53 | export type OAuth2Configuration = { accessToken: string }; 54 | 55 | export type AuthMethodsConfiguration = { 56 | "default"?: SecurityAuthentication, 57 | "BearerAuth"?: HttpBearerConfiguration 58 | } 59 | 60 | /** 61 | * Creates the authentication methods from a swagger description. 62 | * 63 | */ 64 | export function configureAuthMethods(config: AuthMethodsConfiguration | undefined): AuthMethods { 65 | let authMethods: AuthMethods = {} 66 | 67 | if (!config) { 68 | return authMethods; 69 | } 70 | authMethods["default"] = config["default"] 71 | 72 | if (config["BearerAuth"]) { 73 | authMethods["BearerAuth"] = new BearerAuthAuthentication( 74 | config["BearerAuth"]["tokenProvider"] 75 | ); 76 | } 77 | 78 | return authMethods; 79 | } -------------------------------------------------------------------------------- /configuration.ts: -------------------------------------------------------------------------------- 1 | import { HttpLibrary } from "./http/http"; 2 | import { Middleware, PromiseMiddleware, PromiseMiddlewareWrapper } from "./middleware"; 3 | import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "./http/isomorphic-fetch"; 4 | import { BaseServerConfiguration, server1 } from "./servers"; 5 | import { configureAuthMethods, AuthMethods, AuthMethodsConfiguration } from "./auth/auth"; 6 | 7 | export interface Configuration { 8 | readonly baseServer: BaseServerConfiguration; 9 | readonly httpApi: HttpLibrary; 10 | readonly middleware: Middleware[]; 11 | readonly authMethods: AuthMethods; 12 | } 13 | 14 | 15 | /** 16 | * Interface with which a configuration object can be configured. 17 | */ 18 | export interface ConfigurationParameters { 19 | /** 20 | * Default server to use - a list of available servers (according to the 21 | * OpenAPI yaml definition) is included in the `servers` const in `./servers`. You can also 22 | * create your own server with the `ServerConfiguration` class from the same 23 | * file. 24 | */ 25 | baseServer?: BaseServerConfiguration; 26 | /** 27 | * HTTP library to use e.g. IsomorphicFetch. This can usually be skipped as 28 | * all generators come with a default library. 29 | * If available, additional libraries can be imported from `./http/*` 30 | */ 31 | httpApi?: HttpLibrary; 32 | 33 | /** 34 | * The middlewares which will be applied to requests and responses. You can 35 | * add any number of middleware components to modify requests before they 36 | * are sent or before they are deserialized by implementing the `Middleware` 37 | * interface defined in `./middleware` 38 | */ 39 | middleware?: Middleware[]; 40 | /** 41 | * Configures middleware functions that return promises instead of 42 | * Observables (which are used by `middleware`). Otherwise allows for the 43 | * same functionality as `middleware`, i.e., modifying requests before they 44 | * are sent and before they are deserialized. 45 | */ 46 | promiseMiddleware?: PromiseMiddleware[]; 47 | /** 48 | * Configuration for the available authentication methods (e.g., api keys) 49 | * according to the OpenAPI yaml definition. For the definition, please refer to 50 | * `./auth/auth` 51 | */ 52 | authMethods?: AuthMethodsConfiguration 53 | } 54 | 55 | /** 56 | * Provide your `ConfigurationParameters` to this function to get a `Configuration` 57 | * object that can be used to configure your APIs (in the constructor or 58 | * for each request individually). 59 | * 60 | * If a property is not included in conf, a default is used: 61 | * - baseServer: server1 62 | * - httpApi: IsomorphicFetchHttpLibrary 63 | * - middleware: [] 64 | * - promiseMiddleware: [] 65 | * - authMethods: {} 66 | * 67 | * @param conf partial configuration 68 | */ 69 | export function createConfiguration(conf: ConfigurationParameters = {}): Configuration { 70 | const configuration: Configuration = { 71 | baseServer: conf.baseServer !== undefined ? conf.baseServer : server1, 72 | httpApi: conf.httpApi || new DefaultHttpLibrary(), 73 | middleware: conf.middleware || [], 74 | authMethods: configureAuthMethods(conf.authMethods) 75 | }; 76 | if (conf.promiseMiddleware) { 77 | conf.promiseMiddleware.forEach( 78 | m => configuration.middleware.push(new PromiseMiddlewareWrapper(m)) 79 | ); 80 | } 81 | return configuration; 82 | } -------------------------------------------------------------------------------- /git_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ 3 | # 4 | # Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" 5 | 6 | git_user_id=$1 7 | git_repo_id=$2 8 | release_note=$3 9 | 10 | if [ "$git_user_id" = "" ]; then 11 | git_user_id="GIT_USER_ID" 12 | echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" 13 | fi 14 | 15 | if [ "$git_repo_id" = "" ]; then 16 | git_repo_id="GIT_REPO_ID" 17 | echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" 18 | fi 19 | 20 | if [ "$release_note" = "" ]; then 21 | release_note="Minor update" 22 | echo "[INFO] No command line input provided. Set \$release_note to $release_note" 23 | fi 24 | 25 | # Initialize the local directory as a Git repository 26 | git init 27 | 28 | # Adds the files in the local repository and stages them for commit. 29 | git add . 30 | 31 | # Commits the tracked changes and prepares them to be pushed to a remote repository. 32 | git commit -m "$release_note" 33 | 34 | # Sets the new remote 35 | git_remote=$(git remote) 36 | if [ "$git_remote" = "" ]; then # git remote not defined 37 | 38 | if [ "$GIT_TOKEN" = "" ]; then 39 | echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." 40 | git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git 41 | else 42 | git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@github.com/${git_user_id}/${git_repo_id}.git 43 | fi 44 | 45 | fi 46 | 47 | git pull origin master 48 | 49 | # Pushes (Forces) the changes in the local repository up to the remote repository 50 | echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" 51 | git push origin master 2>&1 | grep -v 'To https' 52 | -------------------------------------------------------------------------------- /http/http.ts: -------------------------------------------------------------------------------- 1 | // TODO: evaluate if we can easily get rid of this library 2 | import * as FormData from "form-data"; 3 | import { URL, URLSearchParams } from 'url'; 4 | import * as http from 'http'; 5 | import * as https from 'https'; 6 | import { Observable, from } from '../rxjsStub'; 7 | 8 | export * from './isomorphic-fetch'; 9 | 10 | /** 11 | * Represents an HTTP method. 12 | */ 13 | export enum HttpMethod { 14 | GET = "GET", 15 | HEAD = "HEAD", 16 | POST = "POST", 17 | PUT = "PUT", 18 | DELETE = "DELETE", 19 | CONNECT = "CONNECT", 20 | OPTIONS = "OPTIONS", 21 | TRACE = "TRACE", 22 | PATCH = "PATCH" 23 | } 24 | 25 | /** 26 | * Represents an HTTP file which will be transferred from or to a server. 27 | */ 28 | export type HttpFile = { 29 | data: Buffer, 30 | name: string 31 | }; 32 | 33 | export class HttpException extends Error { 34 | public constructor(msg: string) { 35 | super(msg); 36 | } 37 | } 38 | 39 | /** 40 | * Represents the body of an outgoing HTTP request. 41 | */ 42 | export type RequestBody = undefined | string | FormData | URLSearchParams; 43 | 44 | function ensureAbsoluteUrl(url: string) { 45 | if (url.startsWith("http://") || url.startsWith("https://")) { 46 | return url; 47 | } 48 | throw new Error("You need to define an absolute base url for the server."); 49 | } 50 | 51 | /** 52 | * Represents an HTTP request context 53 | */ 54 | export class RequestContext { 55 | private headers: { [key: string]: string } = {}; 56 | private body: RequestBody = undefined; 57 | private url: URL; 58 | private agent: http.Agent | https.Agent | undefined = undefined; 59 | 60 | /** 61 | * Creates the request context using a http method and request resource url 62 | * 63 | * @param url url of the requested resource 64 | * @param httpMethod http method 65 | */ 66 | public constructor(url: string, private httpMethod: HttpMethod) { 67 | this.url = new URL(ensureAbsoluteUrl(url)); 68 | } 69 | 70 | /* 71 | * Returns the url set in the constructor including the query string 72 | * 73 | */ 74 | public getUrl(): string { 75 | return this.url.toString().endsWith("/") ? 76 | this.url.toString().slice(0, -1) 77 | : this.url.toString(); 78 | } 79 | 80 | /** 81 | * Replaces the url set in the constructor with this url. 82 | * 83 | */ 84 | public setUrl(url: string) { 85 | this.url = new URL(ensureAbsoluteUrl(url)); 86 | } 87 | 88 | /** 89 | * Sets the body of the http request either as a string or FormData 90 | * 91 | * Note that setting a body on a HTTP GET, HEAD, DELETE, CONNECT or TRACE 92 | * request is discouraged. 93 | * https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#rfc.section.7.3.1 94 | * 95 | * @param body the body of the request 96 | */ 97 | public setBody(body: RequestBody) { 98 | this.body = body; 99 | } 100 | 101 | public getHttpMethod(): HttpMethod { 102 | return this.httpMethod; 103 | } 104 | 105 | public getHeaders(): { [key: string]: string } { 106 | return this.headers; 107 | } 108 | 109 | public getBody(): RequestBody { 110 | return this.body; 111 | } 112 | 113 | public setQueryParam(name: string, value: string) { 114 | this.url.searchParams.set(name, value); 115 | } 116 | 117 | /** 118 | * Sets a cookie with the name and value. NO check for duplicate cookies is performed 119 | * 120 | */ 121 | public addCookie(name: string, value: string): void { 122 | if (!this.headers["Cookie"]) { 123 | this.headers["Cookie"] = ""; 124 | } 125 | this.headers["Cookie"] += name + "=" + value + "; "; 126 | } 127 | 128 | public setHeaderParam(key: string, value: string): void { 129 | this.headers[key] = value; 130 | } 131 | 132 | public setAgent(agent: http.Agent | https.Agent) { 133 | this.agent = agent; 134 | } 135 | 136 | public getAgent(): http.Agent | https.Agent | undefined { 137 | return this.agent; 138 | } 139 | } 140 | 141 | export interface ResponseBody { 142 | text(): Promise; 143 | binary(): Promise; 144 | } 145 | 146 | /** 147 | * Helper class to generate a `ResponseBody` from binary data 148 | */ 149 | export class SelfDecodingBody implements ResponseBody { 150 | constructor(private dataSource: Promise) {} 151 | 152 | binary(): Promise { 153 | return this.dataSource; 154 | } 155 | 156 | async text(): Promise { 157 | const data: Buffer = await this.dataSource; 158 | return data.toString(); 159 | } 160 | } 161 | 162 | export class ResponseContext { 163 | public constructor( 164 | public httpStatusCode: number, 165 | public headers: { [key: string]: string }, 166 | public body: ResponseBody 167 | ) {} 168 | 169 | /** 170 | * Parse header value in the form `value; param1="value1"` 171 | * 172 | * E.g. for Content-Type or Content-Disposition 173 | * Parameter names are converted to lower case 174 | * The first parameter is returned with the key `""` 175 | */ 176 | public getParsedHeader(headerName: string): { [parameter: string]: string } { 177 | const result: { [parameter: string]: string } = {}; 178 | if (!this.headers[headerName]) { 179 | return result; 180 | } 181 | 182 | const parameters = this.headers[headerName].split(";"); 183 | for (const parameter of parameters) { 184 | let [key, value] = parameter.split("=", 2); 185 | key = key.toLowerCase().trim(); 186 | if (value === undefined) { 187 | result[""] = key; 188 | } else { 189 | value = value.trim(); 190 | if (value.startsWith('"') && value.endsWith('"')) { 191 | value = value.substring(1, value.length - 1); 192 | } 193 | result[key] = value; 194 | } 195 | } 196 | return result; 197 | } 198 | 199 | public async getBodyAsFile(): Promise { 200 | const data = await this.body.binary(); 201 | const fileName = this.getParsedHeader("content-disposition")["filename"] || ""; 202 | return { data, name: fileName }; 203 | } 204 | 205 | /** 206 | * Use a heuristic to get a body of unknown data structure. 207 | * Return as string if possible, otherwise as binary. 208 | */ 209 | public getBodyAsAny(): Promise { 210 | try { 211 | return this.body.text(); 212 | } catch {} 213 | 214 | try { 215 | return this.body.binary(); 216 | } catch {} 217 | 218 | return Promise.resolve(undefined); 219 | } 220 | } 221 | 222 | export interface HttpLibrary { 223 | send(request: RequestContext): Observable; 224 | } 225 | 226 | export interface PromiseHttpLibrary { 227 | send(request: RequestContext): Promise; 228 | } 229 | 230 | export function wrapHttpLibrary(promiseHttpLibrary: PromiseHttpLibrary): HttpLibrary { 231 | return { 232 | send(request: RequestContext): Observable { 233 | return from(promiseHttpLibrary.send(request)); 234 | } 235 | } 236 | } 237 | 238 | export class HttpInfo extends ResponseContext { 239 | public constructor( 240 | public httpStatusCode: number, 241 | public headers: { [key: string]: string }, 242 | public body: ResponseBody, 243 | public data: T, 244 | ) { 245 | super(httpStatusCode, headers, body); 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /http/isomorphic-fetch.ts: -------------------------------------------------------------------------------- 1 | import {HttpLibrary, RequestContext, ResponseContext} from './http'; 2 | import { from, Observable } from '../rxjsStub'; 3 | import fetch from "node-fetch"; 4 | 5 | export class IsomorphicFetchHttpLibrary implements HttpLibrary { 6 | 7 | public send(request: RequestContext): Observable { 8 | let method = request.getHttpMethod().toString(); 9 | let body = request.getBody(); 10 | 11 | const resultPromise = fetch(request.getUrl(), { 12 | method: method, 13 | body: body as any, 14 | headers: request.getHeaders(), 15 | agent: request.getAgent(), 16 | }).then((resp: any) => { 17 | const headers: { [name: string]: string } = {}; 18 | resp.headers.forEach((value: string, name: string) => { 19 | headers[name] = value; 20 | }); 21 | 22 | const body = { 23 | text: () => resp.text(), 24 | binary: () => resp.buffer() 25 | }; 26 | return new ResponseContext(resp.status, headers, body); 27 | }); 28 | 29 | return from>(resultPromise); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import { createConfiguration } from "./configuration" 2 | import { PromiseDefaultApi as DefaultApi } from './types/PromiseAPI'; 3 | 4 | const getConfig = (apiKey: string) => { 5 | return createConfiguration({ 6 | authMethods: { 7 | BearerAuth: { 8 | 'tokenProvider': { 9 | getToken: async () => { 10 | return apiKey || ''; 11 | } 12 | } 13 | } 14 | } 15 | }); 16 | } 17 | 18 | const getApiInstance = (apiKey: string) => { 19 | const configuration = getConfig(apiKey); 20 | return new DefaultApi(configuration); 21 | }; 22 | 23 | interface IConfig { 24 | apiKey: string; 25 | } 26 | 27 | export default class Perplexity { 28 | private instance: DefaultApi; 29 | 30 | constructor(config: IConfig) { 31 | this.instance = getApiInstance(config.apiKey); 32 | } 33 | 34 | public client(): DefaultApi { 35 | return this.instance; 36 | } 37 | } 38 | 39 | export * from "./http/http"; 40 | export * from "./auth/auth"; 41 | export * from "./models/all"; 42 | export { createConfiguration } from "./configuration" 43 | export { Configuration } from "./configuration" 44 | export * from "./apis/exception"; 45 | export * from "./servers"; 46 | export { RequiredError } from "./apis/baseapi"; 47 | 48 | export { PromiseMiddleware as Middleware } from './middleware'; 49 | export { PromiseDefaultApi as DefaultApi } from './types/PromiseAPI'; 50 | -------------------------------------------------------------------------------- /middleware.ts: -------------------------------------------------------------------------------- 1 | import {RequestContext, ResponseContext} from './http/http'; 2 | import { Observable, from } from './rxjsStub'; 3 | 4 | /** 5 | * Defines the contract for a middleware intercepting requests before 6 | * they are sent (but after the RequestContext was created) 7 | * and before the ResponseContext is unwrapped. 8 | * 9 | */ 10 | export interface Middleware { 11 | /** 12 | * Modifies the request before the request is sent. 13 | * 14 | * @param context RequestContext of a request which is about to be sent to the server 15 | * @returns an observable of the updated request context 16 | * 17 | */ 18 | pre(context: RequestContext): Observable; 19 | /** 20 | * Modifies the returned response before it is deserialized. 21 | * 22 | * @param context ResponseContext of a sent request 23 | * @returns an observable of the modified response context 24 | */ 25 | post(context: ResponseContext): Observable; 26 | } 27 | 28 | export class PromiseMiddlewareWrapper implements Middleware { 29 | 30 | public constructor(private middleware: PromiseMiddleware) { 31 | 32 | } 33 | 34 | pre(context: RequestContext): Observable { 35 | return from(this.middleware.pre(context)); 36 | } 37 | 38 | post(context: ResponseContext): Observable { 39 | return from(this.middleware.post(context)); 40 | } 41 | 42 | } 43 | 44 | /** 45 | * Defines the contract for a middleware intercepting requests before 46 | * they are sent (but after the RequestContext was created) 47 | * and before the ResponseContext is unwrapped. 48 | * 49 | */ 50 | export interface PromiseMiddleware { 51 | /** 52 | * Modifies the request before the request is sent. 53 | * 54 | * @param context RequestContext of a request which is about to be sent to the server 55 | * @returns an observable of the updated request context 56 | * 57 | */ 58 | pre(context: RequestContext): Promise; 59 | /** 60 | * Modifies the returned response before it is deserialized. 61 | * 62 | * @param context ResponseContext of a sent request 63 | * @returns an observable of the modified response context 64 | */ 65 | post(context: ResponseContext): Promise; 66 | } 67 | -------------------------------------------------------------------------------- /models/ChatCompletionResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { ChatCompletionResponseChoicesInner } from '../models/ChatCompletionResponseChoicesInner'; 14 | import { ChatCompletionResponseUsage } from '../models/ChatCompletionResponseUsage'; 15 | import { HttpFile } from '../http/http'; 16 | 17 | export class ChatCompletionResponse { 18 | 'id'?: string; 19 | 'model'?: string; 20 | 'object'?: ChatCompletionResponseObjectEnum; 21 | 'created'?: number; 22 | 'choices'?: Array; 23 | 'usage'?: ChatCompletionResponseUsage; 24 | 25 | static readonly discriminator: string | undefined = undefined; 26 | 27 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 28 | { 29 | "name": "id", 30 | "baseName": "id", 31 | "type": "string", 32 | "format": "" 33 | }, 34 | { 35 | "name": "model", 36 | "baseName": "model", 37 | "type": "string", 38 | "format": "" 39 | }, 40 | { 41 | "name": "object", 42 | "baseName": "object", 43 | "type": "ChatCompletionResponseObjectEnum", 44 | "format": "" 45 | }, 46 | { 47 | "name": "created", 48 | "baseName": "created", 49 | "type": "number", 50 | "format": "" 51 | }, 52 | { 53 | "name": "choices", 54 | "baseName": "choices", 55 | "type": "Array", 56 | "format": "" 57 | }, 58 | { 59 | "name": "usage", 60 | "baseName": "usage", 61 | "type": "ChatCompletionResponseUsage", 62 | "format": "" 63 | } ]; 64 | 65 | static getAttributeTypeMap() { 66 | return ChatCompletionResponse.attributeTypeMap; 67 | } 68 | 69 | public constructor() { 70 | } 71 | } 72 | 73 | 74 | export enum ChatCompletionResponseObjectEnum { 75 | ChatCompletion = 'chat.completion' 76 | } 77 | 78 | -------------------------------------------------------------------------------- /models/ChatCompletionResponseChoicesInner.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { ChatCompletionResponseChoicesInnerDelta } from '../models/ChatCompletionResponseChoicesInnerDelta'; 14 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 15 | import { HttpFile } from '../http/http'; 16 | 17 | export class ChatCompletionResponseChoicesInner { 18 | 'index'?: number; 19 | 'finishReason'?: ChatCompletionResponseChoicesInnerFinishReasonEnum; 20 | 'message'?: ChatCompletionsPostRequestMessagesInner; 21 | 'delta'?: ChatCompletionResponseChoicesInnerDelta; 22 | 23 | static readonly discriminator: string | undefined = undefined; 24 | 25 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 26 | { 27 | "name": "index", 28 | "baseName": "index", 29 | "type": "number", 30 | "format": "" 31 | }, 32 | { 33 | "name": "finishReason", 34 | "baseName": "finish_reason", 35 | "type": "ChatCompletionResponseChoicesInnerFinishReasonEnum", 36 | "format": "" 37 | }, 38 | { 39 | "name": "message", 40 | "baseName": "message", 41 | "type": "ChatCompletionsPostRequestMessagesInner", 42 | "format": "" 43 | }, 44 | { 45 | "name": "delta", 46 | "baseName": "delta", 47 | "type": "ChatCompletionResponseChoicesInnerDelta", 48 | "format": "" 49 | } ]; 50 | 51 | static getAttributeTypeMap() { 52 | return ChatCompletionResponseChoicesInner.attributeTypeMap; 53 | } 54 | 55 | public constructor() { 56 | } 57 | } 58 | 59 | 60 | export enum ChatCompletionResponseChoicesInnerFinishReasonEnum { 61 | Stop = 'stop', 62 | Length = 'length' 63 | } 64 | 65 | -------------------------------------------------------------------------------- /models/ChatCompletionResponseChoicesInnerDelta.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { HttpFile } from '../http/http'; 14 | 15 | export class ChatCompletionResponseChoicesInnerDelta { 16 | 'content': string; 17 | 'role': string; 18 | 19 | static readonly discriminator: string | undefined = undefined; 20 | 21 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 22 | { 23 | "name": "content", 24 | "baseName": "content", 25 | "type": "string", 26 | "format": "" 27 | }, 28 | { 29 | "name": "role", 30 | "baseName": "role", 31 | "type": "string", 32 | "format": "" 33 | } ]; 34 | 35 | static getAttributeTypeMap() { 36 | return ChatCompletionResponseChoicesInnerDelta.attributeTypeMap; 37 | } 38 | 39 | public constructor() { 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /models/ChatCompletionResponseUsage.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { HttpFile } from '../http/http'; 14 | 15 | export class ChatCompletionResponseUsage { 16 | 'promptTokens'?: number; 17 | 'completionTokens'?: number; 18 | 'totalTokens'?: number; 19 | 20 | static readonly discriminator: string | undefined = undefined; 21 | 22 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 23 | { 24 | "name": "promptTokens", 25 | "baseName": "prompt_tokens", 26 | "type": "number", 27 | "format": "" 28 | }, 29 | { 30 | "name": "completionTokens", 31 | "baseName": "completion_tokens", 32 | "type": "number", 33 | "format": "" 34 | }, 35 | { 36 | "name": "totalTokens", 37 | "baseName": "total_tokens", 38 | "type": "number", 39 | "format": "" 40 | } ]; 41 | 42 | static getAttributeTypeMap() { 43 | return ChatCompletionResponseUsage.attributeTypeMap; 44 | } 45 | 46 | public constructor() { 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /models/ChatCompletionsPostRequest.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 14 | import { HttpFile } from '../http/http'; 15 | 16 | export class ChatCompletionsPostRequest { 17 | 'model': ChatCompletionsPostRequestModelEnum; 18 | 'messages': Array; 19 | 'maxTokens'?: number; 20 | 'temperature'?: number; 21 | 'topP'?: number; 22 | 'topK'?: number; 23 | 'stream'?: boolean; 24 | 'presencePenalty'?: number; 25 | 'frequencyPenalty'?: number; 26 | 27 | static readonly discriminator: string | undefined = undefined; 28 | 29 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 30 | { 31 | "name": "model", 32 | "baseName": "model", 33 | "type": "ChatCompletionsPostRequestModelEnum", 34 | "format": "" 35 | }, 36 | { 37 | "name": "messages", 38 | "baseName": "messages", 39 | "type": "Array", 40 | "format": "" 41 | }, 42 | { 43 | "name": "maxTokens", 44 | "baseName": "max_tokens", 45 | "type": "number", 46 | "format": "" 47 | }, 48 | { 49 | "name": "temperature", 50 | "baseName": "temperature", 51 | "type": "number", 52 | "format": "" 53 | }, 54 | { 55 | "name": "topP", 56 | "baseName": "top_p", 57 | "type": "number", 58 | "format": "" 59 | }, 60 | { 61 | "name": "topK", 62 | "baseName": "top_k", 63 | "type": "number", 64 | "format": "" 65 | }, 66 | { 67 | "name": "stream", 68 | "baseName": "stream", 69 | "type": "boolean", 70 | "format": "" 71 | }, 72 | { 73 | "name": "presencePenalty", 74 | "baseName": "presence_penalty", 75 | "type": "number", 76 | "format": "" 77 | }, 78 | { 79 | "name": "frequencyPenalty", 80 | "baseName": "frequency_penalty", 81 | "type": "number", 82 | "format": "" 83 | } ]; 84 | 85 | static getAttributeTypeMap() { 86 | return ChatCompletionsPostRequest.attributeTypeMap; 87 | } 88 | 89 | public constructor() { 90 | } 91 | } 92 | 93 | 94 | export enum ChatCompletionsPostRequestModelEnum { 95 | Pplx7bChat = 'pplx-7b-chat', 96 | Pplx70bChat = 'pplx-70b-chat', 97 | Pplx7bOnline = 'pplx-7b-online', 98 | Pplx70bOnline = 'pplx-70b-online', 99 | Llama270bChat = 'llama-2-70b-chat', 100 | Codellama34bInstruct = 'codellama-34b-instruct', 101 | Codellama70bInstruct = 'codellama-70b-instruct', 102 | Mistral7bInstruct = 'mistral-7b-instruct', 103 | Mixtral8x7bInstruct = 'mixtral-8x7b-instruct' 104 | } 105 | 106 | -------------------------------------------------------------------------------- /models/ChatCompletionsPostRequestMessagesInner.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { HttpFile } from '../http/http'; 14 | 15 | export class ChatCompletionsPostRequestMessagesInner { 16 | 'role': string; 17 | 'content': string; 18 | 19 | static readonly discriminator: string | undefined = undefined; 20 | 21 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 22 | { 23 | "name": "role", 24 | "baseName": "role", 25 | "type": "string", 26 | "format": "" 27 | }, 28 | { 29 | "name": "content", 30 | "baseName": "content", 31 | "type": "string", 32 | "format": "" 33 | } ]; 34 | 35 | static getAttributeTypeMap() { 36 | return ChatCompletionsPostRequestMessagesInner.attributeTypeMap; 37 | } 38 | 39 | public constructor() { 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /models/ErrorResponse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { ErrorResponseError } from '../models/ErrorResponseError'; 14 | import { HttpFile } from '../http/http'; 15 | 16 | export class ErrorResponse { 17 | 'error'?: ErrorResponseError; 18 | 19 | static readonly discriminator: string | undefined = undefined; 20 | 21 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 22 | { 23 | "name": "error", 24 | "baseName": "error", 25 | "type": "ErrorResponseError", 26 | "format": "" 27 | } ]; 28 | 29 | static getAttributeTypeMap() { 30 | return ErrorResponse.attributeTypeMap; 31 | } 32 | 33 | public constructor() { 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /models/ErrorResponseError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Perplexity AI Chat Completions API 3 | * API for generating a model\'s response for the given chat conversation 4 | * 5 | * OpenAPI spec version: 1.0.0 6 | * 7 | * 8 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 9 | * https://openapi-generator.tech 10 | * Do not edit the class manually. 11 | */ 12 | 13 | import { HttpFile } from '../http/http'; 14 | 15 | export class ErrorResponseError { 16 | 'code'?: number; 17 | 'message'?: string; 18 | 19 | static readonly discriminator: string | undefined = undefined; 20 | 21 | static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ 22 | { 23 | "name": "code", 24 | "baseName": "code", 25 | "type": "number", 26 | "format": "" 27 | }, 28 | { 29 | "name": "message", 30 | "baseName": "message", 31 | "type": "string", 32 | "format": "" 33 | } ]; 34 | 35 | static getAttributeTypeMap() { 36 | return ErrorResponseError.attributeTypeMap; 37 | } 38 | 39 | public constructor() { 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /models/ObjectSerializer.ts: -------------------------------------------------------------------------------- 1 | export * from '../models/ChatCompletionResponse'; 2 | export * from '../models/ChatCompletionResponseChoicesInner'; 3 | export * from '../models/ChatCompletionResponseChoicesInnerDelta'; 4 | export * from '../models/ChatCompletionResponseUsage'; 5 | export * from '../models/ChatCompletionsPostRequest'; 6 | export * from '../models/ChatCompletionsPostRequestMessagesInner'; 7 | export * from '../models/ErrorResponse'; 8 | export * from '../models/ErrorResponseError'; 9 | 10 | import { ChatCompletionResponse , ChatCompletionResponseObjectEnum } from '../models/ChatCompletionResponse'; 11 | import { ChatCompletionResponseChoicesInner , ChatCompletionResponseChoicesInnerFinishReasonEnum } from '../models/ChatCompletionResponseChoicesInner'; 12 | import { ChatCompletionResponseChoicesInnerDelta } from '../models/ChatCompletionResponseChoicesInnerDelta'; 13 | import { ChatCompletionResponseUsage } from '../models/ChatCompletionResponseUsage'; 14 | import { ChatCompletionsPostRequest, ChatCompletionsPostRequestModelEnum } from '../models/ChatCompletionsPostRequest'; 15 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 16 | import { ErrorResponse } from '../models/ErrorResponse'; 17 | import { ErrorResponseError } from '../models/ErrorResponseError'; 18 | 19 | /* tslint:disable:no-unused-variable */ 20 | let primitives = [ 21 | "string", 22 | "boolean", 23 | "double", 24 | "integer", 25 | "long", 26 | "float", 27 | "number", 28 | "any" 29 | ]; 30 | 31 | let enumsMap: Set = new Set([ 32 | "ChatCompletionResponseObjectEnum", 33 | "ChatCompletionResponseChoicesInnerFinishReasonEnum", 34 | "ChatCompletionsPostRequestModelEnum", 35 | ]); 36 | 37 | let typeMap: {[index: string]: any} = { 38 | "ChatCompletionResponse": ChatCompletionResponse, 39 | "ChatCompletionResponseChoicesInner": ChatCompletionResponseChoicesInner, 40 | "ChatCompletionResponseChoicesInnerDelta": ChatCompletionResponseChoicesInnerDelta, 41 | "ChatCompletionResponseUsage": ChatCompletionResponseUsage, 42 | "ChatCompletionsPostRequest": ChatCompletionsPostRequest, 43 | "ChatCompletionsPostRequestMessagesInner": ChatCompletionsPostRequestMessagesInner, 44 | "ErrorResponse": ErrorResponse, 45 | "ErrorResponseError": ErrorResponseError, 46 | } 47 | 48 | type MimeTypeDescriptor = { 49 | type: string; 50 | subtype: string; 51 | subtypeTokens: string[]; 52 | }; 53 | 54 | /** 55 | * Every mime-type consists of a type, subtype, and optional parameters. 56 | * The subtype can be composite, including information about the content format. 57 | * For example: `application/json-patch+json`, `application/merge-patch+json`. 58 | * 59 | * This helper transforms a string mime-type into an internal representation. 60 | * This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying 61 | * the payload. 62 | */ 63 | const parseMimeType = (mimeType: string): MimeTypeDescriptor => { 64 | const [type, subtype] = mimeType.split('/'); 65 | return { 66 | type, 67 | subtype, 68 | subtypeTokens: subtype.split('+'), 69 | }; 70 | }; 71 | 72 | type MimeTypePredicate = (mimeType: string) => boolean; 73 | 74 | // This factory creates a predicate function that checks a string mime-type against defined rules. 75 | const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType)); 76 | 77 | // Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype. 78 | const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => { 79 | if (descriptor.type !== type) return false; 80 | if (subtype != null && descriptor.subtype !== subtype) return false; 81 | return true; 82 | }); 83 | 84 | // Creating a set of named predicates that will help us determine how to handle different mime-types 85 | const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text'); 86 | const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json'); 87 | const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json')); 88 | const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream'); 89 | const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded'); 90 | 91 | // Defining a list of mime-types in the order of prioritization for handling. 92 | const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [ 93 | isJsonMimeType, 94 | isJsonLikeMimeType, 95 | isTextLikeMimeType, 96 | isOctetStreamMimeType, 97 | isFormUrlencodedMimeType, 98 | ]; 99 | 100 | export class ObjectSerializer { 101 | public static findCorrectType(data: any, expectedType: string) { 102 | if (data == undefined) { 103 | return expectedType; 104 | } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) { 105 | return expectedType; 106 | } else if (expectedType === "Date") { 107 | return expectedType; 108 | } else { 109 | if (enumsMap.has(expectedType)) { 110 | return expectedType; 111 | } 112 | 113 | if (!typeMap[expectedType]) { 114 | return expectedType; // w/e we don't know the type 115 | } 116 | 117 | // Check the discriminator 118 | let discriminatorProperty = typeMap[expectedType].discriminator; 119 | if (discriminatorProperty == null) { 120 | return expectedType; // the type does not have a discriminator. use it. 121 | } else { 122 | if (data[discriminatorProperty]) { 123 | var discriminatorType = data[discriminatorProperty]; 124 | if(typeMap[discriminatorType]){ 125 | return discriminatorType; // use the type given in the discriminator 126 | } else { 127 | return expectedType; // discriminator did not map to a type 128 | } 129 | } else { 130 | return expectedType; // discriminator was not present (or an empty string) 131 | } 132 | } 133 | } 134 | } 135 | 136 | public static serialize(data: any, type: string, format: string) { 137 | if (data == undefined) { 138 | return data; 139 | } else if (primitives.indexOf(type.toLowerCase()) !== -1) { 140 | return data; 141 | } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6 142 | let subType: string = type.replace("Array<", ""); // Array => Type> 143 | subType = subType.substring(0, subType.length - 1); // Type> => Type 144 | let transformedData: any[] = []; 145 | for (let date of data) { 146 | transformedData.push(ObjectSerializer.serialize(date, subType, format)); 147 | } 148 | return transformedData; 149 | } else if (type === "Date") { 150 | if (format == "date") { 151 | let month = data.getMonth()+1 152 | month = month < 10 ? "0" + month.toString() : month.toString() 153 | let day = data.getDate(); 154 | day = day < 10 ? "0" + day.toString() : day.toString(); 155 | 156 | return data.getFullYear() + "-" + month + "-" + day; 157 | } else { 158 | return data.toISOString(); 159 | } 160 | } else { 161 | if (enumsMap.has(type)) { 162 | return data; 163 | } 164 | if (!typeMap[type]) { // in case we dont know the type 165 | return data; 166 | } 167 | 168 | // Get the actual type of this object 169 | type = this.findCorrectType(data, type); 170 | 171 | // get the map for the correct type. 172 | let attributeTypes = typeMap[type].getAttributeTypeMap(); 173 | let instance: {[index: string]: any} = {}; 174 | for (let attributeType of attributeTypes) { 175 | instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type, attributeType.format); 176 | } 177 | return instance; 178 | } 179 | } 180 | 181 | public static deserialize(data: any, type: string, format: string) { 182 | // polymorphism may change the actual type. 183 | type = ObjectSerializer.findCorrectType(data, type); 184 | if (data == undefined) { 185 | return data; 186 | } else if (primitives.indexOf(type.toLowerCase()) !== -1) { 187 | return data; 188 | } else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6 189 | let subType: string = type.replace("Array<", ""); // Array => Type> 190 | subType = subType.substring(0, subType.length - 1); // Type> => Type 191 | let transformedData: any[] = []; 192 | for (let date of data) { 193 | transformedData.push(ObjectSerializer.deserialize(date, subType, format)); 194 | } 195 | return transformedData; 196 | } else if (type === "Date") { 197 | return new Date(data); 198 | } else { 199 | if (enumsMap.has(type)) {// is Enum 200 | return data; 201 | } 202 | 203 | if (!typeMap[type]) { // dont know the type 204 | return data; 205 | } 206 | let instance = new typeMap[type](); 207 | let attributeTypes = typeMap[type].getAttributeTypeMap(); 208 | for (let attributeType of attributeTypes) { 209 | let value = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type, attributeType.format); 210 | if (value !== undefined) { 211 | instance[attributeType.name] = value; 212 | } 213 | } 214 | return instance; 215 | } 216 | } 217 | 218 | 219 | /** 220 | * Normalize media type 221 | * 222 | * We currently do not handle any media types attributes, i.e. anything 223 | * after a semicolon. All content is assumed to be UTF-8 compatible. 224 | */ 225 | public static normalizeMediaType(mediaType: string | undefined): string | undefined { 226 | if (mediaType === undefined) { 227 | return undefined; 228 | } 229 | return mediaType.split(";")[0].trim().toLowerCase(); 230 | } 231 | 232 | /** 233 | * From a list of possible media types, choose the one we can handle best. 234 | * 235 | * The order of the given media types does not have any impact on the choice 236 | * made. 237 | */ 238 | public static getPreferredMediaType(mediaTypes: Array): string { 239 | /** According to OAS 3 we should default to json */ 240 | if (mediaTypes.length === 0) { 241 | return "application/json"; 242 | } 243 | 244 | const normalMediaTypes = mediaTypes.map(this.normalizeMediaType); 245 | 246 | for (const predicate of supportedMimeTypePredicatesWithPriority) { 247 | for (const mediaType of normalMediaTypes) { 248 | if (mediaType != null && predicate(mediaType)) { 249 | return mediaType; 250 | } 251 | } 252 | } 253 | 254 | throw new Error("None of the given media types are supported: " + mediaTypes.join(", ")); 255 | } 256 | 257 | /** 258 | * Convert data to a string according the given media type 259 | */ 260 | public static stringify(data: any, mediaType: string): string { 261 | if (isTextLikeMimeType(mediaType)) { 262 | return String(data); 263 | } 264 | 265 | if (isJsonLikeMimeType(mediaType)) { 266 | return JSON.stringify(data); 267 | } 268 | 269 | throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.stringify."); 270 | } 271 | 272 | /** 273 | * Parse data from a string according to the given media type 274 | */ 275 | public static parse(rawData: string, mediaType: string | undefined) { 276 | if (mediaType === undefined) { 277 | throw new Error("Cannot parse content. No Content-Type defined."); 278 | } 279 | 280 | if (isTextLikeMimeType(mediaType)) { 281 | return rawData; 282 | } 283 | 284 | if (isJsonLikeMimeType(mediaType)) { 285 | return JSON.parse(rawData); 286 | } 287 | 288 | throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse."); 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /models/all.ts: -------------------------------------------------------------------------------- 1 | export * from '../models/ChatCompletionResponse' 2 | export * from '../models/ChatCompletionResponseChoicesInner' 3 | export * from '../models/ChatCompletionResponseChoicesInnerDelta' 4 | export * from '../models/ChatCompletionResponseUsage' 5 | export * from '../models/ChatCompletionsPostRequest' 6 | export * from '../models/ChatCompletionsPostRequestMessagesInner' 7 | export * from '../models/ErrorResponse' 8 | export * from '../models/ErrorResponseError' 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "perplexity-sdk", 3 | "version": "1.0.0", 4 | "description": "The Unofficial Perplexity SDK for Node.js", 5 | "author": "Rodrigo Gomez-Palacio", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/rgomezp/perplexity-sdk" 9 | }, 10 | "keywords": [ 11 | "fetch", 12 | "typescript", 13 | "openapi-client", 14 | "openapi-generator" 15 | ], 16 | "license": "MIT", 17 | "main": "./dist/index.js", 18 | "type": "commonjs", 19 | "exports": { 20 | ".": { 21 | "require": "./dist/index.js", 22 | "types": "./dist/index.d.js" 23 | } 24 | }, 25 | "typings": "./dist/index.d.ts", 26 | "scripts": { 27 | "build": "tsc", 28 | "prepare": "npm run build", 29 | "prepublishOnly": "npm run build && ./bump" 30 | }, 31 | "dependencies": { 32 | "@types/node": "^20.11.16", 33 | "@types/node-fetch": "^2.5.7", 34 | "es6-promise": "^4.2.4", 35 | "form-data": "^2.5.0", 36 | "node-fetch": "^2.6.0", 37 | "url-parse": "^1.4.3" 38 | }, 39 | "devDependencies": { 40 | "@types/url-parse": "1.4.4", 41 | "typescript": "^4.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /rxjsStub.ts: -------------------------------------------------------------------------------- 1 | export class Observable { 2 | constructor(private promise: Promise) {} 3 | 4 | toPromise() { 5 | return this.promise; 6 | } 7 | 8 | pipe(callback: (value: T) => S | Promise): Observable { 9 | return new Observable(this.promise.then(callback)); 10 | } 11 | } 12 | 13 | export function from(promise: Promise) { 14 | return new Observable(promise); 15 | } 16 | 17 | export function of(value: T) { 18 | return new Observable(Promise.resolve(value)); 19 | } 20 | 21 | export function mergeMap(callback: (value: T) => Observable) { 22 | return (value: T) => callback(value).toPromise(); 23 | } 24 | 25 | export function map(callback: any) { 26 | return callback; 27 | } 28 | -------------------------------------------------------------------------------- /servers.ts: -------------------------------------------------------------------------------- 1 | import { RequestContext, HttpMethod } from "./http/http"; 2 | 3 | export interface BaseServerConfiguration { 4 | makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext; 5 | } 6 | 7 | /** 8 | * 9 | * Represents the configuration of a server including its 10 | * url template and variable configuration based on the url. 11 | * 12 | */ 13 | export class ServerConfiguration implements BaseServerConfiguration { 14 | public constructor(private url: string, private variableConfiguration: T) {} 15 | 16 | /** 17 | * Sets the value of the variables of this server. Variables are included in 18 | * the `url` of this ServerConfiguration in the form `{variableName}` 19 | * 20 | * @param variableConfiguration a partial variable configuration for the 21 | * variables contained in the url 22 | */ 23 | public setVariables(variableConfiguration: Partial) { 24 | Object.assign(this.variableConfiguration, variableConfiguration); 25 | } 26 | 27 | public getConfiguration(): T { 28 | return this.variableConfiguration 29 | } 30 | 31 | private getUrl() { 32 | let replacedUrl = this.url; 33 | for (const key in this.variableConfiguration) { 34 | var re = new RegExp("{" + key + "}","g"); 35 | replacedUrl = replacedUrl.replace(re, this.variableConfiguration[key]); 36 | } 37 | return replacedUrl 38 | } 39 | 40 | /** 41 | * Creates a new request context for this server using the url with variables 42 | * replaced with their respective values and the endpoint of the request appended. 43 | * 44 | * @param endpoint the endpoint to be queried on the server 45 | * @param httpMethod httpMethod to be used 46 | * 47 | */ 48 | public makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext { 49 | return new RequestContext(this.getUrl() + endpoint, httpMethod); 50 | } 51 | } 52 | 53 | export const server1 = new ServerConfiguration<{ }>("https://api.perplexity.ai", { }) 54 | 55 | export const servers = [server1]; 56 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | /* Basic Options */ 5 | "target": "es5", 6 | "moduleResolution": "node", 7 | "declaration": true, 8 | 9 | /* Additional Checks */ 10 | "noUnusedLocals": false, /* Report errors on unused locals. */ // TODO: reenable (unused imports!) 11 | "noUnusedParameters": false, /* Report errors on unused parameters. */ // TODO: set to true again 12 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 13 | "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 14 | 15 | "removeComments": true, 16 | "sourceMap": true, 17 | "outDir": "./dist", 18 | "noLib": false, 19 | "lib": [ "es6" ], 20 | }, 21 | "exclude": [ 22 | "dist", 23 | "node_modules" 24 | ], 25 | "filesGlob": [ 26 | "./**/*.ts", 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /types/ObjectParamAPI.ts: -------------------------------------------------------------------------------- 1 | import { ResponseContext, RequestContext, HttpFile, HttpInfo } from '../http/http'; 2 | import { Configuration} from '../configuration' 3 | 4 | import { ChatCompletionResponse } from '../models/ChatCompletionResponse'; 5 | import { ChatCompletionResponseChoicesInner } from '../models/ChatCompletionResponseChoicesInner'; 6 | import { ChatCompletionResponseChoicesInnerDelta } from '../models/ChatCompletionResponseChoicesInnerDelta'; 7 | import { ChatCompletionResponseUsage } from '../models/ChatCompletionResponseUsage'; 8 | import { ChatCompletionsPostRequest } from '../models/ChatCompletionsPostRequest'; 9 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 10 | import { ErrorResponse } from '../models/ErrorResponse'; 11 | import { ErrorResponseError } from '../models/ErrorResponseError'; 12 | 13 | import { ObservableDefaultApi } from "./ObservableAPI"; 14 | import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; 15 | 16 | export interface DefaultApiChatCompletionsPostRequest { 17 | /** 18 | * 19 | * @type ChatCompletionsPostRequest 20 | * @memberof DefaultApichatCompletionsPost 21 | */ 22 | chatCompletionsPostRequest?: ChatCompletionsPostRequest 23 | } 24 | 25 | export class ObjectDefaultApi { 26 | private api: ObservableDefaultApi 27 | 28 | public constructor(configuration: Configuration, requestFactory?: DefaultApiRequestFactory, responseProcessor?: DefaultApiResponseProcessor) { 29 | this.api = new ObservableDefaultApi(configuration, requestFactory, responseProcessor); 30 | } 31 | 32 | /** 33 | * Generates a model\'s response for the given chat conversation 34 | * @param param the request object 35 | */ 36 | public chatCompletionsPostWithHttpInfo(param: DefaultApiChatCompletionsPostRequest = {}, options?: Configuration): Promise> { 37 | return this.api.chatCompletionsPostWithHttpInfo(param.chatCompletionsPostRequest, options).toPromise(); 38 | } 39 | 40 | /** 41 | * Generates a model\'s response for the given chat conversation 42 | * @param param the request object 43 | */ 44 | public chatCompletionsPost(param: DefaultApiChatCompletionsPostRequest = {}, options?: Configuration): Promise { 45 | return this.api.chatCompletionsPost(param.chatCompletionsPostRequest, options).toPromise(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /types/ObservableAPI.ts: -------------------------------------------------------------------------------- 1 | import { ResponseContext, RequestContext, HttpFile, HttpInfo } from '../http/http'; 2 | import { Configuration} from '../configuration' 3 | import { Observable, of, from } from '../rxjsStub'; 4 | import {mergeMap, map} from '../rxjsStub'; 5 | import { ChatCompletionResponse } from '../models/ChatCompletionResponse'; 6 | import { ChatCompletionResponseChoicesInner } from '../models/ChatCompletionResponseChoicesInner'; 7 | import { ChatCompletionResponseChoicesInnerDelta } from '../models/ChatCompletionResponseChoicesInnerDelta'; 8 | import { ChatCompletionResponseUsage } from '../models/ChatCompletionResponseUsage'; 9 | import { ChatCompletionsPostRequest } from '../models/ChatCompletionsPostRequest'; 10 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 11 | import { ErrorResponse } from '../models/ErrorResponse'; 12 | import { ErrorResponseError } from '../models/ErrorResponseError'; 13 | 14 | import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; 15 | export class ObservableDefaultApi { 16 | private requestFactory: DefaultApiRequestFactory; 17 | private responseProcessor: DefaultApiResponseProcessor; 18 | private configuration: Configuration; 19 | 20 | public constructor( 21 | configuration: Configuration, 22 | requestFactory?: DefaultApiRequestFactory, 23 | responseProcessor?: DefaultApiResponseProcessor 24 | ) { 25 | this.configuration = configuration; 26 | this.requestFactory = requestFactory || new DefaultApiRequestFactory(configuration); 27 | this.responseProcessor = responseProcessor || new DefaultApiResponseProcessor(); 28 | } 29 | 30 | /** 31 | * Generates a model\'s response for the given chat conversation 32 | * @param chatCompletionsPostRequest 33 | */ 34 | public chatCompletionsPostWithHttpInfo(chatCompletionsPostRequest?: ChatCompletionsPostRequest, _options?: Configuration): Observable> { 35 | const requestContextPromise = this.requestFactory.chatCompletionsPost(chatCompletionsPostRequest, _options); 36 | 37 | // build promise chain 38 | let middlewarePreObservable = from(requestContextPromise); 39 | for (let middleware of this.configuration.middleware) { 40 | middlewarePreObservable = middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => middleware.pre(ctx))); 41 | } 42 | 43 | return middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => this.configuration.httpApi.send(ctx))). 44 | pipe(mergeMap((response: ResponseContext) => { 45 | let middlewarePostObservable = of(response); 46 | for (let middleware of this.configuration.middleware) { 47 | middlewarePostObservable = middlewarePostObservable.pipe(mergeMap((rsp: ResponseContext) => middleware.post(rsp))); 48 | } 49 | return middlewarePostObservable.pipe(map((rsp: ResponseContext) => this.responseProcessor.chatCompletionsPostWithHttpInfo(rsp))); 50 | })); 51 | } 52 | 53 | /** 54 | * Generates a model\'s response for the given chat conversation 55 | * @param chatCompletionsPostRequest 56 | */ 57 | public chatCompletionsPost(chatCompletionsPostRequest?: ChatCompletionsPostRequest, _options?: Configuration): Observable { 58 | return this.chatCompletionsPostWithHttpInfo(chatCompletionsPostRequest, _options).pipe(map((apiResponse: HttpInfo) => apiResponse.data)); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /types/PromiseAPI.ts: -------------------------------------------------------------------------------- 1 | import { ResponseContext, RequestContext, HttpFile, HttpInfo } from '../http/http'; 2 | import { Configuration} from '../configuration' 3 | 4 | import { ChatCompletionResponse } from '../models/ChatCompletionResponse'; 5 | import { ChatCompletionResponseChoicesInner } from '../models/ChatCompletionResponseChoicesInner'; 6 | import { ChatCompletionResponseChoicesInnerDelta } from '../models/ChatCompletionResponseChoicesInnerDelta'; 7 | import { ChatCompletionResponseUsage } from '../models/ChatCompletionResponseUsage'; 8 | import { ChatCompletionsPostRequest } from '../models/ChatCompletionsPostRequest'; 9 | import { ChatCompletionsPostRequestMessagesInner } from '../models/ChatCompletionsPostRequestMessagesInner'; 10 | import { ErrorResponse } from '../models/ErrorResponse'; 11 | import { ErrorResponseError } from '../models/ErrorResponseError'; 12 | import { ObservableDefaultApi } from './ObservableAPI'; 13 | 14 | import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; 15 | export class PromiseDefaultApi { 16 | private api: ObservableDefaultApi 17 | 18 | public constructor( 19 | configuration: Configuration, 20 | requestFactory?: DefaultApiRequestFactory, 21 | responseProcessor?: DefaultApiResponseProcessor 22 | ) { 23 | this.api = new ObservableDefaultApi(configuration, requestFactory, responseProcessor); 24 | } 25 | 26 | /** 27 | * Generates a model\'s response for the given chat conversation 28 | * @param chatCompletionsPostRequest 29 | */ 30 | public chatCompletionsPostWithHttpInfo(chatCompletionsPostRequest?: ChatCompletionsPostRequest, _options?: Configuration): Promise> { 31 | const result = this.api.chatCompletionsPostWithHttpInfo(chatCompletionsPostRequest, _options); 32 | return result.toPromise(); 33 | } 34 | 35 | /** 36 | * Generates a model\'s response for the given chat conversation 37 | * @param chatCompletionsPostRequest 38 | */ 39 | public chatCompletionsPost(chatCompletionsPostRequest?: ChatCompletionsPostRequest, _options?: Configuration): Promise { 40 | const result = this.api.chatCompletionsPost(chatCompletionsPostRequest, _options); 41 | return result.toPromise(); 42 | } 43 | 44 | 45 | } 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns if a specific http code is in a given code range 3 | * where the code range is defined as a combination of digits 4 | * and "X" (the letter X) with a length of 3 5 | * 6 | * @param codeRange string with length 3 consisting of digits and "X" (the letter X) 7 | * @param code the http status code to be checked against the code range 8 | */ 9 | export function isCodeInRange(codeRange: string, code: number): boolean { 10 | // This is how the default value is encoded in OAG 11 | if (codeRange === "0") { 12 | return true; 13 | } 14 | if (codeRange == code.toString()) { 15 | return true; 16 | } else { 17 | const codeString = code.toString(); 18 | if (codeString.length != codeRange.length) { 19 | return false; 20 | } 21 | for (let i = 0; i < codeString.length; i++) { 22 | if (codeRange.charAt(i) != "X" && codeRange.charAt(i) != codeString.charAt(i)) { 23 | return false; 24 | } 25 | } 26 | return true; 27 | } 28 | } 29 | 30 | /** 31 | * Returns if it can consume form 32 | * 33 | * @param consumes array 34 | */ 35 | export function canConsumeForm(contentTypes: string[]): boolean { 36 | return contentTypes.indexOf('multipart/form-data') !== -1 37 | } 38 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node-fetch@^2.5.7": 6 | version "2.6.11" 7 | resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" 8 | integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== 9 | dependencies: 10 | "@types/node" "*" 11 | form-data "^4.0.0" 12 | 13 | "@types/node@*", "@types/node@^20.11.16": 14 | version "20.11.16" 15 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.16.tgz#4411f79411514eb8e2926f036c86c9f0e4ec6708" 16 | integrity sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ== 17 | dependencies: 18 | undici-types "~5.26.4" 19 | 20 | "@types/url-parse@1.4.4": 21 | version "1.4.4" 22 | resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.4.tgz#ebeb0ec8b581318739cf73e9f9b186f610764255" 23 | integrity sha512-KtQLad12+4T/NfSxpoDhmr22+fig3T7/08QCgmutYA6QSznSRmEtuL95GrhVV40/0otTEdFc+etRcCTqhh1q5Q== 24 | 25 | asynckit@^0.4.0: 26 | version "0.4.0" 27 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 28 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 29 | 30 | combined-stream@^1.0.6, combined-stream@^1.0.8: 31 | version "1.0.8" 32 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 33 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 34 | dependencies: 35 | delayed-stream "~1.0.0" 36 | 37 | delayed-stream@~1.0.0: 38 | version "1.0.0" 39 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 40 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 41 | 42 | es6-promise@^4.2.4: 43 | version "4.2.8" 44 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 45 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 46 | 47 | form-data@^2.5.0: 48 | version "2.5.1" 49 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" 50 | integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== 51 | dependencies: 52 | asynckit "^0.4.0" 53 | combined-stream "^1.0.6" 54 | mime-types "^2.1.12" 55 | 56 | form-data@^4.0.0: 57 | version "4.0.0" 58 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" 59 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== 60 | dependencies: 61 | asynckit "^0.4.0" 62 | combined-stream "^1.0.8" 63 | mime-types "^2.1.12" 64 | 65 | mime-db@1.52.0: 66 | version "1.52.0" 67 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 68 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 69 | 70 | mime-types@^2.1.12: 71 | version "2.1.35" 72 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 73 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 74 | dependencies: 75 | mime-db "1.52.0" 76 | 77 | node-fetch@^2.6.0: 78 | version "2.7.0" 79 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" 80 | integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== 81 | dependencies: 82 | whatwg-url "^5.0.0" 83 | 84 | querystringify@^2.1.1: 85 | version "2.2.0" 86 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" 87 | integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== 88 | 89 | requires-port@^1.0.0: 90 | version "1.0.0" 91 | resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" 92 | integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== 93 | 94 | tr46@~0.0.3: 95 | version "0.0.3" 96 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 97 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 98 | 99 | typescript@^4.0: 100 | version "4.9.5" 101 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" 102 | integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== 103 | 104 | undici-types@~5.26.4: 105 | version "5.26.5" 106 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 107 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 108 | 109 | url-parse@^1.4.3: 110 | version "1.5.10" 111 | resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" 112 | integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== 113 | dependencies: 114 | querystringify "^2.1.1" 115 | requires-port "^1.0.0" 116 | 117 | webidl-conversions@^3.0.0: 118 | version "3.0.1" 119 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 120 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 121 | 122 | whatwg-url@^5.0.0: 123 | version "5.0.0" 124 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 125 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 126 | dependencies: 127 | tr46 "~0.0.3" 128 | webidl-conversions "^3.0.0" 129 | --------------------------------------------------------------------------------