UNPKG

@codixfy/gemini

Version:

An npm package for nodejs that makes easier working with Gemini AI API. Includes some useful methods solving common tasks, helping quick and stable development.

201 lines (199 loc) 6.08 kB
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); // src/providers/gemini.ts var { GoogleGenerativeAI, HarmBlockThreshold, HarmCategory } = __require("@google/generative-ai"); var Base64 = __require("base64-js"); var Gemini = class { genAI; model; currentModel; apiKey; constructor(apiKey, options) { var _a, _b, _c, _d; this.genAI = new GoogleGenerativeAI(apiKey); this.apiKey = apiKey; this.currentModel = "gemini-1.5-flash"; if (options == null ? void 0 : options.model) { this.currentModel = options.model; if (this.currentModel === "gemini-2.0-flash") { this.currentModel += "-exp"; } if (this.currentModel === "gemini-2.0-flash" && !(options == null ? void 0 : options.useLatestModel)) { this.currentModel += "-latest"; } } this.model = this.genAI.getGenerativeModel({ model: this.currentModel, safetySettings: [ { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: ((_a = options == null ? void 0 : options.safetySettings) == null ? void 0 : _a.blockDangerousContent) === true ? HarmBlockThreshold.BLOCK_ONLY_HIGH : HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: ((_b = options == null ? void 0 : options.safetySettings) == null ? void 0 : _b.blockExplicitContent) === true ? HarmBlockThreshold.BLOCK_ONLY_HIGH : HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: ((_c = options == null ? void 0 : options.safetySettings) == null ? void 0 : _c.blockHarassmentContent) === true ? HarmBlockThreshold.BLOCK_ONLY_HIGH : HarmBlockThreshold.BLOCK_NONE }, { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: ((_d = options == null ? void 0 : options.safetySettings) == null ? void 0 : _d.blockHateContent) === true ? HarmBlockThreshold.BLOCK_ONLY_HIGH : HarmBlockThreshold.BLOCK_NONE } ], systemInstruction: (options == null ? void 0 : options.instructions) || void 0 }); } // Used to send a message without any context async ask(message, extra) { const partsWithFiles = []; if ((extra == null ? void 0 : extra.files) && extra.files.length > 0) { if (this.currentModel === "gemini-pro-vision") { throw new Error( `This model does not support files. Current model: ${this.currentModel}` ); } for (const file of extra.files) { partsWithFiles.push( { text: "Link: " + file } ); } } const contents = [ { role: "user", parts: [ { text: message }, ...partsWithFiles ] } ]; const result = await this.model.generateContentStream({ contents }); const buffer = []; for await (const response of result.stream) { buffer.push(response.text()); if (extra == null ? void 0 : extra.stream) { extra.stream(response.text()); } } return buffer.join(" "); } createChat(chartContext) { return new GeminiChat( this.model, chartContext === null ? [] : chartContext, this.currentModel ); } }; var GeminiChat = class { model; chatContext; currentModel; constructor(model, chatContext, currentModel) { this.model = model; this.chatContext = chatContext; this.currentModel = currentModel; } async send(message, extra) { const partsWithFiles = []; if ((extra == null ? void 0 : extra.files) && extra.files.length > 0) { if (this.currentModel === "gemini-pro-vision") { throw new Error( `This model does not support images. Current model: ${this.currentModel}` ); } for (const file of extra.files) { partsWithFiles.push( { text: "Link: " + file } ); } } if (!this.chatContext) { this.chatContext = []; } this.chatContext.push({ role: "user", parts: [ { text: message }, ...partsWithFiles ] }); const contents = this.chatContext; const result = await this.model.generateContentStream({ contents }); const buffer = []; for await (const response of result.stream) { buffer.push(response.text()); if (extra == null ? void 0 : extra.stream) { extra.stream(response.text()); } } return buffer.join(" "); } async reset() { this.chatContext = []; } async save() { return this.chatContext; } async load(context) { this.chatContext = context; } }; var GeminiUtils = class { static async fileToGenerativePart(file) { const mimeType = await this.mimeTypeFromFile(file); const image64 = await fetch(file).then((r) => r.arrayBuffer()).then((a) => Base64.fromByteArray(new Uint8Array(a))); return { inline_data: { data: image64, mime_type: mimeType } }; } static async mimeTypeFromFile(file) { const extension = file.split(".")[file.split(".").length - 1]; switch (extension) { case "jpg": case "jpeg": return "image/jpeg"; case "png": return "image/png"; case "gif": return "image/gif"; case "webp": return "image/webp"; case "mp4": return "video/mp4"; case "wav": return "audio/wav"; case "mp3": return "audio/mp3"; case "aac": return "audio/aac"; default: throw new Error("Unsupported file type (${extension})"); } } }; export { Gemini, GeminiUtils };