import React, { useState } from 'react' import { ModelChooserModal, useModelData, ModelInfo } from './index' import './styles/modal.css' // Add API Example Modal Component interface ApiExampleModalProps { isOpen: boolean onClose: () => void model: ModelInfo apiKey: string } function ApiExampleModal({ isOpen, onClose, model, apiKey }: ApiExampleModalProps) { const [activeTab, setActiveTab] = useState<'basic' | 'reasoning' | 'streaming'>('basic') if (!isOpen) return null const baseExample = { method: 'POST', url: 'https://openrouter.ai/api/v1/chat/completions', headers: { 'Authorization': `Bearer ${apiKey || 'YOUR_OPENROUTER_API_KEY'}`, 'Content-Type': 'application/json' }, body: { model: model.id, messages: [ { role: 'user', content: 'Hello, how are you?' } ], stream: model.reasoning || false } } const reasoningExample = { ...baseExample, body: { ...baseExample.body, messages: [ { role: 'user', content: 'What\'s bigger, 9.9 or 9.11? Explain your reasoning step by step.' } ], stream: true, reasoning: { // One of the following (not both): effort: 'high', // Can be "high", "medium", or "low" (OpenAI-style) // max_tokens: 2000, // Specific token limit (Anthropic-style) // Optional parameters: exclude: false, // Set to true to exclude reasoning tokens from response enabled: true // Default: inferred from `effort` or `max_tokens` } } } const streamingExample = { ...baseExample, body: { ...baseExample.body, messages: [ { role: 'user', content: 'Write a detailed analysis of renewable energy trends.' } ], stream: true, ...(model.reasoning && { reasoning: { max_tokens: 4000, // Anthropic-style token limit exclude: false, // Include reasoning in streamed response enabled: true // Default: inferred from max_tokens } }) } } const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text).then(() => { // Could add a toast notification here }) } const renderExample = (example: any, title: string, description: string) => (

{title}

