@assistant-ui/react
Version:
TypeScript/React library for AI Chat
116 lines • 4.43 kB
JavaScript
import { useState } from "react";
import { auiV0Decode, auiV0Encode } from "./auiV0.js";
import { useAssistantApi, } from "../../context/react/AssistantApiContext.js";
// Global WeakMap to store message ID mappings across adapter instances
const globalMessageIdMapping = new WeakMap();
class FormattedThreadHistoryAdapter {
parent;
formatAdapter;
constructor(parent, formatAdapter) {
this.parent = parent;
this.formatAdapter = formatAdapter;
}
async append(item) {
// Encode the message using the format adapter
const encoded = this.formatAdapter.encode(item);
const messageId = this.formatAdapter.getId(item.message);
// Delegate to parent's internal append method with the encoded format
return this.parent._appendWithFormat(item.parentId, messageId, this.formatAdapter.format, encoded);
}
async load() {
// Delegate to parent's internal load method with format filter
return this.parent._loadWithFormat(this.formatAdapter.format, (message) => this.formatAdapter.decode(message));
}
}
class AssistantCloudThreadHistoryAdapter {
cloudRef;
store;
constructor(cloudRef, store) {
this.cloudRef = cloudRef;
this.store = store;
}
get _getIdForLocalId() {
if (!globalMessageIdMapping.has(this.store.threadListItem())) {
globalMessageIdMapping.set(this.store.threadListItem(), {});
}
return globalMessageIdMapping.get(this.store.threadListItem());
}
withFormat(formatAdapter) {
return new FormattedThreadHistoryAdapter(this, formatAdapter);
}
async append({ parentId, message }) {
const { remoteId } = await this.store.threadListItem().initialize();
const task = this.cloudRef.current.threads.messages
.create(remoteId, {
parent_id: parentId
? ((await this._getIdForLocalId[parentId]) ?? parentId)
: null,
format: "aui/v0",
content: auiV0Encode(message),
})
.then(({ message_id }) => {
this._getIdForLocalId[message.id] = message_id;
return message_id;
});
this._getIdForLocalId[message.id] = task;
return task.then(() => { });
}
async load() {
const remoteId = this.store.threadListItem().getState().remoteId;
if (!remoteId)
return { messages: [] };
const { messages } = await this.cloudRef.current.threads.messages.list(remoteId, {
format: "aui/v0",
});
const payload = {
messages: messages
.filter((m) => m.format === "aui/v0")
.map(auiV0Decode)
.reverse(),
};
return payload;
}
// Internal methods for FormattedThreadHistoryAdapter
async _appendWithFormat(parentId, messageId, format, content) {
const { remoteId } = await this.store.threadListItem().initialize();
const task = this.cloudRef.current.threads.messages
.create(remoteId, {
parent_id: parentId
? ((await this._getIdForLocalId[parentId]) ?? parentId)
: null,
format,
content: content,
})
.then(({ message_id }) => {
this._getIdForLocalId[messageId] = message_id;
return message_id;
});
this._getIdForLocalId[messageId] = task;
return task.then(() => { });
}
async _loadWithFormat(format, decoder) {
const remoteId = this.store.threadListItem().getState().remoteId;
if (!remoteId)
return { messages: [] };
const { messages } = await this.cloudRef.current.threads.messages.list(remoteId, {
format,
});
return {
messages: messages
.filter((m) => m.format === format)
.map((m) => decoder({
id: m.id,
parent_id: m.parent_id,
format: m.format,
content: m.content,
}))
.reverse(),
};
}
}
export const useAssistantCloudThreadHistoryAdapter = (cloudRef) => {
const store = useAssistantApi();
const [adapter] = useState(() => new AssistantCloudThreadHistoryAdapter(cloudRef, store));
return adapter;
};
//# sourceMappingURL=AssistantCloudThreadHistoryAdapter.js.map