n8n-editor-ui
Version:
Workflow Editor UI for n8n
810 lines (807 loc) • 37.2 kB
JavaScript
;
(function () {
System.register(["./vue.runtime.esm-bundler-legacy--Sn1h8On.js", "./useTelemetry-legacy-B3pzzkAE.js", "./useToast-legacy-C4Vu5mt9.js", "./constants-legacy-TKxWCqvM.js", "./_baseOrderBy-legacy-CB2Dh5d_.js", "./retry-legacy-CTwsGM7o.js", "./constants-legacy-DjFSod4r.js", "./fileUtils-legacy-BbiGYBne.js"], function (_export, _context) {
"use strict";
var computed, ref, v4_default, useTelemetry, useToast, deepCopy, emptyChatModelsResponse, chatHubProviderSchema, defineStore, streamRequest, useRootStore, makeRestApiRequest, retry, CHAT_STORE, CHAT_VIEW, convertFileToBinaryData, STREAM_SEPARATOR, fetchChatModelsApi, stopGenerationApi, fetchConversationsApi, updateConversationApi, updateConversationTitleApi, deleteConversationApi, fetchSingleConversationApi, fetchAgentApi, createAgentApi, updateAgentApi, deleteAgentApi, fetchChatSettingsApi, fetchChatProviderSettingsApi, updateChatSettingsApi, useChatStore;
function sendMessageApi(ctx, payload, onMessageUpdated, onDone, onError) {
streamRequest(ctx, "/chat/conversations/send", payload, onMessageUpdated, onDone, onError, STREAM_SEPARATOR);
}
function editMessageApi(ctx, sessionId, editId, payload, onMessageUpdated, onDone, onError) {
streamRequest(ctx, `/chat/conversations/${sessionId}/messages/${editId}/edit`, payload, onMessageUpdated, onDone, onError, STREAM_SEPARATOR);
}
function regenerateMessageApi(ctx, sessionId, retryId, payload, onMessageUpdated, onDone, onError) {
streamRequest(ctx, `/chat/conversations/${sessionId}/messages/${retryId}/regenerate`, payload, onMessageUpdated, onDone, onError, STREAM_SEPARATOR);
}
function buildChatAttachmentUrl(context, sessionId, messageId, attachmentIndex) {
return `${context.baseUrl}/chat/conversations/${sessionId}/messages/${messageId}/attachments/${attachmentIndex}`;
}
//#endregion
//#region src/features/ai/chatHub/chat.utils.ts
function findOneFromModelsResponse(response) {
for (const provider of chatHubProviderSchema.options) if (response[provider].models.length > 0) return response[provider].models[0];
}
function getRelativeDate(now, dateString) {
const date = new Date(dateString);
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const lastWeek = new Date(today);
lastWeek.setDate(lastWeek.getDate() - 7);
const conversationDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
if (conversationDate.getTime() === today.getTime()) return "Today";else if (conversationDate.getTime() === yesterday.getTime()) return "Yesterday";else if (conversationDate >= lastWeek) return "This week";else return "Older";
}
function groupConversationsByDate(sessions) {
const now = /* @__PURE__ */new Date();
const groups = /* @__PURE__ */new Map();
for (const session of sessions) {
const group = getRelativeDate(now, session.lastMessageAt ?? session.updatedAt);
if (!groups.has(group)) groups.set(group, []);
groups.get(group).push(session);
}
return ["Today", "Yesterday", "This week", "Older"].flatMap(groupName => {
const sessions$1 = groups.get(groupName) ?? [];
return sessions$1.length > 0 ? [{
group: groupName,
sessions: sessions$1.sort((a, b) => Date.parse(b.lastMessageAt ?? b.updatedAt) - Date.parse(a.lastMessageAt ?? a.updatedAt))
}] : [];
});
}
function getAgentRoute(model) {
if (model.provider === "n8n") return {
name: CHAT_VIEW,
query: {
workflowId: model.workflowId
}
};
if (model.provider === "custom-agent") return {
name: CHAT_VIEW,
query: {
agentId: model.agentId
}
};
return {
name: CHAT_VIEW
};
}
function flattenModel(model) {
return {
provider: model.provider,
model: model?.provider === "n8n" || model?.provider === "custom-agent" ? null : model?.model ?? null,
workflowId: model?.provider === "n8n" ? model.workflowId : null,
agentId: model?.provider === "custom-agent" ? model.agentId : null
};
}
function unflattenModel(messageOrSession) {
if (messageOrSession.provider === null) return null;
switch (messageOrSession.provider) {
case "custom-agent":
if (!messageOrSession.agentId) return null;
return {
provider: "custom-agent",
agentId: messageOrSession.agentId
};
case "n8n":
if (!messageOrSession.workflowId) return null;
return {
provider: "n8n",
workflowId: messageOrSession.workflowId
};
default:
if (messageOrSession.model === null) return null;
return {
provider: messageOrSession.provider,
model: messageOrSession.model
};
}
}
function filterAndSortAgents(models, filter) {
let filtered = models;
if (filter.search.trim()) {
const query = filter.search.toLowerCase();
filtered = filtered.filter(model => model.name.toLowerCase().includes(query));
}
if (filter.provider !== "") filtered = filtered.filter(model => model.model.provider === filter.provider);
filtered = [...filtered].sort((a, b) => {
const dateAStr = a[filter.sortBy];
const dateBStr = b[filter.sortBy];
const dateA = dateAStr ? Date.parse(dateAStr) : void 0;
const dateB = dateBStr ? Date.parse(dateBStr) : void 0;
if (dateA && dateB) return dateB - dateA;
if (dateA && !dateB) return -1;
if (!dateA && dateB) return 1;
return 0;
});
return filtered;
}
function stringifyModel(model) {
return `${model.provider}::${model.provider === "custom-agent" ? model.agentId : model.provider === "n8n" ? model.workflowId : model.model}`;
}
function fromStringToModel(value) {
const [provider, identifier] = value.split("::");
const parsedProvider = chatHubProviderSchema.safeParse(provider).data;
if (!parsedProvider) return;
return parsedProvider === "n8n" ? {
provider: "n8n",
workflowId: identifier
} : parsedProvider === "custom-agent" ? {
provider: "custom-agent",
agentId: identifier
} : {
provider: parsedProvider,
model: identifier
};
}
function isMatchedAgent(agent, model) {
if (model.provider === "n8n") return agent.model.provider === "n8n" && agent.model.workflowId === model.workflowId;
if (model.provider === "custom-agent") return agent.model.provider === "custom-agent" && agent.model.agentId === model.agentId;
return agent.model.provider === model.provider && agent.model.model === model.model;
}
function createAiMessageFromStreamingState(sessionId, messageId, streaming) {
return {
id: messageId,
sessionId,
type: "ai",
name: "AI",
content: "",
executionId: streaming?.executionId ?? null,
status: "running",
createdAt: (/* @__PURE__ */new Date()).toISOString(),
updatedAt: (/* @__PURE__ */new Date()).toISOString(),
previousMessageId: streaming?.previousMessageId ?? null,
retryOfMessageId: streaming?.retryOfMessageId ?? null,
revisionOfMessageId: null,
responses: [],
alternatives: [],
attachments: [],
...(streaming?.model ? flattenModel(streaming.model) : {
provider: null,
model: null,
workflowId: null,
agentId: null
})
};
}
function buildUiMessages(sessionId, conversation, streaming) {
const messagesToShow = [];
let foundRunning = false;
for (let index = 0; index < conversation.activeMessageChain.length; index++) {
const id = conversation.activeMessageChain[index];
const message = conversation.messages[id];
if (!message) continue;
foundRunning = foundRunning || message.status === "running";
if (foundRunning || streaming?.sessionId !== sessionId || message.type !== "ai") {
messagesToShow.push(message);
continue;
}
if (streaming.retryOfMessageId === id && !streaming.messageId) {
messagesToShow.push({
...message,
content: "",
status: "running"
});
foundRunning = true;
continue;
}
if (index === conversation.activeMessageChain.length - 1) {
messagesToShow.push({
...message,
status: "running"
});
foundRunning = true;
continue;
}
messagesToShow.push(message);
}
if (!foundRunning && streaming?.sessionId === sessionId && !streaming.messageId && streaming.retryOfMessageId === null && streaming.promptId === messagesToShow[messagesToShow.length - 1]?.id) messagesToShow.push(createAiMessageFromStreamingState(sessionId, v4_default(), streaming));
return messagesToShow;
}
function isLlmProvider(provider) {
return provider !== "n8n" && provider !== "custom-agent";
}
function isLlmProviderModel(model) {
return isLlmProvider(model?.provider);
}
function createSessionFromStreamingState(streaming) {
return {
id: streaming.sessionId,
title: "New Chat",
ownerId: "",
lastMessageAt: (/* @__PURE__ */new Date()).toISOString(),
credentialId: null,
agentName: streaming.agentName,
createdAt: (/* @__PURE__ */new Date()).toISOString(),
updatedAt: (/* @__PURE__ */new Date()).toISOString(),
tools: streaming.tools,
...flattenModel(streaming.model)
};
}
//#endregion
//#region src/features/ai/chatHub/chat.store.ts
_export({
a: fromStringToModel,
c: isLlmProvider,
d: stringifyModel,
f: unflattenModel,
i: flattenModel,
l: isLlmProviderModel,
n: filterAndSortAgents,
o: getAgentRoute,
p: buildChatAttachmentUrl,
r: findOneFromModelsResponse,
s: groupConversationsByDate,
u: isMatchedAgent
});
return {
setters: [function (_vueRuntimeEsmBundlerLegacy003Js) {
computed = _vueRuntimeEsmBundlerLegacy003Js.C;
ref = _vueRuntimeEsmBundlerLegacy003Js.It;
}, function (_useTelemetryLegacy00HJs) {
v4_default = _useTelemetryLegacy00HJs.Ro;
useTelemetry = _useTelemetryLegacy00HJs.t;
}, function (_useToastLegacy00JJs) {
useToast = _useToastLegacy00JJs.t;
}, function (_constantsLegacy00TJs) {
deepCopy = _constantsLegacy00TJs.Da;
emptyChatModelsResponse = _constantsLegacy00TJs.ni;
chatHubProviderSchema = _constantsLegacy00TJs.ti;
}, function (_baseOrderByLegacy00ZJs) {
defineStore = _baseOrderByLegacy00ZJs.k;
streamRequest = _baseOrderByLegacy00ZJs.p;
useRootStore = _baseOrderByLegacy00ZJs.r;
makeRestApiRequest = _baseOrderByLegacy00ZJs.u;
}, function (_retryLegacy01lJs) {
retry = _retryLegacy01lJs.t;
}, function (_constantsLegacy03lJs) {
CHAT_STORE = _constantsLegacy03lJs.c;
CHAT_VIEW = _constantsLegacy03lJs.l;
}, function (_fileUtilsLegacy03pJs) {
convertFileToBinaryData = _fileUtilsLegacy03pJs.t;
}],
execute: function () {
//#region src/features/ai/chatHub/chat.api.ts
STREAM_SEPARATOR = "\n";
_export("m", fetchChatModelsApi = async (context, payload) => {
return await makeRestApiRequest(context, "POST", "/chat/models", payload);
});
stopGenerationApi = async (context, sessionId, messageId) => {
await makeRestApiRequest(context, "POST", `/chat/conversations/${sessionId}/messages/${messageId}/stop`);
};
fetchConversationsApi = async (context, limit, cursor) => {
const queryParams = new URLSearchParams();
queryParams.append("limit", limit.toString());
if (cursor) queryParams.append("cursor", cursor);
return await makeRestApiRequest(context, "GET", `/chat/conversations?${queryParams.toString()}`);
};
updateConversationApi = async (context, sessionId, updates) => {
return await makeRestApiRequest(context, "PATCH", `/chat/conversations/${sessionId}`, updates);
};
updateConversationTitleApi = async (context, sessionId, title) => {
return await updateConversationApi(context, sessionId, {
title
});
};
deleteConversationApi = async (context, sessionId) => {
await makeRestApiRequest(context, "DELETE", `/chat/conversations/${sessionId}`);
};
fetchSingleConversationApi = async (context, sessionId) => {
return await makeRestApiRequest(context, "GET", `/chat/conversations/${sessionId}`);
};
fetchAgentApi = async (context, agentId) => {
return await makeRestApiRequest(context, "GET", `/chat/agents/${agentId}`);
};
createAgentApi = async (context, payload) => {
return await makeRestApiRequest(context, "POST", "/chat/agents", payload);
};
updateAgentApi = async (context, agentId, payload) => {
return await makeRestApiRequest(context, "POST", `/chat/agents/${agentId}`, payload);
};
deleteAgentApi = async (context, agentId) => {
await makeRestApiRequest(context, "DELETE", `/chat/agents/${agentId}`);
};
fetchChatSettingsApi = async context => {
return (await makeRestApiRequest(context, "GET", "/chat/settings")).providers;
};
fetchChatProviderSettingsApi = async (context, provider) => {
return (await makeRestApiRequest(context, "GET", "/chat/settings/" + provider)).settings;
};
updateChatSettingsApi = async (context, settings) => {
return await makeRestApiRequest(context, "POST", "/chat/settings", {
payload: settings
});
};
_export("t", useChatStore = defineStore(CHAT_STORE, () => {
const rootStore = useRootStore();
const toast = useToast();
const telemetry = useTelemetry();
const agents = ref();
const sessions = ref({
byId: {},
ids: null,
hasMore: false,
nextCursor: null
});
const sessionsLoadingMore = ref(false);
const streaming = ref();
const settingsLoading = ref(false);
const settings = ref(null);
const conversationsBySession = ref(/* @__PURE__ */new Map());
const getConversation = sessionId => conversationsBySession.value.get(sessionId);
const getActiveMessages = sessionId => {
const conversation = getConversation(sessionId);
if (!conversation) return [];
return buildUiMessages(sessionId, conversation, streaming.value);
};
function ensureConversation(sessionId) {
if (!conversationsBySession.value.has(sessionId)) conversationsBySession.value.set(sessionId, {
messages: {},
activeMessageChain: []
});
const conversation = conversationsBySession.value.get(sessionId);
if (!conversation) throw new Error(`Conversation for session ID ${sessionId} not found`);
return conversation;
}
function lastMessage(sessionId) {
const conversation = getConversation(sessionId);
if (!conversation || conversation.activeMessageChain.length === 0) return null;
const messageId = conversation.activeMessageChain[conversation.activeMessageChain.length - 1];
return conversation.messages[messageId] ?? null;
}
function isResponding(sessionId) {
return lastMessage(sessionId)?.status === "running";
}
function computeActiveChain(messages, messageId) {
const chain = [];
if (!messageId) return chain;
let id;
const stack = [messageId];
let latest = null;
while (id = stack.pop()) {
const message = messages[id];
if (!latest || message.createdAt > messages[latest].createdAt) latest = id;
for (const responseId of message.responses) stack.push(responseId);
}
if (!latest) return chain;
let current = latest;
const visited = /* @__PURE__ */new Set();
while (current && !visited.has(current)) {
chain.unshift(current);
visited.add(current);
current = messages[current]?.previousMessageId ?? null;
}
return chain;
}
function linkMessages(messages) {
const messagesGraph = {};
for (const message of messages) messagesGraph[message.id] = {
...message,
responses: [],
alternatives: []
};
for (const node of Object.values(messagesGraph)) {
if (node.previousMessageId && messagesGraph[node.previousMessageId]) messagesGraph[node.previousMessageId].responses.push(node.id);
if (node.retryOfMessageId && messagesGraph[node.retryOfMessageId]) messagesGraph[node.retryOfMessageId].alternatives.push(node.id);
if (node.revisionOfMessageId && messagesGraph[node.revisionOfMessageId]) messagesGraph[node.revisionOfMessageId].alternatives.push(node.id);
}
const sortByRunThenTime = (first, second) => {
const a = messagesGraph[first];
const b = messagesGraph[second];
if (a.createdAt !== b.createdAt) return a.createdAt < b.createdAt ? -1 : 1;
return a.id < b.id ? -1 : 1;
};
for (const node of Object.values(messagesGraph)) {
if (!node.alternatives.includes(node.id)) node.alternatives.push(node.id);
if (node.retryOfMessageId && messagesGraph[node.retryOfMessageId]) {
node.alternatives.push(node.retryOfMessageId);
for (const other of messagesGraph[node.retryOfMessageId].alternatives) if (other !== node.id && !node.alternatives.includes(other)) node.alternatives.push(other);
}
if (node.revisionOfMessageId && messagesGraph[node.revisionOfMessageId]) {
node.alternatives.push(node.revisionOfMessageId);
for (const other of messagesGraph[node.revisionOfMessageId].alternatives) if (other !== node.id && !node.alternatives.includes(other)) node.alternatives.push(other);
}
node.responses.sort(sortByRunThenTime);
node.alternatives.sort(sortByRunThenTime);
}
return messagesGraph;
}
function addMessage(sessionId, message) {
const conversation = ensureConversation(sessionId);
conversation.messages[message.id] = message;
conversation.messages = linkMessages(Object.values(conversation.messages));
conversation.activeMessageChain = computeActiveChain(conversation.messages, message.id);
return message;
}
function replaceMessageContent(sessionId, messageId, content) {
const message = ensureConversation(sessionId).messages[messageId];
if (!message) throw new Error(`Message with ID ${messageId} not found in session ${sessionId}`);
message.content = content;
}
function appendMessage(sessionId, messageId, chunk) {
const message = ensureConversation(sessionId).messages[messageId];
if (!message) throw new Error(`Message with ID ${messageId} not found in session ${sessionId}`);
message.content += chunk;
}
function updateMessage(sessionId, messageId, status, content) {
const message = ensureConversation(sessionId).messages[messageId];
if (!message) throw new Error(`Message with ID ${messageId} not found in session ${sessionId}`);
message.status = status;
if (content) message.content = content;
message.updatedAt = (/* @__PURE__ */new Date()).toISOString();
}
async function fetchAgents(credentialMap) {
agents.value = await fetchChatModelsApi(rootStore.restApiContext, {
credentials: credentialMap
});
return agents.value;
}
async function fetchSessions(reset) {
if (sessionsLoadingMore.value) return;
if (!reset && sessions.value && !sessions.value.hasMore && (sessions.value.ids ?? []).length > 0) return;
if (!reset) sessionsLoadingMore.value = true;
try {
const cursor = reset ? void 0 : sessions.value?.nextCursor ?? void 0;
const [response] = await Promise.all([fetchConversationsApi(rootStore.restApiContext, 40, cursor), new Promise(resolve => setTimeout(resolve, 500))]);
if (reset || sessions.value.ids === null) sessions.value.ids = [];
sessions.value.hasMore = response.hasMore;
sessions.value.nextCursor = response.nextCursor;
for (const session of response.data) {
sessions.value.ids.push(session.id);
sessions.value.byId[session.id] = session;
}
} finally {
sessionsLoadingMore.value = false;
}
}
async function fetchMoreSessions() {
if (sessions.value?.hasMore && !sessionsLoadingMore.value) await fetchSessions(false);
}
async function fetchMessages(sessionId) {
const {
conversation,
session
} = await fetchSingleConversationApi(rootStore.restApiContext, sessionId);
const messages = linkMessages(Object.values(conversation.messages));
const latestMessage = Object.values(messages).sort((a, b) => a.createdAt < b.createdAt ? -1 : 1).pop();
conversationsBySession.value.set(sessionId, {
messages,
activeMessageChain: computeActiveChain(messages, latestMessage?.id ?? null)
});
sessions.value.byId[sessionId] = session;
}
function onBeginMessage() {
if (!streaming.value?.messageId) return;
const message = createAiMessageFromStreamingState(streaming.value.sessionId, streaming.value.messageId, streaming.value);
addMessage(streaming.value.sessionId, message);
}
function ensureMessage(sessionId, messageId) {
const message = ensureConversation(sessionId).messages[messageId];
if (message) return message;
return addMessage(sessionId, createAiMessageFromStreamingState(sessionId, messageId, streaming.value));
}
function onChunk(chunk) {
if (streaming.value?.messageId) appendMessage(streaming.value.sessionId, streaming.value.messageId, chunk);
}
function onEndMessage() {
if (streaming.value?.messageId) updateMessage(streaming.value.sessionId, streaming.value.messageId, "success");
}
function onStreamMessage(chunk) {
if (!streaming.value) return;
const {
sessionId
} = streaming.value;
streaming.value = {
...streaming.value,
...chunk.metadata
};
switch (chunk.type) {
case "begin":
onBeginMessage();
break;
case "item":
onChunk(chunk.content ?? "");
break;
case "end":
onEndMessage();
break;
case "error":
if (ensureMessage(sessionId, chunk.metadata.messageId).status === "cancelled") return;
updateMessage(sessionId, chunk.metadata.messageId, "error", chunk.content);
break;
}
}
async function onStreamDone() {
if (!streaming.value) return;
const {
sessionId
} = streaming.value;
streaming.value = void 0;
await retry(async () => {
return (await fetchSingleConversationApi(rootStore.restApiContext, sessionId)).session.title !== "New Chat";
}, 1e3, 3);
await fetchSessions(true);
}
function onStreamError(error) {
if (!streaming.value) return;
toast.showError(error, "Could not send message");
const {
sessionId
} = streaming.value;
streaming.value = void 0;
const conversation = getConversation(sessionId);
if (!conversation) return;
for (const messageId of conversation.activeMessageChain) if (conversation.messages[messageId].status === "running") updateMessage(sessionId, messageId, "error");
}
async function sendMessage(sessionId, message, model, credentials, tools, files = [], agentName) {
const messageId = v4_default();
const conversation = ensureConversation(sessionId);
const previousMessageId = conversation.activeMessageChain.length ? conversation.activeMessageChain[conversation.activeMessageChain.length - 1] : null;
const attachments = (await Promise.all(files.map(convertFileToBinaryData))).map(attachment => ({
fileName: attachment.fileName ?? "unnamed file",
mimeType: attachment.mimeType,
data: attachment.data
}));
addMessage(sessionId, {
id: messageId,
sessionId,
type: "human",
name: "User",
content: message,
provider: null,
model: isLlmProviderModel(model) ? model.model : null,
workflowId: null,
executionId: null,
agentId: null,
status: "success",
createdAt: (/* @__PURE__ */new Date()).toISOString(),
updatedAt: (/* @__PURE__ */new Date()).toISOString(),
previousMessageId,
retryOfMessageId: null,
revisionOfMessageId: null,
responses: [],
alternatives: [],
attachments
});
streaming.value = {
promptId: messageId,
sessionId,
model,
retryOfMessageId: null,
tools,
agentName
};
if (!sessions.value.byId[sessionId]) {
sessions.value.byId[sessionId] = createSessionFromStreamingState(streaming.value);
if (!sessions.value.ids) sessions.value.ids = [];
sessions.value.ids.unshift(sessionId);
}
sendMessageApi(rootStore.restApiContext, {
model,
messageId,
sessionId,
message,
credentials,
previousMessageId,
tools,
attachments,
agentName
}, onStreamMessage, onStreamDone, onStreamError);
telemetry.track("User sent chat hub message", {
...flattenModel(model),
is_custom: model.provider === "custom-agent",
chat_session_id: sessionId
});
}
function editMessage(sessionId, editId, content, model, credentials) {
const promptId = v4_default();
const message = ensureConversation(sessionId).messages[editId];
const previousMessageId = message?.previousMessageId ?? null;
if (message?.type === "human") addMessage(sessionId, {
id: promptId,
sessionId,
type: "human",
name: message.name ?? "User",
content,
provider: null,
model: null,
workflowId: null,
executionId: null,
agentId: null,
status: "success",
createdAt: (/* @__PURE__ */new Date()).toISOString(),
updatedAt: (/* @__PURE__ */new Date()).toISOString(),
previousMessageId,
retryOfMessageId: null,
revisionOfMessageId: editId,
responses: [],
alternatives: [],
attachments: message.attachments ?? null
});else if (message?.type === "ai") replaceMessageContent(sessionId, editId, content);
streaming.value = {
promptId,
sessionId,
model,
retryOfMessageId: null,
tools: [],
agentName: sessions.value.byId[sessionId]?.agentName ?? ""
};
editMessageApi(rootStore.restApiContext, sessionId, editId, {
model,
messageId: promptId,
message: content,
credentials
}, onStreamMessage, onStreamDone, onStreamError);
}
function regenerateMessage(sessionId, retryId, model, credentials) {
if (!(ensureConversation(sessionId).messages[retryId]?.previousMessageId ?? null)) throw new Error("No previous message to base regeneration on");
streaming.value = {
promptId: retryId,
sessionId,
model,
retryOfMessageId: retryId,
tools: [],
agentName: sessions.value.byId[sessionId]?.agentName ?? ""
};
regenerateMessageApi(rootStore.restApiContext, sessionId, retryId, {
model,
credentials
}, onStreamMessage, onStreamDone, onStreamError);
}
async function stopStreamingMessage(sessionId) {
const currentMessage = lastMessage(sessionId);
if (currentMessage && currentMessage.status === "running") {
updateMessage(sessionId, currentMessage.id, "cancelled");
await stopGenerationApi(rootStore.restApiContext, sessionId, currentMessage.id);
streaming.value = void 0;
}
}
function updateSession(sessionId, toUpdate) {
const session = sessions.value.byId[sessionId];
if (session) sessions.value.byId[sessionId] = {
...session,
...toUpdate
};
}
async function updateToolsInSession(sessionId, tools) {
if (!sessions.value?.byId[sessionId]) throw new Error(`Session with ID ${sessionId} not found`);
updateSession(sessionId, (await updateConversationApi(rootStore.restApiContext, sessionId, {
tools
})).session);
}
async function renameSession(sessionId, title) {
updateSession(sessionId, (await updateConversationTitleApi(rootStore.restApiContext, sessionId, title)).session);
}
async function updateSessionModel(sessionId, model, agentName) {
await updateConversationApi(rootStore.restApiContext, sessionId, {
agent: {
model,
name: agentName
}
});
updateSession(sessionId, {
...model,
agentName
});
}
async function deleteSession(sessionId) {
await deleteConversationApi(rootStore.restApiContext, sessionId);
delete sessions.value.byId[sessionId];
sessions.value.ids = sessions.value.ids?.filter(id => id !== sessionId) ?? null;
}
function switchAlternative(sessionId, messageId) {
const conversation = getConversation(sessionId);
if (!conversation?.messages[messageId]) throw new Error(`Message with ID ${messageId} not found in session ${sessionId}`);
conversation.activeMessageChain = computeActiveChain(conversation.messages, messageId);
}
async function fetchCustomAgent(agentId) {
return await fetchAgentApi(rootStore.restApiContext, agentId);
}
function getCustomAgent(agentId) {
return agents.value?.["custom-agent"].models.find(model => "agentId" in model && model.agentId === agentId);
}
async function createCustomAgent(payload, credentials) {
const agent = await createAgentApi(rootStore.restApiContext, payload);
const agentModel = {
model: {
provider: "custom-agent",
agentId: agent.id
},
name: agent.name,
description: agent.description ?? null,
createdAt: agent.createdAt,
updatedAt: agent.updatedAt,
tools: agent.tools,
allowFileUploads: true
};
agents.value?.["custom-agent"].models.push(agentModel);
await fetchAgents(credentials);
telemetry.track("User created agent", {
...flattenModel(payload)
});
return agentModel;
}
async function updateCustomAgent(agentId, payload, credentials) {
const agent = await updateAgentApi(rootStore.restApiContext, agentId, payload);
if (agents.value?.["custom-agent"]) agents.value["custom-agent"].models = agents.value["custom-agent"].models.map(model => "agentId" in model && model.agentId === agentId ? {
...model,
name: agent.name
} : model);
await fetchAgents(credentials);
return agent;
}
async function deleteCustomAgent(agentId, credentials) {
await deleteAgentApi(rootStore.restApiContext, agentId);
if (agents.value?.["custom-agent"]) agents.value["custom-agent"].models = agents.value["custom-agent"].models.filter(model => !("agentId" in model) || model.agentId !== agentId);
await fetchAgents(credentials);
}
function getAgent(model, fallbackName = "") {
const agent = agents.value?.[model.provider]?.models.find(agent$1 => isMatchedAgent(agent$1, model));
if (agent) return agent;
return {
model,
name: fallbackName,
description: null,
createdAt: null,
updatedAt: null,
allowFileUploads: true
};
}
async function fetchAllChatSettings() {
try {
settingsLoading.value = true;
settings.value = await fetchChatSettingsApi(rootStore.restApiContext);
} finally {
settingsLoading.value = false;
}
return settings.value;
}
async function fetchProviderSettings(provider) {
const providerSettings = await fetchChatProviderSettingsApi(rootStore.restApiContext, provider);
if (settings.value) settings.value[provider] = deepCopy(providerSettings);
return providerSettings;
}
async function updateProviderSettings(updated) {
if (!updated.enabled) updated.allowedModels = [];
const saved = await updateChatSettingsApi(rootStore.restApiContext, updated);
if (settings.value) settings.value[updated.provider] = deepCopy(saved);
return saved;
}
return {
agents: computed(() => agents.value ?? emptyChatModelsResponse),
agentsReady: computed(() => agents.value !== void 0),
getAgent,
fetchAgents,
getCustomAgent,
fetchCustomAgent,
createCustomAgent,
updateCustomAgent,
deleteCustomAgent,
sessions,
sessionsReady: computed(() => sessions.value.ids !== null),
sessionsLoading: computed(() => sessionsLoadingMore.value),
fetchSessions,
fetchMoreSessions,
renameSession,
updateSessionModel,
deleteSession,
updateToolsInSession,
getConversation,
fetchMessages,
getActiveMessages,
switchAlternative,
lastMessage,
streaming,
isResponding,
sendMessage,
editMessage,
regenerateMessage,
stopStreamingMessage,
settings,
settingsLoading,
fetchAllChatSettings,
fetchProviderSettings,
updateProviderSettings
};
})); //#endregion
}
};
});
})();