portkey-ai
Version:
Node client library for the Portkey API
235 lines • 11.2 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiClient = exports.APIPromise = void 0;
const agentkeepalive_1 = __importDefault(require("agentkeepalive"));
const apis_1 = require("./apis/index.js");
const constants_1 = require("./constants.js");
const error_1 = require("./error.js");
const streaming_1 = require("./streaming.js");
const utils_1 = require("./utils.js");
const version_1 = require("./version.js");
const defaultHttpAgent = new agentkeepalive_1.default({
keepAlive: true,
timeout: 5 * 60 * 1000,
});
function getFetch() {
if (typeof window !== 'undefined' && window.fetch) {
return window.fetch.bind(window);
}
if (typeof global !== 'undefined' && global.fetch) {
return global.fetch;
}
if (typeof fetch !== 'undefined') {
return fetch;
}
throw new Error('Fetch is not available in this environment');
}
function defaultParseResponse(props) {
return __awaiter(this, void 0, void 0, function* () {
const { response } = props;
if (props.options.stream) {
return new streaming_1.Stream(response);
}
const contentType = response.headers.get('content-type');
if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/json')) {
const headers = defaultParseHeaders(props);
const json = Object.assign(Object.assign({}, (yield response.json())), { getHeaders: () => headers });
return json;
}
const text = yield response.text();
return text;
});
}
function defaultParseHeaders(props) {
const { responseHeaders } = props;
const parsedHeaders = (0, streaming_1.createResponseHeaders)(responseHeaders);
const prefix = constants_1.PORTKEY_HEADER_PREFIX;
const filteredHeaders = Object.entries(parsedHeaders)
.filter(([key, _]) => key.startsWith(prefix)) // eslint-disable-line @typescript-eslint/no-unused-vars
.map(([key, value]) => [key.replace(prefix, ''), value]);
return Object.fromEntries(filteredHeaders);
}
class APIPromise extends Promise {
constructor(responsePromise, parseResponse = defaultParseResponse) {
super((resolve) => {
// this is maybe a bit weird but this has to be a no-op to not implicitly
// parse the response body; instead .then, .catch, .finally are overridden
// to parse the response
resolve(null);
});
this.responsePromise = responsePromise;
this.parseResponse = parseResponse;
}
parse() {
if (!this.parsedPromise) {
this.parsedPromise = this.responsePromise.then(this.parseResponse);
}
return this.parsedPromise;
}
then(onfulfilled, onrejected) {
return this.parse().then(onfulfilled, onrejected);
}
catch(onrejected) {
return this.parse().catch(onrejected);
}
finally(onfinally) {
return this.parse().finally(onfinally);
}
}
exports.APIPromise = APIPromise;
class ApiClient {
constructor(_a) {
var { apiKey, baseURL, config, virtualKey, traceID, metadata, provider, Authorization, cacheForceRefresh, debug, customHost, openaiProject, openaiOrganization, awsSecretAccessKey, awsAccessKeyId, awsSessionToken, awsRegion, vertexProjectId, vertexRegion, workersAiAccountId, azureResourceName, azureDeploymentId, azureApiVersion, azureEndpointName, huggingfaceBaseUrl, forwardHeaders, cacheNamespace, requestTimeout, strictOpenAiCompliance = false, anthropicBeta, anthropicVersion, mistralFimCompletion, dangerouslyAllowBrowser, vertexStorageBucketName, providerFileName, providerModel, awsS3Bucket, awsS3ObjectKey, awsBedrockModel, fireworksAccountId } = _a, rest = __rest(_a, ["apiKey", "baseURL", "config", "virtualKey", "traceID", "metadata", "provider", "Authorization", "cacheForceRefresh", "debug", "customHost", "openaiProject", "openaiOrganization", "awsSecretAccessKey", "awsAccessKeyId", "awsSessionToken", "awsRegion", "vertexProjectId", "vertexRegion", "workersAiAccountId", "azureResourceName", "azureDeploymentId", "azureApiVersion", "azureEndpointName", "huggingfaceBaseUrl", "forwardHeaders", "cacheNamespace", "requestTimeout", "strictOpenAiCompliance", "anthropicBeta", "anthropicVersion", "mistralFimCompletion", "dangerouslyAllowBrowser", "vertexStorageBucketName", "providerFileName", "providerModel", "awsS3Bucket", "awsS3ObjectKey", "awsBedrockModel", "fireworksAccountId"]);
this.maxRetries = 1;
this.apiKey = apiKey !== null && apiKey !== void 0 ? apiKey : '';
this.baseURL = baseURL !== null && baseURL !== void 0 ? baseURL : '';
this.customHeaders = (0, apis_1.createHeaders)(Object.assign({ apiKey,
config,
virtualKey,
traceID,
metadata,
provider,
Authorization,
cacheForceRefresh,
debug,
customHost,
cacheNamespace,
openaiProject,
openaiOrganization,
awsSecretAccessKey,
awsAccessKeyId,
awsSessionToken,
awsRegion,
vertexProjectId,
vertexRegion,
workersAiAccountId,
azureResourceName,
azureDeploymentId,
azureApiVersion,
azureEndpointName,
huggingfaceBaseUrl,
forwardHeaders,
requestTimeout,
strictOpenAiCompliance,
anthropicVersion,
mistralFimCompletion,
anthropicBeta,
dangerouslyAllowBrowser,
vertexStorageBucketName,
providerFileName,
providerModel,
awsS3Bucket,
awsS3ObjectKey,
awsBedrockModel,
fireworksAccountId }, rest));
this.portkeyHeaders = this.defaultHeaders();
this.fetch = getFetch();
this.responseHeaders = {};
}
defaultHeaders() {
return Object.assign({ 'Content-Type': 'application/json', [`${constants_1.PORTKEY_HEADER_PREFIX}package-version`]: `portkey-${version_1.VERSION}` }, (0, utils_1.getPlatformProperties)());
}
_post(path, opts) {
return this.methodRequest('post', path, opts);
}
_put(path, opts) {
return this.methodRequest('put', path, opts);
}
_get(path, opts) {
return this.methodRequest('get', path, opts);
}
_delete(path, opts) {
return this.methodRequest('delete', path, opts);
}
generateError(status, errorResponse, message, headers) {
return error_1.APIError.generate(status, errorResponse, message, headers);
}
_shouldRetry(response) {
const retryStatusCode = response.status;
const retryTraceId = response.headers.get('x-portkey-trace-id');
const retryRequestId = response.headers.get('x-portkey-request-id');
const retryGatewayException = response.headers.get('x-portkey-gateway-exception');
if (retryStatusCode < 500 ||
retryTraceId ||
retryRequestId ||
retryGatewayException) {
return false;
}
return true;
}
request(opts, retryCount = 0) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
// Build the request.
const { req, url } = this.buildRequest(opts);
// Make the call to rubeus.
const response = yield this.fetch(url, req).catch(utils_1.castToError);
// Parse the response and check for errors.
if (response instanceof Error) {
if ((_a = opts.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
throw new error_1.APIUserAbortError();
}
if (retryCount < this.maxRetries) {
return this.request(opts, retryCount + 1);
}
if (response.name === 'AbortError') {
throw new error_1.APIConnectionTimeoutError({
message: `${response.message} \n STACK: ${response.stack}`,
});
}
throw new error_1.APIConnectionError({ cause: response });
}
this.responseHeaders = (0, streaming_1.createResponseHeaders)(response.headers);
if (!response.ok) {
if (retryCount < this.maxRetries && this._shouldRetry(response)) {
return this.request(opts, retryCount + 1);
}
const errText = yield response.text().catch(() => 'Unknown');
const errJSON = (0, streaming_1.safeJSON)(errText);
const errMessage = errJSON ? undefined : errText;
throw this.generateError(response.status, errJSON, errMessage, this.responseHeaders);
}
// Receive and format the response.
return { response, options: opts, responseHeaders: response.headers };
});
}
buildRequest(opts) {
const url = new URL(this.baseURL + opts.path);
const { method, body, extraHeaders } = opts;
const reqHeaders = Object.assign(Object.assign(Object.assign({}, this.defaultHeaders()), this.customHeaders), extraHeaders);
const agentConfig = typeof window === 'undefined' ? { agent: defaultHttpAgent } : {};
const req = Object.assign({ method, headers: reqHeaders }, agentConfig);
if (method !== 'get' && body !== undefined) {
req.body = JSON.stringify((0, utils_1.parseBody)(body));
}
return { req: req, url: url.toString() };
}
methodRequest(method, path, opts) {
return new APIPromise(this.request(Object.assign({ method, path }, opts)));
}
}
exports.ApiClient = ApiClient;
//# sourceMappingURL=baseClient.js.map