Team Ai
Apppublic

Alcazard/vibe-coding-api

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes
AIService.php124 linesDownload Raw Back to Service
1<?php2 3namespace src\Service;4namespace VibeCoding\Service;5 6use Symfony\Contracts\HttpClient\HttpClientInterface;7use Psr\Log\LoggerInterface;8 9class AIService10{11    private array $providers = [];12 13    public function __construct(14        private HttpClientInterface $httpClient,15        private LoggerInterface $logger,16        private string $openRouterKey,17        private string $geminiKey18    ) {19        $this->providers = [20            'openrouter' => [21                'key' => $openRouterKey,22                'models' => [23                    'deepseek/deepseek-r1:free',24                    'qwen/qwen-2.5-coder-32b-instruct:free',25                    'google/gemini-2.0-flash-exp:free',26                    'meta-llama/llama-4-maverick:free'27                ]28            ],29            'gemini' => [30                'key' => $geminiKey,31                'models' => ['gemini-2.0-flash']32            ]33        ];34    }35 36    public function generateWithBestProvider(string $prompt, array $availableProviders): array37    {38        // Priorité: OpenRouter d'abord (meilleurs modèles)39        if (in_array('openrouter', $availableProviders)) {40            try {41                return $this->generateWithOpenRouter($prompt);42            } catch (\Exception $e) {43                $this->logger->warning('OpenRouter failed: ' . $e->getMessage());44            }45        }46 47        // Fallback sur Gemini48        if (in_array('gemini', $availableProviders)) {49            try {50                return $this->generateWithGemini($prompt);51            } catch (\Exception $e) {52                $this->logger->warning('Gemini failed: ' . $e->getMessage());53            }54        }55 56        throw new \Exception('No provider available');57    }58 59    private function generateWithOpenRouter(string $prompt): array60    {61        // Sélection aléatoire d'un modèle pour répartir la charge62        $models = $this->providers['openrouter']['models'];63        $model = $models[array_rand($models)];64 65        $response = $this->httpClient->request('POST', 'https://openrouter.ai/api/v1/chat/completions', [66            'headers' => [67                'Authorization' => 'Bearer ' . $this->providers['openrouter']['key'],68                'Content-Type' => 'application/json',69                'HTTP-Referer' => 'http://localhost',70                'X-Title' => 'Vibe Coding Assistant'71            ],72            'json' => [73                'model' => $model,74                'messages' => [75                    [76                        'role' => 'system',77                        'content' => 'Tu es un expert en programmation. Génère du code propre et fonctionnel. Détecte automatiquement le langage.'78                    ],79                    [80                        'role' => 'user',81                        'content' => $prompt82                    ]83                ],84                'temperature' => 0.3,85                'max_tokens' => 200086            ]87        ]);88 89        $data = $response->toArray();90        $code = $data['choices'][0]['message']['content'] ?? '';91 92        return [93            'code' => $code,94            'model' => $model,95            'provider' => 'openrouter'96        ];97    }98 99    private function generateWithGemini(string $prompt): array100    {101        $response = $this->httpClient->request('POST', 102            'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' . 103            $this->providers['gemini']['key'], [104            'json' => [105                'contents' => [106                    [107                        'parts' => [108                            ['text' => $prompt]109                        ]110                    ]111                ]112            ]113        ]);114 115        $data = $response->toArray();116        $code = $data['candidates'][0]['content']['parts'][0]['text'] ?? '';117 118        return [119            'code' => $code,120            'model' => 'gemini-2.0-flash',121            'provider' => 'gemini'122        ];123    }124}