generated from nhcarrigan/template
fix: resolve message submission and stuck processing bugs #199
@@ -339,6 +339,7 @@ User: ${formattedMessage}`;
|
||||
conversationId,
|
||||
message: messageToSend,
|
||||
});
|
||||
claudeStore.setProcessing(true);
|
||||
} catch (error) {
|
||||
console.error("Failed to send prompt:", error);
|
||||
claudeStore.addLine("error", `Failed to send: ${error}`);
|
||||
@@ -793,6 +794,7 @@ User: ${formattedMessage}`;
|
||||
conversationId,
|
||||
message: prompt,
|
||||
});
|
||||
claudeStore.setProcessing(true);
|
||||
} catch (error) {
|
||||
console.error("Failed to send quick action:", error);
|
||||
claudeStore.addLine("error", `Failed to send: ${error}`);
|
||||
|
||||
@@ -41,6 +41,7 @@ export const claudeStore = {
|
||||
setWorkingDirectory: conversationsStore.setWorkingDirectory,
|
||||
setWorkingDirectoryForConversation: conversationsStore.setWorkingDirectoryForConversation,
|
||||
setProcessing: conversationsStore.setProcessing,
|
||||
setProcessingForConversation: conversationsStore.setProcessingForConversation,
|
||||
addLine: conversationsStore.addLine,
|
||||
addLineToConversation: conversationsStore.addLineToConversation,
|
||||
updateLine: conversationsStore.updateLine,
|
||||
|
||||
@@ -561,3 +561,97 @@ describe("draft text persistence", () => {
|
||||
expect(conversation.draftText).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isProcessing state management", () => {
|
||||
it("starts as false by default", () => {
|
||||
const conversation = { id: "conv-1", isProcessing: false };
|
||||
expect(conversation.isProcessing).toBe(false);
|
||||
});
|
||||
|
||||
it("setProcessingForConversation sets processing true for the target conversation", () => {
|
||||
const conversations = new Map([
|
||||
["conv-1", { isProcessing: false, lastActivityAt: new Date(0) }],
|
||||
["conv-2", { isProcessing: false, lastActivityAt: new Date(0) }],
|
||||
]);
|
||||
|
||||
const setProcessingForConversation = (conversationId: string, processing: boolean) => {
|
||||
const conv = conversations.get(conversationId);
|
||||
if (conv) {
|
||||
conv.isProcessing = processing;
|
||||
conv.lastActivityAt = new Date();
|
||||
}
|
||||
};
|
||||
|
||||
setProcessingForConversation("conv-1", true);
|
||||
|
||||
expect(conversations.get("conv-1")?.isProcessing).toBe(true);
|
||||
expect(conversations.get("conv-2")?.isProcessing).toBe(false);
|
||||
});
|
||||
|
||||
it("setProcessingForConversation resets processing to false", () => {
|
||||
const conversations = new Map([
|
||||
["conv-1", { isProcessing: true, lastActivityAt: new Date(0) }],
|
||||
]);
|
||||
|
||||
const setProcessingForConversation = (conversationId: string, processing: boolean) => {
|
||||
const conv = conversations.get(conversationId);
|
||||
if (conv) {
|
||||
conv.isProcessing = processing;
|
||||
conv.lastActivityAt = new Date();
|
||||
}
|
||||
};
|
||||
|
||||
setProcessingForConversation("conv-1", false);
|
||||
|
||||
expect(conversations.get("conv-1")?.isProcessing).toBe(false);
|
||||
});
|
||||
|
||||
it("setProcessingForConversation does nothing for unknown conversation", () => {
|
||||
const conversations = new Map([["conv-1", { isProcessing: false, lastActivityAt: new Date(0) }]]);
|
||||
|
||||
const setProcessingForConversation = (conversationId: string, processing: boolean) => {
|
||||
const conv = conversations.get(conversationId);
|
||||
if (conv) {
|
||||
conv.isProcessing = processing;
|
||||
conv.lastActivityAt = new Date();
|
||||
}
|
||||
};
|
||||
|
||||
setProcessingForConversation("unknown", true);
|
||||
|
||||
expect(conversations.get("conv-1")?.isProcessing).toBe(false);
|
||||
});
|
||||
|
||||
it("isProcessing is cleared when idle state arrives", () => {
|
||||
const conversation = { isProcessing: true, characterState: "thinking" };
|
||||
|
||||
const terminalStates = ["idle", "success", "error"];
|
||||
const handleStateChange = (state: string) => {
|
||||
conversation.characterState = state;
|
||||
if (terminalStates.includes(state)) {
|
||||
conversation.isProcessing = false;
|
||||
}
|
||||
};
|
||||
|
||||
handleStateChange("idle");
|
||||
|
||||
expect(conversation.isProcessing).toBe(false);
|
||||
});
|
||||
|
||||
it("isProcessing stays true during non-terminal states", () => {
|
||||
const conversation = { isProcessing: true, characterState: "thinking" };
|
||||
|
||||
const terminalStates = ["idle", "success", "error"];
|
||||
const handleStateChange = (state: string) => {
|
||||
conversation.characterState = state;
|
||||
if (terminalStates.includes(state)) {
|
||||
conversation.isProcessing = false;
|
||||
}
|
||||
};
|
||||
|
||||
for (const state of ["thinking", "typing", "coding", "searching", "mcp"]) {
|
||||
handleStateChange(state);
|
||||
expect(conversation.isProcessing).toBe(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -560,6 +560,17 @@ function createConversationsStore() {
|
||||
});
|
||||
},
|
||||
|
||||
setProcessingForConversation: (conversationId: string, processing: boolean) => {
|
||||
conversations.update((convs) => {
|
||||
const conv = convs.get(conversationId);
|
||||
if (conv) {
|
||||
conv.isProcessing = processing;
|
||||
conv.lastActivityAt = new Date();
|
||||
}
|
||||
return convs;
|
||||
});
|
||||
},
|
||||
|
||||
addLine: (
|
||||
type: TerminalLine["type"],
|
||||
content: string,
|
||||
|
||||
@@ -333,13 +333,21 @@ export async function initializeTauriListeners() {
|
||||
}
|
||||
|
||||
// Always update the conversation's state
|
||||
const isTerminalState =
|
||||
mappedState === "idle" || mappedState === "success" || mappedState === "error";
|
||||
if (conversation_id) {
|
||||
claudeStore.setCharacterStateForConversation(conversation_id, mappedState);
|
||||
if (isTerminalState) {
|
||||
claudeStore.setProcessingForConversation(conversation_id, false);
|
||||
}
|
||||
} else {
|
||||
// Fallback to active conversation if no conversation_id
|
||||
const activeConversationId = get(claudeStore.activeConversationId);
|
||||
if (activeConversationId) {
|
||||
claudeStore.setCharacterStateForConversation(activeConversationId, mappedState);
|
||||
if (isTerminalState) {
|
||||
claudeStore.setProcessingForConversation(activeConversationId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user