UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.

151 lines (150 loc) 6.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenAI = void 0; const wrapExport_1 = require("../agent/hooks/wrapExport"); const isPlainObject_1 = require("../helpers/isPlainObject"); function isResponse(response) { return ((0, isPlainObject_1.isPlainObject)(response) && "model" in response && typeof response.model === "string"); } function isCompletionResponse(response) { return ((0, isPlainObject_1.isPlainObject)(response) && "model" in response && typeof response.model === "string"); } class OpenAI { inspectResponse(agent, response, provider) { var _a; if (!isResponse(response)) { return; } let inputTokens = 0; let outputTokens = 0; if (response.usage) { if (typeof response.usage.input_tokens === "number") { inputTokens = response.usage.input_tokens; } if (typeof response.usage.output_tokens === "number") { outputTokens = response.usage.output_tokens; } } const aiStats = agent.getAIStatistics(); aiStats.onAICall({ provider: provider, model: (_a = response.model) !== null && _a !== void 0 ? _a : "", inputTokens: inputTokens, outputTokens: outputTokens, }); } inspectCompletionResponse(agent, response, provider) { var _a; if (!isCompletionResponse(response)) { return; } let inputTokens = 0; let outputTokens = 0; if (response.usage) { if (typeof response.usage.prompt_tokens === "number") { inputTokens = response.usage.prompt_tokens; } if (typeof response.usage.completion_tokens === "number") { outputTokens = response.usage.completion_tokens; } } const aiStats = agent.getAIStatistics(); aiStats.onAICall({ provider: provider, model: (_a = response.model) !== null && _a !== void 0 ? _a : "", inputTokens: inputTokens, outputTokens: outputTokens, }); } // The _client property is used to determine if the OpenAI client is an Azure OpenAI client or not. // See https://github.com/openai/openai-node/blob/master/src/core/resource.ts getProvider(exports, subject) { if ( // @ts-expect-error We don't know the type of exports exports.AzureOpenAI && // @ts-expect-error We don't know the type of subject subject._client && // @ts-expect-error We don't know the type of subject subject._client instanceof exports.AzureOpenAI) { return "azure"; } return "openai"; } getResponsesClass(exports) { if (exports.Responses) { return exports.Responses; // v4 } if (exports.OpenAI && exports.OpenAI.Responses) { return exports.OpenAI.Responses; // v5 } } getCompletionsClass(exports) { if (exports.Chat && exports.Chat.Completions) { return exports.Chat.Completions; // v4 } if (exports.OpenAI && exports.OpenAI.Chat && exports.OpenAI.Chat.Completions) { return exports.OpenAI.Chat.Completions; // v5 } } wrap(hooks) { // Note: Streaming is not supported yet hooks .addPackage("openai") .withVersion("^5.0.0 || ^4.0.0") .onRequire((exports, pkgInfo) => { const responsesClass = this.getResponsesClass(exports); if (responsesClass) { (0, wrapExport_1.wrapExport)(responsesClass.prototype, "create", pkgInfo, { kind: "ai_op", modifyReturnValue: (_, returnValue, agent, subject) => { if (returnValue instanceof Promise) { // Inspect the response after the promise resolves, it won't change the original promise returnValue .then((response) => { this.inspectResponse(agent, response, this.getProvider(exports, subject)); }) .catch((error) => { agent.onErrorThrownByInterceptor({ error: error, method: "create.<promise>", module: "openai", }); }); } return returnValue; }, }); } const completionsClass = this.getCompletionsClass(exports); if (completionsClass) { (0, wrapExport_1.wrapExport)(completionsClass.prototype, "create", pkgInfo, { kind: "ai_op", modifyReturnValue: (_, returnValue, agent, subject) => { if (returnValue instanceof Promise) { // Inspect the response after the promise resolves, it won't change the original promise returnValue .then((response) => { this.inspectCompletionResponse(agent, response, this.getProvider(exports, subject)); }) .catch((error) => { agent.onErrorThrownByInterceptor({ error: error, method: "create.<promise>", module: "openai", }); }); } return returnValue; }, }); } }); } } exports.OpenAI = OpenAI;