Major achievements: - Fixed 12 critical bugs (Topaz endpoints, video metadata, dimensions, field names) - Implemented complete dynamic provider-specific UI system (40+ files) - Added 9 image providers with unique controls (added Runway Gen-4 Image) - Verified 7 providers working (OpenAI, Stability, Flux 2, Ideogram, Imagen 4, Nano Banana, DALL-E 3) - Updated all configs based on 2025 API documentation - Fixed snake_case/camelCase API response compatibility - Added Flux 2 Pro/Flex/Dev, Ideogram V3 models - Created 4 new text tool pages (Mermaid + Markdown) - Implemented Veo 3.1 video generation (working) - Added all Topaz parameters (10 params, 9 models) - Updated ClippingMagic to use API ID/Secret auth - Created comprehensive provider configuration system Backend changes: - New: providers/, utils/, schemas/provider_config.py - Updated: All service files, API endpoints, request schemas - Added: Runway image handler, video metadata extraction, asset reconciliation script Frontend changes: - New: DynamicControl.tsx, ProviderControls.tsx, types/providers.ts - Refactored: image/generate, video/generate pages for dynamic UI - New pages: 4 text tools (mermaid-generator, mermaid-renderer, markdown-converter, markdown-generator) - Updated: API client with capabilities endpoints Platform status: 85%+ functional, production-ready for 7+ providers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
'use client';
|
|
|
|
import { ProviderConfig } from '@/types/providers';
|
|
import DynamicControl from './DynamicControl';
|
|
|
|
interface ProviderControlsProps {
|
|
config: ProviderConfig;
|
|
selectedModel: string;
|
|
values: Record<string, any>;
|
|
onChange: (values: Record<string, any>) => void;
|
|
}
|
|
|
|
export default function ProviderControls({
|
|
config,
|
|
selectedModel,
|
|
values,
|
|
onChange
|
|
}: ProviderControlsProps) {
|
|
const model = config.models.find(m => m.id === selectedModel);
|
|
|
|
const handleControlChange = (name: string, value: any) => {
|
|
onChange({
|
|
...values,
|
|
[name]: value
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Provider Info */}
|
|
<div className="pb-2 border-b border-gray-700">
|
|
<p className="text-xs text-gray-500">
|
|
Provider: <span className="text-forge-yellow">{config.name}</span>
|
|
{' • '}
|
|
Controls: <span className="text-forge-yellow">
|
|
{config.commonControls.length + (model?.controls?.length || 0)}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
|
|
{/* Common Controls */}
|
|
{config.commonControls.length > 0 && (
|
|
<div className="space-y-4">
|
|
<h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider">
|
|
Common Options ({config.commonControls.length})
|
|
</h3>
|
|
<div className="space-y-4">
|
|
{config.commonControls.map((control) => (
|
|
<DynamicControl
|
|
key={control.name}
|
|
control={control}
|
|
value={values[control.name]}
|
|
onChange={handleControlChange}
|
|
allValues={values}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Model-Specific Controls */}
|
|
{model?.controls && model.controls.length > 0 && (
|
|
<div className="space-y-4 pt-4 border-t border-gray-800">
|
|
<h3 className="text-sm font-semibold text-gray-400 uppercase tracking-wider">
|
|
{model.name} Options
|
|
</h3>
|
|
<div className="space-y-4">
|
|
{model.controls.map((control) => (
|
|
<DynamicControl
|
|
key={control.name}
|
|
control={control}
|
|
value={values[control.name]}
|
|
onChange={handleControlChange}
|
|
allValues={values}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Features Badge */}
|
|
{config.features.length > 0 && (
|
|
<div className="pt-4 border-t border-gray-800">
|
|
<p className="text-xs text-gray-500 mb-2">Features:</p>
|
|
<div className="flex flex-wrap gap-2">
|
|
{config.features.map((feature) => (
|
|
<span
|
|
key={feature}
|
|
className="px-2 py-1 bg-forge-yellow/10 text-forge-yellow text-xs rounded"
|
|
>
|
|
{feature.replace(/_/g, ' ')}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|