diff --git a/main.js b/main.js index 6eb8e82..33fc725 100644 --- a/main.js +++ b/main.js @@ -9059,7 +9059,11 @@ var ChatView = class extends import_obsidian3.ItemView { if (existingEl) { const contentEl = existingEl.querySelector(".ollama-message-content"); if (contentEl) { - contentEl.textContent = msg.content; + if (msg.isThinking) { + contentEl.innerHTML = 'Thinking\u2026'; + } else { + contentEl.textContent = msg.content; + } } } else { const messageEl = container.createEl("div", { @@ -9069,7 +9073,11 @@ var ChatView = class extends import_obsidian3.ItemView { const headerEl = messageEl.createEl("div", { cls: "ollama-message-header" }); headerEl.createEl("span", { cls: "ollama-message-role", text: msg.role }); const contentEl = messageEl.createEl("div", { cls: "ollama-message-content" }); - contentEl.textContent = msg.content; + if (msg.isThinking) { + contentEl.innerHTML = 'Thinking\u2026'; + } else { + contentEl.textContent = msg.content; + } } } const streamingMessage = messagesSnapshot.find((msg) => msg.isStreaming); @@ -9297,7 +9305,8 @@ var ChatView = class extends import_obsidian3.ItemView { role: "assistant", content: "", timestamp: Date.now(), - isStreaming: true + isStreaming: true, + isThinking: true }; const previousStreamingEl = this.lastMessageEl; this.messages = [...this.messages, userChatMessage, assistantMessage]; @@ -9334,7 +9343,8 @@ ${userMessage}` : userMessage; fullResponse += chunk.content; this.updateLastMessage({ content: fullResponse, - isStreaming: true + isStreaming: true, + isThinking: false }); } if (chunk.tool_calls) { @@ -9373,7 +9383,8 @@ ${userMessage}` : userMessage; ErrorHandler.handleError(error, "ChatView.handleUserInput"); this.updateMessageById(assistantMessageId, { content: "An error occurred while processing your request.", - isStreaming: false + isStreaming: false, + isThinking: false }); } finally { this.cleanupStreamingResources(); diff --git a/src/chat-view.ts b/src/chat-view.ts index c3d9898..7a2f14f 100755 --- a/src/chat-view.ts +++ b/src/chat-view.ts @@ -146,7 +146,11 @@ export class ChatView extends ItemView { if (existingEl) { const contentEl = existingEl.querySelector('.ollama-message-content'); if (contentEl) { - contentEl.textContent = msg.content; + if (msg.isThinking) { + contentEl.innerHTML = 'Thinking…'; + } else { + contentEl.textContent = msg.content; + } } } else { const messageEl = container.createEl('div', { @@ -158,7 +162,11 @@ export class ChatView extends ItemView { headerEl.createEl('span', { cls: 'ollama-message-role', text: msg.role }); const contentEl = messageEl.createEl('div', { cls: 'ollama-message-content' }); - contentEl.textContent = msg.content; + if (msg.isThinking) { + contentEl.innerHTML = 'Thinking…'; + } else { + contentEl.textContent = msg.content; + } } } @@ -437,6 +445,7 @@ export class ChatView extends ItemView { content: '', timestamp: Date.now(), isStreaming: true, + isThinking: true, }; const previousStreamingEl = this.lastMessageEl; @@ -486,6 +495,7 @@ export class ChatView extends ItemView { this.updateLastMessage({ content: fullResponse, isStreaming: true, + isThinking: false, }); } @@ -536,6 +546,7 @@ export class ChatView extends ItemView { this.updateMessageById(assistantMessageId, { content: 'An error occurred while processing your request.', isStreaming: false, + isThinking: false, }); } finally { // Clean up streaming resources regardless of outcome diff --git a/src/types.ts b/src/types.ts index 70c751a..db620ff 100644 --- a/src/types.ts +++ b/src/types.ts @@ -141,6 +141,7 @@ export interface ChatMessage { content: string; timestamp: number; isStreaming?: boolean; + isThinking?: boolean; tool_calls?: OllamaToolCall[]; // Refinement tracking originalQuery?: string; diff --git a/styles.css b/styles.css index 50f0444..1c6a8b3 100644 --- a/styles.css +++ b/styles.css @@ -149,3 +149,29 @@ .ollama-send-button:active { filter: brightness(0.95); } + +/* Thinking indicator */ +.ollama-thinking-indicator { + display: inline-flex; + align-items: center; + gap: var(--size-4-1); + font-style: italic; + color: var(--text-muted); +} + +.ollama-thinking-indicator::before { + content: ''; + display: inline-block; + width: 0.9em; + height: 0.9em; + border: 2px solid var(--text-muted); + border-top-color: transparent; + border-radius: 50%; + animation: ollama-spin 1s linear infinite; +} + +@keyframes ollama-spin { + to { + transform: rotate(360deg); + } +}