@assistant-ui/react
Version:
React components for AI chat.
178 lines (177 loc) • 6.18 kB
JavaScript
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, {
useExternalMessageConverter: () => useExternalMessageConverter
});
module.exports = __toCommonJS(external_message_converter_exports);
var import_react = require("react");
var import_ThreadMessageConverter = require("./ThreadMessageConverter.cjs");
var import_getExternalStoreMessage = require("./getExternalStoreMessage.cjs");
var import_ThreadMessageLike = require("./ThreadMessageLike.cjs");
var import_auto_status = require("./auto-status.cjs");
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,
result: output.result
};
} else {
throw new Error(
`Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`
);
}
} else {
const role = output.role;
switch (role) {
case "system":
case "user":
return output;
case "assistant":
if (assistantMessage.content.length === 0) {
assistantMessage.id = output.id;
assistantMessage.createdAt ??= output.createdAt;
assistantMessage.status ??= output.status;
}
assistantMessage.content.push(...output.content);
break;
default: {
const unsupportedRole = role;
throw new Error(`Unknown message role: ${unsupportedRole}`);
}
}
}
}
return assistantMessage;
};
var chunkExternalMessages = (callbackResults) => {
const results = [];
let isAssistant = false;
let inputs = [];
let outputs = [];
const flush = () => {
if (outputs.length) {
results.push({
inputs,
outputs
});
}
inputs = [];
outputs = [];
};
for (const callbackResult of callbackResults) {
for (const output of callbackResult.outputs) {
if (!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);
}
}
flush();
return results;
};
var useExternalMessageConverter = ({
callback,
messages,
isRunning
}) => {
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).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;
});
return 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.getExternalStoreMessage)(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;
}
);
}, [state, messages, isRunning]);
};
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 = {
useExternalMessageConverter
});
//# sourceMappingURL=external-message-converter.js.map
;