@assistant-ui/react
Version:
Typescript/React library for AI Chat
260 lines (259 loc) • 9.42 kB
JavaScript
"use client";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/runtimes/external-store/external-message-converter.tsx
var external_message_converter_exports = {};
__export(external_message_converter_exports, {
convertExternalMessages: () => convertExternalMessages,
useExternalMessageConverter: () => useExternalMessageConverter
});
module.exports = __toCommonJS(external_message_converter_exports);
var import_react = require("react");
var import_ThreadMessageConverter = require("./ThreadMessageConverter.js");
var import_getExternalStoreMessage = require("./getExternalStoreMessage.js");
var import_ThreadMessageLike = require("./ThreadMessageLike.js");
var import_auto_status = require("./auto-status.js");
var joinExternalMessages = (messages) => {
const assistantMessage = {
role: "assistant",
content: []
};
for (const output of messages) {
if (output.role === "tool") {
const toolCallIdx = assistantMessage.content.findIndex(
(c) => c.type === "tool-call" && c.toolCallId === output.toolCallId
);
if (toolCallIdx !== -1) {
const toolCall = assistantMessage.content[toolCallIdx];
if (output.toolName) {
if (toolCall.toolName !== output.toolName)
throw new Error(
`Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`
);
}
assistantMessage.content[toolCallIdx] = {
...toolCall,
...{
[import_getExternalStoreMessage.symbolInnerMessage]: [
...toolCall[import_getExternalStoreMessage.symbolInnerMessage] ?? [],
output
]
},
result: output.result
};
} else {
throw new Error(
`Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`
);
}
} else {
const role = output.role;
const content = (typeof output.content === "string" ? [{ type: "text", text: output.content }] : output.content).map((c) => ({
...c,
...{ [import_getExternalStoreMessage.symbolInnerMessage]: [output] }
}));
switch (role) {
case "system":
case "user":
return {
...output,
content
};
case "assistant":
if (assistantMessage.content.length === 0) {
assistantMessage.id = output.id;
assistantMessage.createdAt ??= output.createdAt;
assistantMessage.status ??= output.status;
if (output.attachments) {
assistantMessage.attachments = [
...assistantMessage.attachments ?? [],
...output.attachments
];
}
if (output.metadata) {
assistantMessage.metadata ??= {};
if (output.metadata.unstable_annotations) {
assistantMessage.metadata.unstable_annotations = [
...assistantMessage.metadata.unstable_annotations ?? [],
...output.metadata.unstable_annotations
];
}
if (output.metadata.unstable_data) {
assistantMessage.metadata.unstable_data = [
...assistantMessage.metadata.unstable_data ?? [],
...output.metadata.unstable_data
];
}
if (output.metadata.steps) {
assistantMessage.metadata.steps = [
...assistantMessage.metadata.steps ?? [],
...output.metadata.steps
];
}
if (output.metadata.custom) {
assistantMessage.metadata.custom = {
...assistantMessage.metadata.custom ?? {},
...output.metadata.custom
};
}
}
}
assistantMessage.content.push(...content);
break;
default: {
const unsupportedRole = role;
throw new Error(`Unknown message role: ${unsupportedRole}`);
}
}
}
}
return assistantMessage;
};
var chunkExternalMessages = (callbackResults, joinStrategy) => {
const results = [];
let isAssistant = false;
let pendingNone = false;
let inputs = [];
let outputs = [];
const flush = () => {
if (outputs.length) {
results.push({
inputs,
outputs
});
}
inputs = [];
outputs = [];
isAssistant = false;
pendingNone = false;
};
for (const callbackResult of callbackResults) {
for (const output of callbackResult.outputs) {
if (pendingNone && output.role !== "tool" || !isAssistant || output.role === "user" || output.role === "system") {
flush();
}
isAssistant = output.role === "assistant" || output.role === "tool";
if (inputs.at(-1) !== callbackResult.input) {
inputs.push(callbackResult.input);
}
outputs.push(output);
if (output.role === "assistant" && (output.convertConfig?.joinStrategy === "none" || joinStrategy === "none")) {
pendingNone = true;
}
}
}
flush();
return results;
};
var convertExternalMessages = (messages, callback, isRunning) => {
const callbackResults = [];
for (const message of messages) {
const output = callback(message);
const outputs = Array.isArray(output) ? output : [output];
const result = { input: message, outputs };
callbackResults.push(result);
}
const chunks = chunkExternalMessages(callbackResults);
return chunks.map((message, idx) => {
const isLast = idx === chunks.length - 1;
const autoStatus = (0, import_auto_status.getAutoStatus)(isLast, isRunning);
const newMessage = (0, import_ThreadMessageLike.fromThreadMessageLike)(
joinExternalMessages(message.outputs),
idx.toString(),
autoStatus
);
newMessage[import_getExternalStoreMessage.symbolInnerMessage] = message.inputs;
return newMessage;
});
};
var useExternalMessageConverter = ({
callback,
messages,
isRunning,
joinStrategy
}) => {
const state = (0, import_react.useMemo)(
() => ({
callback,
callbackCache: /* @__PURE__ */ new WeakMap(),
chunkCache: /* @__PURE__ */ new WeakMap(),
converterCache: new import_ThreadMessageConverter.ThreadMessageConverter()
}),
[callback]
);
return (0, import_react.useMemo)(() => {
const callbackResults = [];
for (const message of messages) {
let result = state.callbackCache.get(message);
if (!result) {
const output = state.callback(message);
const outputs = Array.isArray(output) ? output : [output];
result = { input: message, outputs };
state.callbackCache.set(message, result);
}
callbackResults.push(result);
}
const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(
(m) => {
const key = m.outputs[0];
if (!key) return m;
const cached = state.chunkCache.get(key);
if (cached && shallowArrayEqual(cached.outputs, m.outputs))
return cached;
state.chunkCache.set(key, m);
return m;
}
);
const threadMessages = state.converterCache.convertMessages(
chunks,
(cache, message, idx) => {
const isLast = idx === chunks.length - 1;
const autoStatus = (0, import_auto_status.getAutoStatus)(isLast, isRunning);
if (cache && (cache.role !== "assistant" || !(0, import_auto_status.isAutoStatus)(cache.status) || cache.status === autoStatus)) {
const inputs = (0, import_getExternalStoreMessage.getExternalStoreMessages)(cache);
if (shallowArrayEqual(inputs, message.inputs)) {
return cache;
}
}
const newMessage = (0, import_ThreadMessageLike.fromThreadMessageLike)(
joinExternalMessages(message.outputs),
idx.toString(),
autoStatus
);
newMessage[import_getExternalStoreMessage.symbolInnerMessage] = message.inputs;
return newMessage;
}
);
threadMessages[import_getExternalStoreMessage.symbolInnerMessage] = messages;
return threadMessages;
}, [state, messages, isRunning, joinStrategy]);
};
var shallowArrayEqual = (a, b) => {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
convertExternalMessages,
useExternalMessageConverter
});
//# sourceMappingURL=external-message-converter.js.map
;