UNPKG

aiwrapper

Version:

A Universal AI Wrapper for JavaScript & TypeScript

235 lines (234 loc) 7.77 kB
var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import extractJSON from "./json/extract-json.js"; class LangMessage { constructor(role, init, meta) { __publicField(this, "role"); __publicField(this, "items"); __publicField(this, "meta"); this.role = role; this.items = Array.isArray(init) ? init : [{ type: "text", text: init }]; this.meta = meta; } get text() { return this.items.filter((item) => item.type === "text").map((item) => item.text).join("\n\n"); } get reasoning() { return this.items.filter((item) => item.type === "reasoning").map((item) => item.text).join("\n\n"); } get object() { const text = this.text; if (text && text.length > 0) return extractJSON(text); return null; } get toolRequests() { return this.items.filter((item) => item.type === "tool").map((item) => item); } get toolResults() { return this.items.filter((item) => item.type === "tool-result").map((item) => item); } get images() { return this.items.filter((item) => item.type === "image").map((item) => item); } } class LangMessages extends Array { constructor(initial, opts) { super(...Array.isArray(initial) ? [] : []); __publicField(this, "availableTools"); __publicField(this, "finished", false); __publicField(this, "aborted", false); __publicField(this, "instructions"); if (typeof initial === "string") { this.addUserMessage(initial); } else if (initial instanceof LangMessages) { for (const m of initial) { this.push(m); } if (opts == null ? void 0 : opts.tools) { this.availableTools = opts.tools; } else if (initial.availableTools) { this.availableTools = initial.availableTools; } } else if (Array.isArray(initial)) { for (const m of initial) { if (m instanceof LangMessage) { this.push(m); } else { this.push(new LangMessage(m.role, m.items, m.meta)); } } } if (opts == null ? void 0 : opts.tools) { this.availableTools = opts.tools; } } /** * Last assistant message as text */ get answer() { for (let i = this.length - 1; i >= 0; i--) { const msg = this[i]; if (msg.role === "assistant") { return msg.text; } } return ""; } get object() { const answer = this.answer; if (answer.length > 0) { return extractJSON(answer); } return null; } get assistantImages() { return this.getImagesFromLastMessage("assistant"); } get userImages() { return this.getImagesFromLastMessage("user"); } getImagesFromLastMessage(role) { let lastMessageByRole; for (let i = this.length - 1; i >= 0; i--) { if (this[i].role === role) { lastMessageByRole = this[i]; break; } } if (!lastMessageByRole) return []; return lastMessageByRole.images; } addUserMessage(content) { this.push(new LangMessage("user", content)); return this; } addUserItems(items) { this.push(new LangMessage("user", items)); return this; } addToolResultsMessage(items) { this.push(new LangMessage("tool-results", items)); return this; } addUserImages(imageOrImages) { const images = Array.isArray(imageOrImages) ? imageOrImages : [imageOrImages]; const items = images.map((image) => this.createImageMessageItem(image)); return this.addUserItems(items); } createImageMessageItem(image) { switch (image.kind) { case "url": return { type: "image", url: image.url }; case "base64": return { type: "image", base64: image.base64, mimeType: image.mimeType }; case "bytes": return { type: "image", base64: LangMessages.encodeBytesAsBase64(image.bytes), mimeType: image.mimeType }; case "blob": throw new Error("LangMessages.addUserImages does not support Blob inputs yet. Convert the Blob to base64 or a URL first."); default: throw new Error("Unsupported image input type."); } } static encodeBytesAsBase64(bytes) { const view = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes); const globalObject = typeof globalThis !== "undefined" ? globalThis : {}; if (globalObject.Buffer) { return globalObject.Buffer.from(view).toString("base64"); } const btoaFn = typeof globalObject.btoa === "function" ? globalObject.btoa.bind(globalObject) : void 0; if (btoaFn) { let binary = ""; const chunkSize = 32768; for (let i = 0; i < view.length; i += chunkSize) { const chunk = view.subarray(i, i + chunkSize); binary += String.fromCharCode(...chunk); } return btoaFn(binary); } throw new Error("Unable to convert byte images to base64 in this environment. Provide base64 or URL images instead."); } addAssistantMessage(content, meta) { this.push(new LangMessage("assistant", content, meta)); return this; } addAssistantItems(items, meta) { this.push(new LangMessage("assistant", items, meta)); return this; } async executeRequestedTools(meta) { const last = this.length > 0 ? this[this.length - 1] : void 0; if (!last || last.role !== "assistant" || last.items.length === 0) { return null; } const toolRequests = last.toolRequests; const toolsWithHandlers = (this.availableTools || []).filter( (t) => "handler" in t ); const toolResults = []; for (const requestedTool of toolRequests) { const toolName = requestedTool.name; if (!toolName) continue; const tool = toolsWithHandlers.find((t) => t.name === toolName); if (!tool) { const id2 = requestedTool.callId; toolResults.push({ toolId: id2, name: toolName, result: { error: true, name: "ToolNotFound", message: `Tool "${toolName}" is not available. Available tools: ${toolsWithHandlers.map((t) => t.name).join(", ") || "none"}` } }); continue; } let result; try { result = await Promise.resolve(tool.handler(requestedTool.arguments || {})); } catch (error) { result = __spreadValues({ error: true, name: error.name, message: error.message }, Object.fromEntries(Object.entries(error))); } const id = requestedTool.callId; toolResults.push({ toolId: id, name: toolName, result }); } if (toolResults.length > 0) { this.addToolResultsMessage(toolResults.map((result) => ({ type: "tool-result", name: result.name, callId: result.toolId, result: result.result }))); } return this[this.length - 1]; } toString() { const out = []; for (const msg of this) { out.push(`${msg.role}: ${JSON.stringify(msg.items, null, 2)}`); } return out.join("\n\n"); } } export { LangMessage, LangMessages }; //# sourceMappingURL=messages.js.map