{description}

        {JSON.stringify(example, null, 2)}
      
) return (
{/* Header */}

API Examples for {model.name}

Ready-to-use examples with {model.reasoning ? 'reasoning tokens' : 'standard configuration'}

{/* Tabs */}
{['basic', 'reasoning', 'streaming'].map((tab) => ( ))}
{/* Content */}
{activeTab === 'basic' && renderExample( baseExample, 'Basic API Call', `Simple API call to ${model.name}. ${model.reasoning ? 'Streaming enabled automatically for reasoning models.' : 'Standard configuration.'}` )} {activeTab === 'reasoning' && (
{model.reasoning ? ( <> {renderExample( reasoningExample, 'Reasoning with Effort Level', 'Uses reasoning.effort parameter (high/medium/low) - supported by OpenAI o-series and Grok models.' )} {renderExample( { ...reasoningExample, body: { ...reasoningExample.body, reasoning: { // Use max_tokens instead of effort (not both): max_tokens: 2000, // Specific token limit (Anthropic-style) // Optional parameters: exclude: false, // Set to true to exclude reasoning from response enabled: true // Default: inferred from max_tokens } } }, 'Reasoning with Max Tokens', 'Uses reasoning.max_tokens parameter - supported by Anthropic and Gemini thinking models.' )} {renderExample( { ...reasoningExample, body: { ...reasoningExample.body, reasoning: { effort: 'medium', // Can be "high", "medium", or "low" exclude: true, // Hide reasoning from response enabled: true // Default: inferred from effort } } }, 'Hidden Reasoning', 'Model uses reasoning internally but excludes it from the response (reasoning.exclude: true).' )} {renderExample( { ...reasoningExample, body: { ...reasoningExample.body, reasoning: { max_tokens: 1500, // Anthropic-style token limit exclude: false, // Include reasoning in response enabled: true // Explicitly enable reasoning } } }, 'Complete Reasoning Configuration', 'Shows all available parameters with explicit settings for maximum control.' )}
💡 Reasoning Token Configuration
  • Effort vs Max Tokens: Use one or the other, not both
  • effort: "high"/"medium"/"low" (OpenAI o-series, Grok)
  • max_tokens: Specific token limit (Anthropic, Gemini thinking)
  • exclude: false (default) = show reasoning, true = hide it
  • enabled: Auto-inferred from effort/max_tokens, can override
  • Billing: Reasoning tokens are charged as output tokens
  • Streaming: Use stream: true to see thinking process live
) : (

This model doesn't support reasoning tokens

Select a reasoning model (🧠) to see reasoning-specific examples.

)}
)} {activeTab === 'streaming' && (
{renderExample( streamingExample, 'Streaming Response', `Streaming configuration${model.streamCancel ? ' with cancellation support' : ' (no cancellation support)'}.` )}
{model.streamCancel ? '✅ Stream Cancellation Supported' : 'âš ī¸ Stream Cancellation NOT Supported'}

{model.streamCancel ? 'You can safely abort streaming requests to control costs. The model will stop processing immediately.' : 'This provider does not support stream cancellation. You will be charged for the complete response even if you abort the request.' }

{model.reasoning && (
{renderExample( { method: 'POST', url: 'https://openrouter.ai/api/v1/chat/completions', headers: baseExample.headers, body: { model: model.id, messages: [ { role: 'user', content: 'Solve this math problem step by step: What is 15% of 240?' } ], stream: true, reasoning: { effort: 'high' } } }, 'Streaming + Reasoning', 'Combines streaming with reasoning tokens for real-time thinking process visibility.' )}
)}
)}
{/* Footer */}
📚 Learn more: OpenRouter Reasoning Tokens Documentation
) } export function DemoApp() { const [selectedModel, setSelectedModel] = useState('') const [selectedModelInfo, setSelectedModelInfo] = useState(null) const [isModalOpen, setIsModalOpen] = useState(false) const [apiKey, setApiKey] = useState('') const [showApiKeyInput, setShowApiKeyInput] = useState(false) const [testing, setTesting] = useState(false) const [testResult, setTestResult] = useState(null) const [showApiModal, setShowApiModal] = useState(false) const { models, loading, error, refresh } = useModelData() const handleTestCall = async () => { alert('Test functionality removed. Use the "View API Examples" button instead for comprehensive API usage examples.') } const handleApiKeySubmit = () => { if (apiKey.trim()) { setShowApiKeyInput(false) handleTestCall() } } const handleExampleApiCall = () => { if (!selectedModel || !selectedModelInfo) return setShowApiModal(true) } return (

OpenRouter Model Picker Demo

This demo shows the improved model picker with live data fetching, proper model filtering, and exact model ID usage. The API key is only used for testing actual model calls.

{/* Current Selection */}

Current Selection

{selectedModel ? (() => { // Use the selected model info from the enhanced callback const model = selectedModelInfo || models.find(m => m.id === selectedModel) return (
{selectedModel}
{model && (
{model.name} by {model.provider}
{model.reasoning && ( 🧠 Reasoning Support )} {model.multimodal && ( 👁 Vision Support )} {model.streamCancel && ( âšī¸ Stream Cancel )} {model.costTier.charAt(0).toUpperCase() + model.costTier.slice(1)} Cost
{model.reasoning && (
â„šī¸ This model supports reasoning tokens for step-by-step thinking
)} {model.streamCancel && (
âšī¸ This model supports stream cancellation for cost control
)}
)}

✅ This exact model ID will be used in API calls (no suffixes added)

) })() : (

No model selected

)}
{selectedModel && ( <> )}
{/* API Key Input - Only shown when needed */} {showApiKeyInput && (

API Key Required

setApiKey(e.target.value)} placeholder="Enter your OpenRouter API key..." onKeyDown={(e) => e.key === 'Enter' && handleApiKeySubmit()} style={{ width: '100%', padding: '0.5rem', border: '1px solid #d1d5db', borderRadius: '0.375rem', fontSize: '0.875rem' }} autoFocus /> 💡 Your API key is needed to make actual test calls to the OpenRouter API
)} {/* Test Results */} {testResult && (

Test Result

{testResult.success ? (
Response: {testResult.response}
{testResult.usage && (
Usage: {testResult.usage.prompt_tokens} prompt + {testResult.usage.completion_tokens} completion = {testResult.usage.total_tokens} total tokens
)}
) : (
Error: {testResult.error}
)}
)} {/* Features Section */}

Key Features

  • ✅ Live model fetching from OpenRouter API (no API key needed)
  • ✅ 🧠 Reasoning model detection - Automatically detects and highlights o1, DeepSeek R1, and other thinking models
  • ✅ Enhanced deprecated model filtering - Removes models that cause 404 errors
  • ✅ Free vs paid model categorization
  • ✅ Exact model ID usage (no ":free" suffixes)
  • ✅ Real model testing with API key (actual completions)
  • ✅ Improved error handling and fallback models
  • ✅ Enhanced UI with model statistics
💡 Tip: Check the browser console to see filtering stats - broken models are pre-filtered out, experimental models can be hidden via checkbox.
setIsModalOpen(false)} selectedModel={selectedModel} onModelChange={setSelectedModel} onModelSelect={setSelectedModelInfo} categorizeByType={true} maxHeight="90vh" maxWidth="1200px" /> {selectedModelInfo && ( setShowApiModal(false)} model={selectedModelInfo} apiKey={apiKey} /> )}
) }