fix: message metadata and agent selection
This commit is contained in:
@@ -16,6 +16,17 @@ import { extractTextFromPart, normalizeStreamingPart } from "./utils/messageUtil
|
|||||||
import { getSafeStorage } from "./utils/safeStorage";
|
import { getSafeStorage } from "./utils/safeStorage";
|
||||||
import { useFileStore } from "./fileStore";
|
import { useFileStore } from "./fileStore";
|
||||||
import { useSessionStore } from "./sessionStore";
|
import { useSessionStore } from "./sessionStore";
|
||||||
|
import { useContextStore } from "./contextStore";
|
||||||
|
|
||||||
|
// Helper function to clean up pending user message metadata
|
||||||
|
const cleanupPendingUserMessageMeta = (
|
||||||
|
currentPending: Map<string, { mode?: string; providerID?: string; modelID?: string }>,
|
||||||
|
sessionId: string
|
||||||
|
): Map<string, { mode?: string; providerID?: string; modelID?: string }> => {
|
||||||
|
const nextPending = new Map(currentPending);
|
||||||
|
nextPending.delete(sessionId);
|
||||||
|
return nextPending;
|
||||||
|
};
|
||||||
|
|
||||||
interface QueuedPart {
|
interface QueuedPart {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
@@ -339,6 +350,8 @@ interface MessageState {
|
|||||||
pendingAssistantParts: Map<string, { sessionId: string; parts: Part[] }>;
|
pendingAssistantParts: Map<string, { sessionId: string; parts: Part[] }>;
|
||||||
sessionCompactionUntil: Map<string, number>;
|
sessionCompactionUntil: Map<string, number>;
|
||||||
sessionAbortFlags: Map<string, SessionAbortRecord>;
|
sessionAbortFlags: Map<string, SessionAbortRecord>;
|
||||||
|
pendingAssistantHeaderSessions: Set<string>;
|
||||||
|
pendingUserMessageMetaBySession: Map<string, { mode?: string; providerID?: string; modelID?: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessageActions {
|
interface MessageActions {
|
||||||
@@ -379,6 +392,8 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
pendingAssistantParts: new Map(),
|
pendingAssistantParts: new Map(),
|
||||||
sessionCompactionUntil: new Map(),
|
sessionCompactionUntil: new Map(),
|
||||||
sessionAbortFlags: new Map(),
|
sessionAbortFlags: new Map(),
|
||||||
|
pendingAssistantHeaderSessions: new Set(),
|
||||||
|
pendingUserMessageMetaBySession: new Map(),
|
||||||
|
|
||||||
loadMessages: async (sessionId: string, limit: number = MEMORY_LIMITS.VIEWPORT_MESSAGES) => {
|
loadMessages: async (sessionId: string, limit: number = MEMORY_LIMITS.VIEWPORT_MESSAGES) => {
|
||||||
const allMessages = await executeWithSessionDirectory(sessionId, () => opencodeClient.getSessionMessages(sessionId));
|
const allMessages = await executeWithSessionDirectory(sessionId, () => opencodeClient.getSessionMessages(sessionId));
|
||||||
@@ -654,6 +669,18 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
url: file.dataUrl,
|
url: file.dataUrl,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
const next = new Set(state.pendingAssistantHeaderSessions);
|
||||||
|
next.add(sessionId);
|
||||||
|
const nextUserMeta = new Map(state.pendingUserMessageMetaBySession);
|
||||||
|
nextUserMeta.set(sessionId, {
|
||||||
|
mode: typeof agent === 'string' && agent.trim().length > 0 ? agent.trim() : undefined,
|
||||||
|
providerID,
|
||||||
|
modelID,
|
||||||
|
});
|
||||||
|
return { pendingAssistantHeaderSessions: next, pendingUserMessageMetaBySession: nextUserMeta };
|
||||||
|
});
|
||||||
|
|
||||||
await opencodeClient.sendMessage({
|
await opencodeClient.sendMessage({
|
||||||
id: sessionId,
|
id: sessionId,
|
||||||
providerID,
|
providerID,
|
||||||
@@ -696,7 +723,11 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
set((state) => {
|
set((state) => {
|
||||||
const nextControllers = new Map(state.abortControllers);
|
const nextControllers = new Map(state.abortControllers);
|
||||||
nextControllers.delete(sessionId);
|
nextControllers.delete(sessionId);
|
||||||
return { abortControllers: nextControllers };
|
const nextHeaders = new Set(state.pendingAssistantHeaderSessions);
|
||||||
|
nextHeaders.delete(sessionId);
|
||||||
|
const nextUserMeta = new Map(state.pendingUserMessageMetaBySession);
|
||||||
|
nextUserMeta.delete(sessionId);
|
||||||
|
return { abortControllers: nextControllers, pendingAssistantHeaderSessions: nextHeaders, pendingUserMessageMetaBySession: nextUserMeta };
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
@@ -719,7 +750,11 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
set((state) => {
|
set((state) => {
|
||||||
const nextControllers = new Map(state.abortControllers);
|
const nextControllers = new Map(state.abortControllers);
|
||||||
nextControllers.delete(sessionId);
|
nextControllers.delete(sessionId);
|
||||||
return { abortControllers: nextControllers };
|
const nextHeaders = new Set(state.pendingAssistantHeaderSessions);
|
||||||
|
nextHeaders.delete(sessionId);
|
||||||
|
const nextUserMeta = new Map(state.pendingUserMessageMetaBySession);
|
||||||
|
nextUserMeta.delete(sessionId);
|
||||||
|
return { abortControllers: nextControllers, pendingAssistantHeaderSessions: nextHeaders, pendingUserMessageMetaBySession: nextUserMeta };
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new Error(errorMessage);
|
throw new Error(errorMessage);
|
||||||
@@ -1145,6 +1180,22 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
const normalizedPart = normalizeStreamingPart(part);
|
const normalizedPart = normalizeStreamingPart(part);
|
||||||
(window as any).__messageTracker?.(messageId, `new_user_part_type:${(normalizedPart as any).type || 'unknown'}`);
|
(window as any).__messageTracker?.(messageId, `new_user_part_type:${(normalizedPart as any).type || 'unknown'}`);
|
||||||
|
|
||||||
|
const pendingMeta = state.pendingUserMessageMetaBySession.get(sessionId);
|
||||||
|
const contextStore = useContextStore.getState();
|
||||||
|
const sessionAgent =
|
||||||
|
pendingMeta?.mode ??
|
||||||
|
contextStore.getSessionAgentSelection(sessionId) ??
|
||||||
|
contextStore.getCurrentAgent(sessionId);
|
||||||
|
const agentMode = typeof sessionAgent === 'string' && sessionAgent.trim().length > 0
|
||||||
|
? sessionAgent.trim()
|
||||||
|
: undefined;
|
||||||
|
const providerID = pendingMeta?.providerID ?? (state.lastUsedProvider?.providerID || undefined);
|
||||||
|
const modelID = pendingMeta?.modelID ?? (state.lastUsedProvider?.modelID || undefined);
|
||||||
|
|
||||||
|
if (pendingMeta) {
|
||||||
|
updates.pendingUserMessageMetaBySession = cleanupPendingUserMessageMeta(state.pendingUserMessageMetaBySession, sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
const newUserMessage = {
|
const newUserMessage = {
|
||||||
info: {
|
info: {
|
||||||
id: messageId,
|
id: messageId,
|
||||||
@@ -1152,6 +1203,9 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
role: 'user' as const,
|
role: 'user' as const,
|
||||||
clientRole: 'user',
|
clientRole: 'user',
|
||||||
userMessageMarker: true,
|
userMessageMarker: true,
|
||||||
|
...(agentMode ? { mode: agentMode } : {}),
|
||||||
|
...(providerID ? { providerID } : {}),
|
||||||
|
...(modelID ? { modelID } : {}),
|
||||||
time: {
|
time: {
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
},
|
},
|
||||||
@@ -1212,19 +1266,58 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
const newPending = new Map(state.pendingAssistantParts);
|
const newPending = new Map(state.pendingAssistantParts);
|
||||||
newPending.set(messageId, { sessionId, parts: pendingParts });
|
newPending.set(messageId, { sessionId, parts: pendingParts });
|
||||||
|
|
||||||
const placeholderInfo = {
|
const providerID = state.lastUsedProvider?.providerID || "";
|
||||||
id: messageId,
|
const modelID = state.lastUsedProvider?.modelID || "";
|
||||||
sessionID: sessionId,
|
const now = Date.now();
|
||||||
role: actualRole as "user" | "assistant",
|
const cwd = opencodeClient.getDirectory() ?? "/";
|
||||||
clientRole: actualRole,
|
const contextStore = useContextStore.getState();
|
||||||
providerID: state.lastUsedProvider?.providerID || "",
|
const sessionAgent = contextStore.getSessionAgentSelection(sessionId)
|
||||||
modelID: state.lastUsedProvider?.modelID || "",
|
?? contextStore.getCurrentAgent(sessionId);
|
||||||
time: {
|
const agentMode = typeof sessionAgent === "string" && sessionAgent.trim().length > 0
|
||||||
created: Date.now(),
|
? sessionAgent.trim()
|
||||||
},
|
: undefined;
|
||||||
animationSettled: actualRole === "assistant" ? false : undefined,
|
|
||||||
streaming: actualRole === "assistant" ? true : undefined,
|
const shouldAnchorHeader = state.pendingAssistantHeaderSessions.has(sessionId);
|
||||||
} as Message;
|
if (shouldAnchorHeader) {
|
||||||
|
const nextPendingHeaders = new Set(state.pendingAssistantHeaderSessions);
|
||||||
|
nextPendingHeaders.delete(sessionId);
|
||||||
|
updates.pendingAssistantHeaderSessions = nextPendingHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeholderInfo = (actualRole === "user"
|
||||||
|
? {
|
||||||
|
id: messageId,
|
||||||
|
sessionID: sessionId,
|
||||||
|
role: "user",
|
||||||
|
time: { created: now },
|
||||||
|
agent: agentMode || "default",
|
||||||
|
model: { providerID, modelID },
|
||||||
|
clientRole: actualRole,
|
||||||
|
animationSettled: undefined,
|
||||||
|
streaming: undefined,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
id: messageId,
|
||||||
|
sessionID: sessionId,
|
||||||
|
role: "assistant",
|
||||||
|
time: { created: now },
|
||||||
|
parentID: messageId,
|
||||||
|
modelID,
|
||||||
|
providerID,
|
||||||
|
mode: agentMode || "default",
|
||||||
|
...(shouldAnchorHeader ? { openchamberHeaderAnchor: true } : {}),
|
||||||
|
path: { cwd, root: cwd },
|
||||||
|
cost: 0,
|
||||||
|
tokens: {
|
||||||
|
input: 0,
|
||||||
|
output: 0,
|
||||||
|
reasoning: 0,
|
||||||
|
cache: { read: 0, write: 0 },
|
||||||
|
},
|
||||||
|
clientRole: actualRole,
|
||||||
|
animationSettled: false,
|
||||||
|
streaming: true,
|
||||||
|
}) as unknown as Message;
|
||||||
|
|
||||||
const placeholderMessage = {
|
const placeholderMessage = {
|
||||||
info: placeholderInfo,
|
info: placeholderInfo,
|
||||||
@@ -1603,11 +1696,15 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
|
|
||||||
if (incomingInfo && incomingInfo.role === 'user') {
|
if (incomingInfo && incomingInfo.role === 'user') {
|
||||||
const pendingParts = pendingEntry?.parts ?? [];
|
const pendingParts = pendingEntry?.parts ?? [];
|
||||||
|
const pendingMeta = state.pendingUserMessageMetaBySession.get(sessionId);
|
||||||
const newUserMessage = {
|
const newUserMessage = {
|
||||||
info: {
|
info: {
|
||||||
...incomingInfo,
|
...incomingInfo,
|
||||||
userMessageMarker: true,
|
userMessageMarker: true,
|
||||||
clientRole: 'user',
|
clientRole: 'user',
|
||||||
|
...(pendingMeta?.mode ? { mode: pendingMeta.mode } : {}),
|
||||||
|
...(pendingMeta?.providerID ? { providerID: pendingMeta.providerID } : {}),
|
||||||
|
...(pendingMeta?.modelID ? { modelID: pendingMeta.modelID } : {}),
|
||||||
} as Message,
|
} as Message,
|
||||||
parts: pendingParts.length > 0 ? [...pendingParts] : [],
|
parts: pendingParts.length > 0 ? [...pendingParts] : [],
|
||||||
};
|
};
|
||||||
@@ -1625,6 +1722,11 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
|
|
||||||
const updates: Partial<MessageState> = {
|
const updates: Partial<MessageState> = {
|
||||||
messages: newMessages,
|
messages: newMessages,
|
||||||
|
...(pendingMeta
|
||||||
|
? {
|
||||||
|
pendingUserMessageMetaBySession: cleanupPendingUserMessageMeta(state.pendingUserMessageMetaBySession, sessionId),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const nextIndex = upsertMessageSessionIndex(
|
const nextIndex = upsertMessageSessionIndex(
|
||||||
@@ -1650,10 +1752,13 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pendingParts = pendingEntry?.parts ?? [];
|
const pendingParts = pendingEntry?.parts ?? [];
|
||||||
|
|
||||||
|
const shouldAnchorHeader = state.pendingAssistantHeaderSessions.has(sessionId);
|
||||||
const newMessage = {
|
const newMessage = {
|
||||||
info: {
|
info: {
|
||||||
...incomingInfo,
|
...incomingInfo,
|
||||||
animationSettled: (incomingInfo as any)?.animationSettled ?? false,
|
animationSettled: (incomingInfo as any)?.animationSettled ?? false,
|
||||||
|
...(shouldAnchorHeader ? { openchamberHeaderAnchor: true } : {}),
|
||||||
} as Message,
|
} as Message,
|
||||||
parts: pendingParts.length > 0 ? [...pendingParts] : [],
|
parts: pendingParts.length > 0 ? [...pendingParts] : [],
|
||||||
};
|
};
|
||||||
@@ -1665,6 +1770,15 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
|
|
||||||
const updates: Partial<MessageState> = {
|
const updates: Partial<MessageState> = {
|
||||||
messages: newMessages,
|
messages: newMessages,
|
||||||
|
...(shouldAnchorHeader
|
||||||
|
? {
|
||||||
|
pendingAssistantHeaderSessions: (() => {
|
||||||
|
const nextPendingHeaders = new Set(state.pendingAssistantHeaderSessions);
|
||||||
|
nextPendingHeaders.delete(sessionId);
|
||||||
|
return nextPendingHeaders;
|
||||||
|
})(),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const nextIndex = upsertMessageSessionIndex(
|
const nextIndex = upsertMessageSessionIndex(
|
||||||
@@ -1693,32 +1807,44 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
existingInfo.clientRole === 'user' ||
|
existingInfo.clientRole === 'user' ||
|
||||||
existingInfo.role === 'user';
|
existingInfo.role === 'user';
|
||||||
|
|
||||||
if (isUserMessage) {
|
if (isUserMessage) {
|
||||||
|
|
||||||
|
const updatedInfo = {
|
||||||
|
...existingMessage.info,
|
||||||
|
...messageInfo,
|
||||||
|
|
||||||
|
role: 'user',
|
||||||
|
clientRole: 'user',
|
||||||
|
userMessageMarker: true,
|
||||||
|
|
||||||
|
providerID: existingInfo.providerID || undefined,
|
||||||
|
modelID: existingInfo.modelID || undefined,
|
||||||
|
} as any;
|
||||||
|
|
||||||
const updatedInfo = {
|
const pendingMeta = state.pendingUserMessageMetaBySession.get(sessionId);
|
||||||
...existingMessage.info,
|
if (pendingMeta && !updatedInfo.mode && pendingMeta.mode) {
|
||||||
...messageInfo,
|
updatedInfo.mode = pendingMeta.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedMessage = {
|
||||||
|
...existingMessage,
|
||||||
|
info: updatedInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
const newMessages = new Map(state.messages);
|
||||||
|
const updatedSessionMessages = [...normalizedSessionMessages];
|
||||||
|
updatedSessionMessages[messageIndex] = updatedMessage;
|
||||||
|
newMessages.set(sessionId, updatedSessionMessages);
|
||||||
|
|
||||||
role: 'user',
|
if (pendingMeta) {
|
||||||
clientRole: 'user',
|
const nextPending = new Map(state.pendingUserMessageMetaBySession);
|
||||||
userMessageMarker: true,
|
nextPending.delete(sessionId);
|
||||||
|
return { messages: newMessages, pendingUserMessageMetaBySession: nextPending };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { messages: newMessages };
|
||||||
|
}
|
||||||
|
|
||||||
providerID: existingInfo.providerID || undefined,
|
|
||||||
modelID: existingInfo.modelID || undefined,
|
|
||||||
} as any;
|
|
||||||
|
|
||||||
const updatedMessage = {
|
|
||||||
...existingMessage,
|
|
||||||
info: updatedInfo
|
|
||||||
};
|
|
||||||
|
|
||||||
const newMessages = new Map(state.messages);
|
|
||||||
const updatedSessionMessages = [...normalizedSessionMessages];
|
|
||||||
updatedSessionMessages[messageIndex] = updatedMessage;
|
|
||||||
newMessages.set(sessionId, updatedSessionMessages);
|
|
||||||
|
|
||||||
return { messages: newMessages };
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedInfo = {
|
const updatedInfo = {
|
||||||
...existingMessage.info,
|
...existingMessage.info,
|
||||||
|
|||||||
@@ -270,6 +270,23 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
loadMessages: (sessionId: string) => useMessageStore.getState().loadMessages(sessionId),
|
loadMessages: (sessionId: string) => useMessageStore.getState().loadMessages(sessionId),
|
||||||
sendMessage: async (content: string, providerID: string, modelID: string, agent?: string, attachments?: AttachedFile[], agentMentionName?: string) => {
|
sendMessage: async (content: string, providerID: string, modelID: string, agent?: string, attachments?: AttachedFile[], agentMentionName?: string) => {
|
||||||
const draft = get().newSessionDraft;
|
const draft = get().newSessionDraft;
|
||||||
|
const trimmedAgent = typeof agent === 'string' && agent.trim().length > 0 ? agent.trim() : undefined;
|
||||||
|
|
||||||
|
const setBusyPhase = (sessionId: string) => {
|
||||||
|
set((state) => {
|
||||||
|
const next = new Map(state.sessionActivityPhase ?? new Map());
|
||||||
|
next.set(sessionId, 'busy');
|
||||||
|
return { sessionActivityPhase: next };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setIdlePhase = (sessionId: string) => {
|
||||||
|
set((state) => {
|
||||||
|
const next = new Map(state.sessionActivityPhase ?? new Map());
|
||||||
|
next.set(sessionId, 'idle');
|
||||||
|
return { sessionActivityPhase: next };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (draft?.open) {
|
if (draft?.open) {
|
||||||
const created = await useSessionManagementStore
|
const created = await useSessionManagementStore
|
||||||
@@ -282,6 +299,7 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
|
|
||||||
const configState = useConfigStore.getState();
|
const configState = useConfigStore.getState();
|
||||||
const draftAgentName = configState.currentAgentName;
|
const draftAgentName = configState.currentAgentName;
|
||||||
|
const effectiveDraftAgent = trimmedAgent ?? draftAgentName;
|
||||||
const draftProviderId = configState.currentProviderId;
|
const draftProviderId = configState.currentProviderId;
|
||||||
const draftModelId = configState.currentModelId;
|
const draftModelId = configState.currentModelId;
|
||||||
|
|
||||||
@@ -293,9 +311,9 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (draftAgentName) {
|
if (effectiveDraftAgent) {
|
||||||
try {
|
try {
|
||||||
useContextStore.getState().saveSessionAgentSelection(created.id, draftAgentName);
|
useContextStore.getState().saveSessionAgentSelection(created.id, effectiveDraftAgent);
|
||||||
} catch {
|
} catch {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
@@ -304,7 +322,7 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
try {
|
try {
|
||||||
useContextStore
|
useContextStore
|
||||||
.getState()
|
.getState()
|
||||||
.saveAgentModelForSession(created.id, draftAgentName, draftProviderId, draftModelId);
|
.saveAgentModelForSession(created.id, effectiveDraftAgent, draftProviderId, draftModelId);
|
||||||
} catch {
|
} catch {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
@@ -320,14 +338,45 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
}
|
}
|
||||||
|
|
||||||
get().closeNewSessionDraft();
|
get().closeNewSessionDraft();
|
||||||
|
setBusyPhase(created.id);
|
||||||
|
|
||||||
return useMessageStore
|
try {
|
||||||
.getState()
|
return await useMessageStore
|
||||||
.sendMessage(content, providerID, modelID, agent, created.id, attachments, agentMentionName);
|
.getState()
|
||||||
|
.sendMessage(content, providerID, modelID, effectiveDraftAgent, created.id, attachments, agentMentionName);
|
||||||
|
} catch (error) {
|
||||||
|
setIdlePhase(created.id);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentSessionId = useSessionManagementStore.getState().currentSessionId;
|
const currentSessionId = useSessionManagementStore.getState().currentSessionId;
|
||||||
return useMessageStore.getState().sendMessage(content, providerID, modelID, agent, currentSessionId || undefined, attachments, agentMentionName);
|
const sessionAgentSelection = currentSessionId
|
||||||
|
? useContextStore.getState().getSessionAgentSelection(currentSessionId)
|
||||||
|
: null;
|
||||||
|
const configAgentName = useConfigStore.getState().currentAgentName;
|
||||||
|
const effectiveAgent = trimmedAgent || sessionAgentSelection || configAgentName || undefined;
|
||||||
|
|
||||||
|
if (currentSessionId && effectiveAgent) {
|
||||||
|
try {
|
||||||
|
useContextStore.getState().saveSessionAgentSelection(currentSessionId, effectiveAgent);
|
||||||
|
} catch {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSessionId) {
|
||||||
|
setBusyPhase(currentSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await useMessageStore.getState().sendMessage(content, providerID, modelID, effectiveAgent, currentSessionId || undefined, attachments, agentMentionName);
|
||||||
|
} catch (error) {
|
||||||
|
if (currentSessionId) {
|
||||||
|
setIdlePhase(currentSessionId);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
abortCurrentOperation: () => {
|
abortCurrentOperation: () => {
|
||||||
const currentSessionId = useSessionManagementStore.getState().currentSessionId;
|
const currentSessionId = useSessionManagementStore.getState().currentSessionId;
|
||||||
|
|||||||
Reference in New Issue
Block a user