Skip to content

Commit 636d031

Browse files
feat(chat): Enhance quick message sending with improved session handling and error management
- Updated quick message sending logic to ensure chat session initialization and error handling. - Integrated Letta API for sending messages without streaming for faster responses. - Added logging for loaded messages in MultiChatModal for better debugging. - Improved message sorting to handle different date formats.
1 parent 599b451 commit 636d031

File tree

2 files changed

+74
-32
lines changed

2 files changed

+74
-32
lines changed

obsidian-plugin/thoth-obsidian/main.ts

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,8 @@ export default class ThothPlugin extends Plugin {
779779
`;
780780

781781
// Handle quick message sending
782+
// NOTE: This uses the same Letta API as the full chat (MultiChatModal.sendMessage)
783+
// but without streaming for faster, simpler responses in the minimized pill view
782784
const sendQuickMessage = async () => {
783785
const message = inputEl.value.trim();
784786
if (!message || sendBtn.disabled) return;
@@ -793,42 +795,75 @@ export default class ThothPlugin extends Plugin {
793795
sendBtn.textContent = 'Asking...';
794796

795797
try {
796-
// Use the chat modal instance to send message
797-
if (this.chatModalInstance && this.chatModalInstance.activeSessionId) {
798-
// Send to server using existing chat functionality
799-
const endpoint = this.getEndpointUrl();
800-
const response = await fetch(`${endpoint}/research/chat`, {
801-
method: 'POST',
802-
headers: { 'Content-Type': 'application/json' },
803-
body: JSON.stringify({
804-
message: message,
805-
conversation_id: this.chatModalInstance.activeSessionId,
806-
timestamp: Date.now(),
807-
id: crypto.randomUUID()
808-
})
809-
});
810-
811-
if (response.ok) {
812-
const result = await response.json();
813-
const assistantResponse = result.response;
814-
815-
// Show response
816-
responseArea.textContent = assistantResponse.length > 150 ?
817-
assistantResponse.substring(0, 150) + '...' : assistantResponse;
818-
819-
// Update full chat in background
820-
if (this.chatModalInstance) {
821-
await this.chatModalInstance.loadChatSessions();
822-
this.chatModalInstance.renderSessionList();
798+
// Ensure we have a chat modal instance
799+
if (!this.chatModalInstance) {
800+
throw new Error('Chat system not initialized');
801+
}
802+
803+
// Ensure we have an active session, create one if needed
804+
let conversationId = this.chatModalInstance.activeSessionId;
805+
if (!conversationId) {
806+
responseArea.textContent = 'Initializing chat session...';
807+
try {
808+
conversationId = await this.chatModalInstance.getOrCreateDefaultConversation();
809+
this.chatModalInstance.activeSessionId = conversationId;
810+
await this.chatModalInstance.loadChatSessions();
811+
} catch (initError) {
812+
throw new Error(`Failed to initialize chat: ${initError.message}`);
813+
}
814+
}
815+
816+
// Send to server using Letta chat endpoint (same as full chat but without streaming)
817+
const endpoint = this.getLettaEndpointUrl();
818+
819+
const response = await fetch(`${endpoint}/v1/conversations/${conversationId}/messages`, {
820+
method: 'POST',
821+
headers: { 'Content-Type': 'application/json' },
822+
body: JSON.stringify({
823+
input: message,
824+
streaming: false // No streaming for quick responses
825+
})
826+
});
827+
828+
if (response.ok) {
829+
const result = await response.json();
830+
831+
// Extract assistant response from Letta response format
832+
// Letta returns an array of messages - find the last assistant message
833+
let assistantResponse = 'No response received';
834+
835+
if (Array.isArray(result.messages)) {
836+
// Find last assistant_message
837+
const assistantMsg = [...result.messages]
838+
.reverse()
839+
.find((m: any) => m.message_type === 'assistant_message');
840+
841+
if (assistantMsg) {
842+
// Extract text from assistant message
843+
assistantResponse = assistantMsg.assistant_message?.text ||
844+
assistantMsg.text ||
845+
assistantMsg.content ||
846+
assistantResponse;
823847
}
824-
} else {
825-
throw new Error('Failed to send message');
848+
} else if (result.response) {
849+
assistantResponse = result.response;
826850
}
851+
852+
// Show response
853+
responseArea.style.color = 'var(--text-muted)';
854+
responseArea.textContent = assistantResponse.length > 150 ?
855+
assistantResponse.substring(0, 150) + '...' : assistantResponse;
856+
857+
// Update full chat in background
858+
await this.chatModalInstance.loadChatSessions();
859+
this.chatModalInstance.renderSessionList();
827860
} else {
828-
throw new Error('No active chat session');
861+
const errorData = await response.json().catch(() => ({}));
862+
throw new Error(errorData.message || errorData.detail || `Server error: ${response.status}`);
829863
}
830864
} catch (error) {
831865
console.error('Quick chat error:', error);
866+
responseArea.style.color = 'var(--text-error)';
832867
responseArea.textContent = `Error: ${error.message}`;
833868
} finally {
834869
sendBtn.disabled = false;

obsidian-plugin/thoth-obsidian/src/modals/multi-chat-modal.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,11 @@ ${isConnected ? '✓ Ready to chat with Letta' : '⚠ Start the Letta server to
21282128
if (response.ok) {
21292129
const newMessages = await response.json();
21302130

2131+
console.log(`[MultiChatModal] Loaded ${newMessages.length} messages for session ${sessionId}`, {
2132+
loadEarlier,
2133+
messageTypes: newMessages.map((m: any) => m.message_type || m.type).filter((t: any, i: number, arr: any[]) => arr.indexOf(t) === i)
2134+
});
2135+
21312136
// Get or initialize cached messages
21322137
let allMessages = this.messageCache.get(sessionId) || [];
21332138

@@ -2255,11 +2260,13 @@ ${isConnected ? '✓ Ready to chat with Letta' : '⚠ Start the Letta server to
22552260
// Sort by date to ensure chronological order (oldest first)
22562261
// This provides a fallback in case the API order changes
22572262
.sort((a, b) => {
2258-
const dateA = new Date(a.date).getTime();
2259-
const dateB = new Date(b.date).getTime();
2263+
const dateA = new Date(a.date || a.created_at || 0).getTime();
2264+
const dateB = new Date(b.date || b.created_at || 0).getTime();
22602265
return dateA - dateB;
22612266
});
22622267

2268+
console.log(`[MultiChatModal] Rendering ${chatMessages.length} chat messages from ${messages.length} total messages`);
2269+
22632270
// Load existing messages or show empty state
22642271
if (chatMessages.length === 0) {
22652272
this.createEmptyState(

0 commit comments

Comments
 (0)