@pezzo/client
Version:
TypeScript API client for Pezzo
339 lines (328 loc) • 13.6 kB
JavaScript
import 'reflect-metadata';
import { __awaiter, __decorate, __metadata } from 'tslib';
import fetch from 'cross-fetch';
import OpenAI from 'openai';
import { Type } from 'class-transformer';
var PromptExecutionStatus;
(function (PromptExecutionStatus) {
PromptExecutionStatus["Success"] = "Success";
PromptExecutionStatus["Error"] = "Error";
})(PromptExecutionStatus || (PromptExecutionStatus = {}));
const defaultOptions = {
serverUrl: "https://api.pezzo.ai",
};
class Pezzo {
constructor(options) {
this.options = Object.assign({ serverUrl: options.serverUrl ||
process.env["PEZZO_SERVER_URL"] ||
defaultOptions.serverUrl, apiKey: options.apiKey || process.env["PEZZO_API_KEY"], projectId: options.projectId || process.env["PEZZO_PROJECT_ID"], environment: options.environment || process.env["PEZZO_ENVIRONMENT"] }, options);
}
getPrompt(promptName) {
return __awaiter(this, void 0, void 0, function* () {
const url = new URL(`${this.options.serverUrl}/api/prompts/v2/deployment`);
url.searchParams.append("name", promptName);
url.searchParams.append("environmentName", this.options.environment);
const response = yield fetch(url.toString(), {
headers: {
"Content-Type": "application/json",
"x-pezzo-api-key": this.options.apiKey,
"x-pezzo-project-id": this.options.projectId,
},
});
const data = yield response.json();
if (!response.ok) {
if (data === null || data === void 0 ? void 0 : data.message) {
throw new Error(data.message);
}
else {
throw new Error(`Error fetching prompt "${promptName}" for environment "${this.options.environment}" (${data.statusCode}).`);
}
}
const pezzoPrompt = {
metadata: {
promptId: data.promptId,
promptVersionSha: data.promptVersionSha,
type: data.type,
},
settings: data.settings,
content: data.content,
};
return {
pezzo: pezzoPrompt,
};
});
}
reportPromptExecution(dto) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`${this.options.serverUrl}/api/reporting/v2/request`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-pezzo-api-key": this.options.apiKey,
"x-pezzo-project-id": this.options.projectId,
},
body: JSON.stringify(dto),
});
if (!response.ok) {
const json = yield response.json();
console.warn("Could not report prompt execution", json);
}
});
}
fetchCachedRequest(request) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`${this.options.serverUrl}/api/cache/v1/request/retrieve`, {
method: "POST",
body: JSON.stringify({ request }),
headers: {
"Content-Type": "application/json",
"x-pezzo-api-key": this.options.apiKey,
"x-pezzo-project-id": this.options.projectId,
},
});
if (!response.ok) {
const json = yield response.json();
console.warn("Could not fetch request fro mcache", json);
}
const data = yield response.json();
return data;
});
}
cacheRequest(request, _response) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield fetch(`${this.options.serverUrl}/api/cache/v1/request/save`, {
method: "POST",
body: JSON.stringify({
request,
response: _response,
}),
headers: {
"Content-Type": "application/json",
"x-pezzo-api-key": this.options.apiKey,
"x-pezzo-project-id": this.options.projectId,
},
});
if (!response.ok) {
const json = yield response.json();
console.warn("Could not cache request", json);
}
});
}
}
function interpolateVariablesRecursively(obj, variables) {
const processValue = (value) => {
if (typeof value === "string") {
return value.replace(/{\s*(\w+)\s*}/g, (match, key) => Object.prototype.hasOwnProperty.call(variables, key)
? String(variables[key])
: match);
}
else if (Array.isArray(value)) {
return value.map(processValue);
}
else if (typeof value === "object" && value !== null) {
return processObj(value);
}
else {
return value;
}
};
const processObj = (object) => {
return Object.entries(object).reduce((newObject, [key, value]) => {
newObject[key] = processValue(value);
return newObject;
}, {});
};
return processValue(obj);
}
const merge = (...args) => {
return args.reduce((acc, arg) => {
return Object.assign(Object.assign({}, acc), arg);
}, {});
};
var PromptExecutionType;
(function (PromptExecutionType) {
PromptExecutionType["ChatCompletion"] = "ChatCompletion";
PromptExecutionType["Completion"] = "Completion";
})(PromptExecutionType || (PromptExecutionType = {}));
var PromptService;
(function (PromptService) {
PromptService["OpenAIChatCompletion"] = "OpenAIChatCompletion";
PromptService["AzureOpenAIChatCompletion"] = "AzureOpenAIChatCompletion";
PromptService["AnthropicCompletion"] = "AnthropicCompletion";
})(PromptService || (PromptService = {}));
var Provider;
(function (Provider) {
Provider["OpenAI"] = "OpenAI";
Provider["Azure"] = "Azure";
Provider["Anthropic"] = "Anthropic";
})(Provider || (Provider = {}));
({
[Provider.OpenAI]: {
name: "OpenAI",
},
[Provider.Azure]: {
name: "Azure",
},
[Provider.Anthropic]: {
name: "Anthropic",
},
});
({
[PromptService.OpenAIChatCompletion]: {
name: "OpenAI Chat Completion",
provider: Provider.OpenAI,
defaultSettings: {},
},
[PromptService.AzureOpenAIChatCompletion]: {
name: "Azure OpenAI (Coming Soon)",
provider: Provider.Azure,
defaultSettings: {},
},
[PromptService.AnthropicCompletion]: {
name: "Anthropic (Coming Soon)",
provider: Provider.Anthropic,
defaultSettings: {},
},
});
class GenericObservabilityRequestResponseBody {
}
class OpenAIObservabilityRequestBody {
}
class OpenAIObservabilityResponseBody {
}
class ObservabilityRequest {
}
__decorate([
Type((opts) => (opts === null || opts === void 0 ? void 0 : opts.object["provider"]) === Provider.OpenAI
? OpenAIObservabilityRequestBody
: GenericObservabilityRequestResponseBody),
__metadata("design:type", Object)
], ObservabilityRequest.prototype, "body", void 0);
class ObservabilityResponse {
}
__decorate([
Type((opts) => (opts === null || opts === void 0 ? void 0 : opts.object["provider"]) === Provider.OpenAI
? OpenAIObservabilityResponseBody
: GenericObservabilityRequestResponseBody),
__metadata("design:type", Object)
], ObservabilityResponse.prototype, "body", void 0);
const version = "0.4.19";
class PezzoOpenAI {
constructor(pezzo, configuration) {
this.openai = new OpenAI(configuration);
this.chat = new Chat(pezzo, this.openai);
}
}
class Chat {
constructor(pezzo, openai) {
this.completions = new Completions(pezzo, openai);
}
}
class Completions {
constructor(pezzo, openai) {
this.pezzo = pezzo;
this.openai = openai;
}
create(_arg1, pezzoOptions = {}, openaiOptions) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const arg1 = _arg1;
const pezzoPrompt = arg1.pezzo; // TODO: Fix this type
const nativeOptions = Object.assign({}, arg1);
delete nativeOptions["pezzo"];
let managedMessages = [];
if (pezzoPrompt) {
if (pezzoPrompt.content.messages) {
managedMessages = pezzoPrompt.content.messages;
}
else {
managedMessages = [
{ role: "user", content: pezzoPrompt.content.prompt },
];
}
}
const requestBody = Object.assign(Object.assign({ messages: managedMessages }, ((_a = pezzoPrompt === null || pezzoPrompt === void 0 ? void 0 : pezzoPrompt.settings) !== null && _a !== void 0 ? _a : {})), nativeOptions);
if (pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.variables) {
const messages = interpolateVariablesRecursively(requestBody.messages, pezzoOptions.variables);
requestBody.messages = messages;
}
let response;
let error;
let reportPayload;
const baseMetadata = {
environment: this.pezzo.options.environment,
provider: Provider.OpenAI,
type: PromptExecutionType.ChatCompletion,
client: "pezzo-ts",
clientVersion: version,
};
const requestTimestamp = new Date().toISOString();
const baseReport = {
metadata: merge(baseMetadata, pezzoPrompt === null || pezzoPrompt === void 0 ? void 0 : pezzoPrompt.metadata),
properties: pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.properties,
cacheEnabled: false,
cacheHit: null,
request: {
timestamp: requestTimestamp,
body: requestBody,
},
};
if (pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.cache) {
baseReport.cacheEnabled = true;
const cachedRequest = yield this.pezzo.fetchCachedRequest(requestBody);
if (cachedRequest.hit === true) {
baseReport.cacheHit = true;
response = Object.assign(Object.assign({}, cachedRequest.data), { usage: {
prompt_tokens: 0,
completion_tokens: 0,
total_tokens: 0,
} });
reportPayload = Object.assign(Object.assign({}, baseReport), { response: {
timestamp: requestTimestamp,
body: response,
status: 200,
} });
}
else {
baseReport.cacheHit = false;
}
}
if (!(pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.cache) || ((pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.cache) && !baseReport.cacheHit)) {
try {
response = yield this.openai.chat.completions.create(Object.assign({}, requestBody), openaiOptions);
reportPayload = Object.assign(Object.assign({}, baseReport), { response: {
timestamp: new Date().toISOString(),
body: response,
status: 200,
} });
}
catch (err) {
error = err;
reportPayload = Object.assign(Object.assign({}, baseReport), { response: {
timestamp: new Date().toISOString(),
body: err.error,
status: err.status,
} });
}
}
const shouldWriteToCache = (pezzoOptions === null || pezzoOptions === void 0 ? void 0 : pezzoOptions.cache) &&
reportPayload.cacheHit === false &&
reportPayload.response.status === 200;
const reportRequest = this.pezzo.reportPromptExecution(reportPayload);
try {
yield Promise.all(shouldWriteToCache
? [reportRequest, this.pezzo.cacheRequest(requestBody, response)]
: [reportRequest]);
}
catch (error) {
console.error("Failed to report prompt execution", error);
}
if (error) {
throw error;
}
return response;
});
}
}
export { Pezzo, PezzoOpenAI, PromptExecutionStatus };
//# sourceMappingURL=index.esm.js.map