Implement complete InferenceProvider system with OpenRouter integration

## 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>
This commit is contained in:
Jerome 2025-06-10 17:37:11 +01:00
commit 438ceb333c
No known key found for this signature in database

32
src/App.tsx Normal file
View file

@ -0,0 +1,32 @@
import React from 'react'
import { InferenceProvider } from '@/contexts/InferenceContext'
import { InferenceTest } from '@/components/InferenceTest'
import { OAuthCallback } from '@/components/OAuthCallback'
function App() {
// Simple routing based on pathname
const pathname = window.location.pathname;
const isInferenceOAuthCallback = pathname === '/oauth/inference/callback';
const isMcpOAuthCallback = pathname.startsWith('/oauth/mcp/');
if (isInferenceOAuthCallback) {
return <OAuthCallback type="inference" />;
}
if (isMcpOAuthCallback) {
// Extract server identifier from path like /oauth/mcp/server123/callback
const serverMatch = pathname.match(/^\/oauth\/mcp\/([^\/]+)\/callback$/);
const serverId = serverMatch?.[1];
return <OAuthCallback type="mcp" serverId={serverId} />;
}
return (
<InferenceProvider>
<div className="min-h-screen bg-gray-100 dark:bg-gray-900">
<InferenceTest />
</div>
</InferenceProvider>
)
}
export default App