## Changes
- **Removed navigation tabs**: Eliminated inference and MCP provider test tabs
- **Simplified App component**: Now directly shows ConversationApp without navigation
- **Full-screen layout**: ConversationApp now uses full viewport height (h-screen)
- **Cleaned up imports**: Removed unused test component imports
- **Deleted test components**: Removed InferenceTest.tsx and MCPTest.tsx files
## Benefits
- ✅ **Streamlined UX**: Single-purpose interface focused on conversations
- ✅ **Smaller bundle**: Reduced JS bundle size by ~25KB and CSS by ~3KB
- ✅ **Cleaner codebase**: Removed complexity of tab navigation and test interfaces
- ✅ **Better focus**: All functionality accessible through conversation interface
## Integration Points Preserved
- MCP server management available through conversation sidebar MCP status
- Model selection integrated into conversation header
- All authentication flows still work through conversation interface
- OAuth callbacks remain functional
The conversation interface now provides access to all functionality:
- Model selection in chat header
- MCP server status/management in sidebar
- Test tools still available through agent loop
- Full authentication and provider management
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Problem
When starting an agent loop in one conversation and switching to another,
the "assistant thinking" UI would incorrectly appear in the second
conversation, even though it was idle.
## Root Cause
The `isLoading` state in ChatInterface was global/shared across all
conversations. When conversation A started generating, `isLoading` was
set to `true`. Switching to conversation B would still show the thinking
UI because `isGenerating = agentLoopState?.isRunning || isLoading`
evaluated to `true` due to the shared loading state.
## Solution
- **Conversation-specific loading**: Changed from single `isLoading` boolean
to `loadingConversations` Set tracking which conversations are loading
- **Isolated state**: Each conversation now has independent loading state
- **Proper cleanup**: Loading state is properly added/removed per conversation
## Technical Changes
- Replaced `useState<boolean>` with `useState<Set<string>>`
- Updated `handleSendMessage` to add/remove conversation IDs from Set
- Modified `isGenerating` calculation to check current conversation only
## User Experience
- ✅ **Isolated UI state**: Thinking UI only appears for actually running conversations
- ✅ **No cross-conversation interference**: Switching conversations shows correct state
- ✅ **Maintained functionality**: All existing behavior preserved
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Problem
After page refresh, the model selector would be empty even though the
authentication provider was restored and models were loaded successfully.
Users had to manually click "reload models" to populate the selector.
## Root Cause
The context state wasn't being properly updated after models were loaded
during provider restoration. The provider had the models, but React
components weren't re-rendering to show them.
## Solution
- **Added forced re-render**: Added extra `setAuthStateVersion()` call after
model loading to trigger React context update
- **Auto-load models on restore**: Provider restoration now automatically
loads models and restores saved model selection
- **Improved error handling**: Better error handling during model restoration
## Technical Details
- Modified `restoreProviderWithModels()` to force context re-render
- Ensured model loading happens immediately when provider is restored
- Maintained existing model persistence functionality
- Cleaned up debugging logs
## User Experience
- ✅ **Seamless model selection**: Model selector is populated immediately after refresh
- ✅ **Persistent choice**: Previously selected model is automatically restored
- ✅ **No manual intervention**: No need to click "reload models" button
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Features
- **Sticky model selection**: Chosen model persists across browser sessions
- **Automatic restoration**: Saved model is restored when loading models
- **Validation**: Invalid saved models are automatically cleared
- **Provider switching**: Model selection is reset when switching providers
## Implementation Details
- Model ID saved to localStorage on selection
- Model restored during loadModels() if still available
- Saved selection cleared when:
- Switching inference providers
- Logging out
- Model no longer exists in available models
## User Experience
- Users no longer need to reselect their preferred model after refresh
- Model selector maintains state across page reloads
- Graceful handling when saved model becomes unavailable
## Technical Notes
- Uses 'selected_model_id' localStorage key
- Integrates with existing InferenceContext state management
- Maintains backward compatibility with existing provider logic
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Problem
MCP server names with invalid characters (spaces, special chars, etc.)
caused tool routing failures when prefixed to tool names, as OpenRouter
API requires tool names to match pattern ^[a-zA-Z0-9_-]{1,64}$
## Solution
- **Added normalizeServerName utility**: Converts invalid characters to underscores
- **Centralized normalization logic**: Shared utility prevents code duplication
- **Fixed tool routing**: Agent loop now matches normalized server names correctly
- **Updated tool discovery**: MCP tools use normalized prefixes consistently
## Examples
- "My Weather Service\!" → "My_Weather_Service"
- "Test@Server#123" → "Test_Server_123"
- "Server...with...dots" → "Server_with_dots"
- " spaces_and__double__underscores " → "spaces_and_double_underscores"
## Technical Details
- Created /src/utils/mcpUtils.ts for shared normalization function
- Updated MCPConnectionManager to use normalized prefixes in tool names
- Fixed agent loop to match connections using normalized names
- Maintains original server names in UI while using normalized names for API
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Features Added
- **Unique server name validation**: Prevent duplicate MCP server names to avoid tool routing conflicts
- **Quick-add server examples**: Added example server buttons for "Everything" and "Test Server" configurations
- **Conversation model selector**: Added dropdown to change AI models directly in chat interface
- **Fixed nav bar height**: Conversation widget now properly accounts for navigation bar height
## User Experience Improvements
- Server name uniqueness prevents tool naming conflicts and confusion
- Quick-add buttons make it easier to get started with common MCP servers
- Model selector allows switching between AI models without leaving conversation
- Proper height calculation eliminates layout issues with conversation interface
## Technical Details
- Server name validation happens before calling addMcpServer API
- Model selector integrates with existing inference context
- Height calculation uses CSS calc(100vh - 4rem) for nav bar compensation
- All changes maintain backward compatibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Features
- Add proactive health check monitoring for MCP connections (30s intervals)
- Implement automatic reconnection on health check failures
- Add proper cleanup of health check intervals on disconnect
## Fixes
- Resolve OAuth type compatibility issues with MCP SDK
- Fix naming collision between InferenceProvider class and React component
- Remove unused React imports across all components (new JSX transform)
- Clean up unused type imports and variables
- Remove unused handleOAuthAuthentication function
## Technical Details
- Health checks use lightweight listTools() calls to verify connection state
- Automatic reconnection triggers when health checks fail
- Maintains existing exponential backoff retry logic
- All TypeScript compilation errors resolved
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add OpenRouter API key persistence to localStorage with auto-restore
- Add automatic provider restoration on app startup for seamless login
- Fix MCP OAuth token persistence by preserving connection IDs across refreshes
- Add manual reconnect button for failed/disconnected MCP servers
- Add auto-reconnect for MCP servers on app startup
- Maintain backward compatibility with old connection storage format
Resolves auth token loss on page refresh for both inference and MCP providers.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update MCP tool naming from server.tool to server__tool format
- Add tool naming requirements section with OpenRouter API constraints
- Update troubleshooting guide with tool naming validation errors
- Add specific troubleshooting for agent loop hanging with MCP tools
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change tool name separator from dot to double underscore (server__tool)
- Update tool discovery to use server__tool_name format
- Update tool execution routing to parse double underscore separator
- Fix OpenRouter API error: tool names must match pattern '^[a-zA-Z0-9_-]{1,64}'
This resolves the silent failure when MCP tools were present in conversations.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Document conversation system architecture and data models
- Explain agent loop implementation and tool integration
- Cover state management, authentication flow, and UI components
- Provide development guidelines and troubleshooting guide
- Include performance, security, and testing considerations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix ChatInterface to use context's reactive isAuthenticated value
- Fix useAgentLoop to use context's reactive isAuthenticated value
- Ensure consistent authentication state checking across the application
- Add isAuthenticated to useCallback dependencies for proper reactivity
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add conversation management with persistence and multi-conversation support
- Create agent loop hook with test tools and MCP tool integration
- Implement full chat UI with message display, tool call visualization
- Add inline authentication flow for inference providers
- Support both API key and OAuth authentication methods
- Add conversation sidebar with conversation list and management
- Integrate MCP status display for debugging
- Create message input with proper disabled states and tooltips
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Features
- 🔧 InferenceProvider interface with pluggable architecture
- 🔑 OpenRouter API key and OAuth PKCE authentication providers
- 🛠️ Tool calling support with automatic agent loop execution
- 📱 Interactive test UI with model selection and chat interface
- 🎯 Provider-level filtering to tool-capable models only
- ⚛️ React context with proper state management for UI reactivity
## Components
- Core types and interfaces in src/types/inference.ts
- OpenRouter client with shared utilities for both auth methods
- Two separate providers (composition over inheritance):
- OpenRouterApiProvider for API key authentication
- OpenRouterOAuthProvider for OAuth PKCE flow
- React InferenceContext with useInference hook
- Interactive test UI with tool calling demonstration
- OAuth callback routing with proper namespacing
## Tool Calling
- 3 test tools: weather, calculator, time
- Automatic tool execution and agent loop
- Visual tool call display with arguments and results
- Error handling for malformed tool calls
## Bug Fixes
- Fixed model selection UI reactivity issue
- Fixed OAuth popup race condition causing "cancelled" errors
- Proper cleanup of event listeners and intervals
## Documentation
- Comprehensive interface design document
- Implementation strategy and key design decisions
- Testing approach and security considerations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>