portkey-ai
Version:
Node client library for the Portkey API
191 lines • 7.9 kB
JavaScript
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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setApiKey = exports.setBaseURL = exports.toQueryParams = exports.initOpenAIClient = exports.defaultHeadersBuilder = exports.portkeyHeaders = exports.finalResponse = exports.parseBody = exports.overrideConfig = exports.getPortkeyHeader = exports.isEmpty = exports.castToError = exports.readEnv = exports.getPlatformProperties = void 0;
const constants_1 = require("./constants.js");
const streaming_1 = require("./streaming.js");
const openai_1 = __importDefault(require("openai"));
const core_1 = require("./core.js");
const getPlatformProperties = () => {
if (Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]') {
return {
[`${constants_1.PORTKEY_HEADER_PREFIX}runtime`]: 'node',
[`${constants_1.PORTKEY_HEADER_PREFIX}runtime-version`]: process.version,
};
}
const browserInfo = (0, core_1.getBrowserInfo)();
if (browserInfo) {
return {
[`${constants_1.PORTKEY_HEADER_PREFIX}runtime`]: `browser: ${browserInfo.browser}`,
[`${constants_1.PORTKEY_HEADER_PREFIX}runtime-version`]: browserInfo.version,
};
}
return {};
};
exports.getPlatformProperties = getPlatformProperties;
const readEnv = (env) => {
var _a, _b;
if (typeof process !== 'undefined') {
return (_b = (_a = process.env) === null || _a === void 0 ? void 0 : _a[env]) !== null && _b !== void 0 ? _b : undefined;
}
return undefined;
};
exports.readEnv = readEnv;
const castToError = (err) => {
if (err instanceof Error)
return err;
return new Error(err);
};
exports.castToError = castToError;
const isEmpty = (value) => {
// Check if the value is null or undefined
if (value == null) {
return true;
}
// Check if the value is a string and has zero length
if (typeof value === 'string' && value.trim().length === 0) {
return true;
}
// Check if the value is an array and has zero elements
if (Array.isArray(value) && value.length === 0) {
return true;
}
// Check if the value is an object and has zero keys
if (typeof value === 'object' && Object.keys(value).length === 0) {
return true;
}
// If none of the above conditions are met, the value is not empty
return false;
};
exports.isEmpty = isEmpty;
const getPortkeyHeader = (key) => {
return `${constants_1.PORTKEY_HEADER_PREFIX}${key}`;
};
exports.getPortkeyHeader = getPortkeyHeader;
const overrideConfig = (initialConfig, updatedConfig) => {
if ((0, exports.isEmpty)(updatedConfig)) {
return initialConfig;
}
return updatedConfig;
};
exports.overrideConfig = overrideConfig;
const parseBody = (data) => {
// Making sure that every key in the body is in snake case
if ((0, exports.isEmpty)(data)) {
return {};
}
const parsedData = {};
for (let k in data) {
const v = data[k];
// convert to snakecase
k = k
.replace('ID', 'Id')
.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
parsedData[k] = v;
}
return parsedData;
};
exports.parseBody = parseBody;
function finalResponse(response) {
var _a;
const headers = portkeyHeaders(response.response.headers);
const json = Object.assign(Object.assign({}, (((_a = response.data) === null || _a === void 0 ? void 0 : _a.body) || response.data)), { getHeaders: () => headers });
return json;
}
exports.finalResponse = finalResponse;
function portkeyHeaders(headers) {
const parsedHeaders = (0, streaming_1.createResponseHeaders)(headers);
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);
}
exports.portkeyHeaders = portkeyHeaders;
function defaultHeadersBuilder(client) {
const customHeaders = client.customHeaders;
const portkeyHeaders = client.portkeyHeaders;
// Logic to add Bearer only if it is not present.
// Else it would be added everytime a request is made
if (Object.prototype.hasOwnProperty.call(customHeaders, 'authorization') &&
!customHeaders['authorization'].startsWith('Bearer')) {
client.customHeaders['authorization'] =
'Bearer ' + client.customHeaders['authorization'];
}
return Object.assign(Object.assign({}, customHeaders), portkeyHeaders);
}
exports.defaultHeadersBuilder = defaultHeadersBuilder;
function initOpenAIClient(client) {
var _a;
return new openai_1.default({
apiKey: client.apiKey || (0, exports.readEnv)('OPENAI_API_KEY') || constants_1.OPEN_AI_API_KEY,
baseURL: client.baseURL,
defaultHeaders: defaultHeadersBuilder(client),
maxRetries: 0,
dangerouslyAllowBrowser: (_a = client.dangerouslyAllowBrowser) !== null && _a !== void 0 ? _a : false,
fetch: (url, init) => __awaiter(this, void 0, void 0, function* () {
var _b;
// NOTE: For adding duplex option only when body is a Readable stream
const fetchOptions = Object.assign(Object.assign({}, init), ((init === null || init === void 0 ? void 0 : init.body) &&
typeof ((_b = init.body) === null || _b === void 0 ? void 0 : _b.pipe) === 'function' && { duplex: 'half' }));
let isRetrying = false;
let response;
try {
response = yield fetch(url, fetchOptions);
}
catch (error) {
isRetrying = true;
}
if (isRetrying ||
(response && !response.ok && client._shouldRetry(response))) {
return yield fetch(url, fetchOptions);
}
else if (response) {
return response;
}
else {
throw (0, exports.castToError)(response);
}
}),
});
}
exports.initOpenAIClient = initOpenAIClient;
function toQueryParams(params) {
if (!params) {
return '';
}
const queryParams = Object.entries(params)
.filter(([, value]) => value !== undefined && value !== null)
.map(([key, value]) => `${key}=${value}`)
.join('&');
return queryParams ? `?${queryParams}` : '';
}
exports.toQueryParams = toQueryParams;
function setBaseURL(baseURL, apiKey) {
if (baseURL) {
return baseURL;
}
return apiKey ? constants_1.PORTKEY_BASE_URL : constants_1.LOCAL_BASE_URL;
}
exports.setBaseURL = setBaseURL;
function setApiKey(baseURL, apiKey) {
if (apiKey) {
return apiKey;
}
if (baseURL === constants_1.PORTKEY_BASE_URL && !apiKey) {
throw (0, exports.castToError)(constants_1.MISSING_API_KEY_ERROR_MESSAGE);
}
}
exports.setApiKey = setApiKey;
//# sourceMappingURL=utils.js.map
;