aiwrapper
Version:
A Universal AI Wrapper for JavaScript & TypeScript
233 lines (232 loc) • 7.63 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
import {
LangMessage
} from "../messages.js";
class OpenAIChatCompletionsStreamHandler {
constructor(messages, onResult) {
__publicField(this, "messages");
__publicField(this, "onResult");
__publicField(this, "currentAssistantMessage");
__publicField(this, "toolCallItems", /* @__PURE__ */ new Map());
__publicField(this, "toolArgBuffers", /* @__PURE__ */ new Map());
this.messages = messages;
this.onResult = onResult;
}
setOnResult(onResult) {
this.onResult = onResult;
}
handleEvent(data) {
var _a, _b, _c;
if (data == null) {
return;
}
if (data.finished) {
this.finalizeToolArguments();
if (this.currentAssistantMessage) {
(_a = this.onResult) == null ? void 0 : _a.call(this, this.currentAssistantMessage);
}
return;
}
if (!Array.isArray(data.choices) || data.choices.length === 0) {
return;
}
const choice = data.choices[0];
const delta = (_b = choice == null ? void 0 : choice.delta) != null ? _b : {};
if (delta.role === "assistant" && !this.currentAssistantMessage) {
this.ensureAssistantMessage();
}
if (delta.content !== void 0) {
this.handleContentDelta(delta.content);
}
if (delta.reasoning_content !== void 0) {
this.handleReasoningDelta(delta.reasoning_content);
}
if (delta.tool_calls) {
this.handleToolCalls(delta.tool_calls);
}
if (delta.function_call) {
this.handleFunctionCall(delta.function_call);
}
if (this.currentAssistantMessage) {
(_c = this.onResult) == null ? void 0 : _c.call(this, this.currentAssistantMessage);
}
}
ensureAssistantMessage() {
if (!this.currentAssistantMessage) {
this.currentAssistantMessage = new LangMessage("assistant", []);
this.messages.push(this.currentAssistantMessage);
}
return this.currentAssistantMessage;
}
getOrCreateTextItem() {
const message = this.ensureAssistantMessage();
const lastItem = message.items[message.items.length - 1];
if (lastItem && lastItem.type === "text") {
return lastItem;
}
const textItem = { type: "text", text: "" };
message.items.push(textItem);
return textItem;
}
getOrCreateReasoningItem() {
const message = this.ensureAssistantMessage();
const lastItem = message.items[message.items.length - 1];
if (lastItem && lastItem.type === "reasoning") {
return lastItem;
}
const reasoningItem = { type: "reasoning", text: "" };
message.items.push(reasoningItem);
return reasoningItem;
}
appendText(delta) {
if (typeof delta !== "string" || delta.length === 0) {
return;
}
const textItem = this.getOrCreateTextItem();
textItem.text += delta;
}
appendReasoning(delta) {
if (typeof delta !== "string" || delta.length === 0) {
return;
}
const reasoningItem = this.getOrCreateReasoningItem();
reasoningItem.text += delta;
}
appendImageFromUrl(url) {
if (typeof url !== "string" || url.length === 0) {
return;
}
const message = this.ensureAssistantMessage();
const imageItem = { type: "image", url };
message.items.push(imageItem);
}
appendImageFromBase64(base64, mimeType) {
if (typeof base64 !== "string" || base64.length === 0) {
return;
}
const message = this.ensureAssistantMessage();
const imageItem = {
type: "image",
base64,
mimeType: mimeType || "image/png"
};
message.items.push(imageItem);
}
handleContentDelta(contentDelta) {
var _a;
if (typeof contentDelta === "string") {
this.appendText(contentDelta);
return;
}
if (!Array.isArray(contentDelta)) {
return;
}
for (const part of contentDelta) {
if (!part) continue;
if (part.type === "text" && typeof part.text === "string") {
this.appendText(part.text);
} else if (part.type === "reasoning" && typeof part.text === "string") {
this.appendReasoning(part.text);
} else if (part.type === "image_url" && ((_a = part.image_url) == null ? void 0 : _a.url)) {
this.appendImageFromUrl(part.image_url.url);
} else if ((part.type === "output_image" || part.type === "inline_data") && (part.b64_json || part.data)) {
const base64 = part.b64_json || part.data;
const mimeType = part.mime_type || part.mimeType || "image/png";
this.appendImageFromBase64(base64, mimeType);
}
}
}
handleReasoningDelta(reasoningDelta) {
if (typeof reasoningDelta === "string") {
this.appendReasoning(reasoningDelta);
return;
}
if (!Array.isArray(reasoningDelta)) {
return;
}
for (const part of reasoningDelta) {
if (!part) continue;
if (typeof part === "string") {
this.appendReasoning(part);
} else if (typeof part.text === "string") {
this.appendReasoning(part.text);
}
}
}
handleToolCalls(toolCalls) {
var _a, _b, _c;
for (const tc of toolCalls) {
if (!tc) continue;
const id = typeof tc.id === "string" ? tc.id : tc.index !== void 0 ? String(tc.index) : `tool_call_${this.toolCallItems.size}`;
const toolItem = this.getOrCreateToolItem(id);
const func = (_a = tc.function) != null ? _a : {};
if (typeof func.name === "string" && func.name.length > 0) {
toolItem.name = func.name;
}
if (typeof func.arguments === "string") {
const existing = (_b = this.toolArgBuffers.get(id)) != null ? _b : "";
const updated = existing + func.arguments;
this.toolArgBuffers.set(id, updated);
try {
toolItem.arguments = JSON.parse(updated);
} catch (e) {
}
}
(_c = this.onResult) == null ? void 0 : _c.call(this, this.ensureAssistantMessage());
}
}
handleFunctionCall(functionCall) {
var _a;
const id = "function_call";
const toolItem = this.getOrCreateToolItem(id);
if (typeof functionCall.name === "string") {
toolItem.name = functionCall.name;
}
if (typeof functionCall.arguments === "string") {
const existing = (_a = this.toolArgBuffers.get(id)) != null ? _a : "";
const updated = existing + functionCall.arguments;
this.toolArgBuffers.set(id, updated);
try {
toolItem.arguments = JSON.parse(updated);
} catch (e) {
}
}
}
getOrCreateToolItem(id) {
let toolItem = this.toolCallItems.get(id);
if (!toolItem) {
const message = this.ensureAssistantMessage();
toolItem = {
type: "tool",
callId: id,
name: "",
arguments: {}
};
message.items.push(toolItem);
this.toolCallItems.set(id, toolItem);
}
return toolItem;
}
finalizeToolArguments() {
for (const [id, buffer] of this.toolArgBuffers.entries()) {
const toolItem = this.toolCallItems.get(id);
if (!toolItem) continue;
if (!buffer) {
toolItem.arguments = {};
continue;
}
try {
toolItem.arguments = JSON.parse(buffer);
} catch (e) {
toolItem.arguments = {};
}
}
this.toolArgBuffers.clear();
}
}
export {
OpenAIChatCompletionsStreamHandler
};
//# sourceMappingURL=openai-chat-completions-stream-handler.js.map