- Added httpOnly option to UseMcpOptions to skip SSE fallback
- Updated all HTTP transport failure paths to respect httpOnly flag
- Temporarily enabled httpOnly in chat UI for streamable HTTP debugging
- Updated AGENT.md to require frequent commits after changes
- Added extensive debug logging to transport creation and connection flows
- Added proper Accept header (application/json, text/event-stream) to transport options
- Fixed scroll jittering during streaming with instant scroll behavior
- Investigating HTTP transport 'Not connected' errors and SSE connection hanging
- Use overflow:hidden + whitespace:nowrap to prevent line breaks
- Apply justify-end flexbox to push content to the right
- New tokens push older ones out to the left edge and hide them
- Creates smooth sliding window effect showing only recent tokens
- Only applies during streaming, keeps normal wrap after completion
This creates a nice visual effect where you can see the latest reasoning
tokens flowing in from right to left as the model thinks.
- Remove 500ms setTimeout delay when reasoning finishes
- Reasoning block now collapses immediately when response starts
- Creates smoother transition from thinking to response phase
- Eliminates jarring delay between reasoning end and collapse
The reasoning block now collapses instantly as soon as the model
starts generating the actual response, providing better UX flow.
- Create assistant message as soon as first reasoning event arrives
- This ensures reasoning block is visible from the beginning of thinking
- Prevent duplicate message creation in text-delta handler
- Move reasoning end time logic to text-delta start (when thinking finishes)
This fixes the issue where reasoning blocks weren't appearing because
the assistant message was only created after reasoning completed.
- Update ReasoningBlock to start expanded and show live reasoning content
- Add timing tracking with start/end timestamps for reasoning duration
- Auto-collapse reasoning blocks after completion with 500ms delay
- Show timing summary (e.g. 'Thought for 0.4s') instead of content when collapsed
- Add streaming cursor animation and real-time content updates
- Update types to support reasoning timing and streaming state
- Stream reasoning content live as tokens arrive during thinking phase
This provides a much better UX where users can see the model thinking
in real-time, then get a clean timing summary after completion.
- Add cleaning logic to remove <think> and </think> tags from reasoning
- Trim whitespace after tag removal for clean display
- Add debug logging to show before/after cleaning
- The middleware extracts reasoning but includes the original tags
This ensures the reasoning blocks show clean thinking content without
the XML tags that were being captured along with the reasoning text.
- Add debug logs inside reasoning event handler to see if it's being triggered
- Log reasoning content length as it's being collected
- Add final reasoning content summary at end of stream
- Log why reasoning isn't being added if conditions aren't met
- Cast event to any to avoid potential TypeScript issues
This will help identify why reasoning events aren't being captured
despite appearing in the event stream logs.
- Add back reasoning variable to track content during streaming
- Handle reasoning events from extractReasoningMiddleware in stream processing
- Build up reasoning content from individual reasoning textDelta events
- Remove dependency on result.reasoning which wasn't being populated
- Add reasoning to assistant message after stream completes
The logs showed reasoning events were coming through correctly but we
weren't capturing them. This fixes the issue by collecting reasoning
content during streaming as the events arrive.
- Add debug logging to track aiResponse vs result.text content
- Use result.text from extractReasoningMiddleware for final content
- This should provide the properly cleaned text without thinking tags
- Comment out unused sidebar and edit functionality to fix TS errors
The result.text should contain content that has been automatically
cleaned by the extractReasoningMiddleware, while result.reasoning
contains the extracted thinking content.
- Add multiple regex passes to handle various think tag scenarios
- Remove standalone <think> and </think> tags that might remain
- Clean leading whitespace after tag removal
- Add debug logging to track text cleaning process
- Handle streaming cases where tags appear before closing tags arrive
This provides more robust cleaning to ensure no think tags appear
in the final message content during streaming scenarios.
- Add regex-based cleaning to remove <think>...</think> tags from display text
- Handle both closed and unclosed think tags in streaming content
- Apply cleaning only for reasoning-capable models to avoid unnecessary processing
- Update conversation content with cleaned response instead of raw response
This ensures thinking tags are extracted for reasoning display but don't
appear in the main message content, providing a clean user experience.
- Import extractReasoningMiddleware and wrapLanguageModel from AI SDK
- Wrap reasoning-capable models with extractReasoningMiddleware
- Use 'think' as tagName to parse <think> XML blocks from models
- Enable startWithReasoning option to handle models missing reasoning tags
- Extract reasoning from result.reasoning after stream completes
- Remove manual reasoning event handling and provider-specific config
This fixes the issue where thinking blocks appeared as raw XML tags
instead of parsed reasoning content. The middleware automatically
extracts reasoning from <think> tags and exposes it via result.reasoning.
- Add reasoning field to AssistantMessage type
- Create ReasoningBlock component with truncate/expand functionality
- Add reasoning-capable models (Qwen QwQ, DeepSeek R1, Qwen 3 32B)
- Implement reasoning event handling in stream processing
- Enable reasoning format for Groq and Anthropic models
- Style reasoning blocks with grey border and reduced font size
- Display reasoning above assistant messages when available
The reasoning blocks show truncated thinking tokens by default and
expand on click to show full reasoning process from models like
Qwen3-32b that support step-by-step reasoning output.
- Add background-size: 100% 100vh to fix gradient height to viewport
- Add background-repeat: repeat-y to tile gradient vertically
- Gradient pattern now repeats down the page as content grows
- Animation applies consistently to all repeated background tiles
- Creates seamless repeating pattern while maintaining hue rotation
- Change from h-dvh to min-h-screen on main container
- Remove overflow-clip to allow content to expand
- Update inner containers to use min-h-screen for proper height
- Background gradient now extends with content rather than fixed to viewport
- Allows for scrolling when content exceeds viewport height
- Add qwen-3-32b model entry using qwen/qwen3-32b model ID
- Uses same Groq provider as Llama 3.3, sharing API token
- Model appears in selection modal between Llama and Claude
- Clean name 'Qwen 3 32B' for user interface
- Add react-router-dom dependency for routing support
- Create OAuthCallback component with animated background and loading spinner
- Add routing to App.tsx with /oauth/callback route
- Match styling with main app using animated-bg-container
- Use onMcpAuthorization from use-mcp library for OAuth handling
- Library already handles multiple server differentiation via state parameter
- Each MCP server gets unique OAuth flow identified by state containing server URL
- Clean up unused imports and variables in McpServerModal
- Remove radial gradient to fix banding issues
- Use solid 80% black background (rgba(0,0,0,0.8))
- Apply to both ModelSelectionModal and McpServerModal
- Clean, consistent backdrop without visual artifacts
- Replace solid black 50% opacity with radial gradient
- Center: 80% black (rgba(0,0,0,0.8))
- Corners: 70% black (rgba(0,0,0,0.7))
- Apply to both ModelSelectionModal and McpServerModal
- Creates softer, more visually appealing backdrop
- Remove bg-black bg-opacity-50 classes and use inline style
- Change from '0 (1) servers, 0 (2) tools' to '0/1 servers, 0/2 tools'
- Use forward slash format showing enabled/total for both servers and tools
- Cleaner, more compact visual representation
- Examples:
- No servers: '0/0 servers, 0/0 tools'
- One disabled server with 2 tools: '0/1 servers, 0/2 tools'
- One enabled server with 2 tools: '1/1 servers, 2/2 tools'
- Change format from '0 (1 servers) 0 (2 tools)' to '0 (1) servers, 0 (2) tools'
- Move words 'servers' and 'tools' outside brackets
- Add comma separation between server and tool counts
- More concise and readable format
- Change indicator format to show enabled/total for both servers and tools
- Format: 'X (Y servers) A (B tools)' where:
- X = enabled servers, Y = total servers
- A = tools from enabled servers, B = total tools from all servers
- Track tool counts per server in localStorage (mcpServerToolCounts)
- Persist tool counts even when servers are disabled
- Examples:
- No servers: '0 (0 servers) 0 (0 tools)'
- One disabled server with 2 tools: '0 (1 servers) 0 (2 tools)'
- One enabled server with 2 tools: '1 (1 servers) 2 (2 tools)'
- Clean up tool counts when servers are deleted
- Completely rewrite McpServerModal to support multiple servers
- Add McpServer interface with id, url, enabled, and name fields
- Use localStorage 'mcpServers' array instead of single server URL
- Add server list UI with status badges, toggle, and delete buttons
- Add 'Add New Server' section at bottom with input and Add button
- Support enabling/disabling individual servers with Power/PowerOff icons
- Delete servers with Trash2 icon in top right of each server block
- Aggregate tools from all enabled servers for parent component
- Render multiple McpConnection components for enabled servers
- Update plug indicator to show correct server count
- Add debug information panel showing server and tool counts
- Handle server names using hostname from URL
- Each server gets unique connection state tracking by server ID
- Add cursor-pointer class to X button in ModelSelectionModal
- Add onClick handler to backdrop overlay to close modal
- Add stopPropagation to modal content to prevent backdrop clicks
- Consistent modal behavior between model selector and MCP server modals
- Add cursor-pointer class to modal X button
- Add onClick handler to backdrop overlay to close modal
- Add stopPropagation to modal content to prevent backdrop clicks
- Now modal can be dismissed by clicking outside or using X button
- Add onMcpToolsUpdate prop to ConversationThread interface
- Pass setMcpTools function from ChatApp down to ConversationThread
- Connect McpServerModal onToolsUpdate to parent state update
- Now plug icon will correctly show '1 (N)' when N tools are available
- Fixes issue where tool count remained at 0 despite successful connection
- Replace conditional rendering with CSS visibility (hidden/block)
- Remove early return null when modal is closed
- McpConnection component stays mounted to preserve MCP server connection
- Modal is always in DOM but visually hidden when isOpen is false
- Prevents MCP disconnection when modal is dismissed
- Create McpServerModal component based on existing McpServers component
- Add plug emoji (🔌) indicator on right side, opposite to brain emoji
- Show '0' when no servers connected, '1 (N)' when connected with N tools
- Fullscreen modal with MCP server configuration UI
- Support for single MCP server connection (foundation for multiple servers)
- Integrate with existing MCP tools logic and useMcp hook
- Clean layout with brain emoji on left, plug emoji on right
- Change unconfigured model indicator from red ✕ to grey 'none' text
- Add explicit cursor-pointer class to brain emoji button
- Maintains grey text color consistent with configured model names
- Cleaner, less alarming visual for unconfigured state
- Create separate background layer using ::before pseudo-element
- Move hue-rotate animation to background layer with z-index: -1
- Remove filter from main container to prevent inheritance
- Use equivalent gradient colors in CSS (pink-100, purple-50, indigo-100)
- Foreground elements (brain emoji, text) now maintain original colors
- Background still animates smoothly without affecting content
- Create ModelSelectionModal component with list-style interface
- Add brain emoji (🧠) indicator below chat input, left-aligned
- Show current model name in lowercase or red X if not configured
- Fullscreen modal displays all available models with configuration status
- Green checkmark for configured models, red alert for unconfigured
- Integrate with existing API key management and model selection logic
- Modal handles API key setup workflow when selecting unconfigured models
- Clean separation between compact indicator and full selection interface
- Move animation-delay to CSS using custom property --random-delay
- JavaScript still required to generate random value (CSS has no random functions)
- Cleaner separation between styling (CSS) and logic (JavaScript)
- Maintains same functionality with better organization
- Generate random negative animation-delay between 0 and -60 seconds
- Starts animation at random point in the 60-second cycle
- Each page load will show different initial colors
- Uses useState with initializer function to set delay once on mount
- CSS doesn't have random functions, so JavaScript handles the randomization
- Change animation duration from 8s to 60s for subtle color shifting
- Creates gentle, barely noticeable background color transitions
- Maintains visual interest without being distracting
- Revert complex conical gradient approach
- Return to original linear gradient (pink-100 → purple-50 → indigo-100)
- Add hue-rotate filter animation cycling through 360 degrees
- 8s duration for fast testing
- Simpler implementation with continuous color shifting
- Less control over saturation but smoother performance
- Create large 500% conical gradient with pastel color cycle
- Position gradient off-screen (-200% top/left) for smooth rotation
- Add 8s linear infinite rotation animation for fast testing
- Use ::before pseudo-element to avoid repainting main content
- Cycle through various pastel shades (pink, purple, blue, green, yellow, orange)
- Performance-optimized: only transforms, no gradient repainting
- Hide sidebar (conversations, model picker, MCP servers) while preserving components
- Hide navbar/title bar while preserving component
- Remove title text and description above input field
- Add pastel gradient background (pink-purple-indigo)
- Expand conversation thread to full width
- Create minimal, focused interface with only white input field visible