aiwrapper
Version:
A Universal AI Wrapper for JavaScript & TypeScript
235 lines (234 loc) • 7.77 kB
JavaScript
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