apiProvider = $apiProvider; $this->logInfo('RunwareAi plugin initialized.', ['provider_name' => $apiProvider->name]); } public function getIdentifier(): string { return 'runwareai'; } public function getName(): string { return 'RunwareAI'; } public function isEnabled(): bool { return $this->apiProvider->enabled; } public function enable(): bool { $this->apiProvider->enabled = true; $result = $this->apiProvider->save(); if ($result) { $this->logInfo('RunwareAi plugin enabled.', ['provider_name' => $this->apiProvider->name]); } else { $this->logError('Failed to enable RunwareAi plugin.', ['provider_name' => $this->apiProvider->name]); } return $result; } public function disable(): bool { $this->apiProvider->enabled = false; $result = $this->apiProvider->save(); if ($result) { $this->logInfo('RunwareAi plugin disabled.', ['provider_name' => $this->apiProvider->name]); } else { $this->logError('Failed to disable RunwareAi plugin.', ['provider_name' => $this->apiProvider->name]); } return $result; } public function getStatus(string $imageUUID): array { $this->logDebug('Getting status for image.', ['image_uuid' => $imageUUID]); // Implement RunwareAI specific status check return ['status' => 'unknown']; } public function getProgress(string $imageUUID): array { $this->logDebug('Getting progress for image.', ['image_uuid' => $imageUUID]); // Implement RunwareAI specific progress check return ['progress' => 0]; } public function processImageStyleChange(string $imagePath, string $prompt, string $modelId, ?string $parameters = null): array { // Step 1: Upload the original image $uploadResult = $this->upload($imagePath); if (!isset($uploadResult['data'][0]['imageUUID'])) { throw new \Exception('Image upload to AI service failed or returned no UUID.'); } $seedImageUUID = $uploadResult['data'][0]['imageUUID']; // Step 2: Request style change using the uploaded image's UUID $result = $this->styleChangeRequest($prompt, $seedImageUUID, $modelId, $parameters); if (!isset($result['base64Data'])) { throw new \Exception('AI service did not return base64 image data.'); } return $result; } private function upload(string $imagePath): array { $this->logInfo('Attempting to upload image to RunwareAI.', ['image_path' => $imagePath]); if (!$this->apiProvider->api_url || !$this->apiProvider->token) { $this->logError('RunwareAI API URL or Token not configured for upload.', ['provider_name' => $this->apiProvider->name]); throw new \Exception('RunwareAI API URL or Token not configured.'); } $apiUrl = rtrim($this->apiProvider->api_url, '/'); $token = $this->apiProvider->token; $taskUUID = (string) Str::uuid(); $imageData = 'data:image/png;base64,' . base64_encode(file_get_contents($imagePath)); try { $response = Http::withHeaders([ 'Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json', 'Content-Type' => 'application/json', ])->post($apiUrl, [ [ 'taskType' => 'imageUpload', 'taskUUID' => $taskUUID, 'image' => $imageData, ] ]); $response->throw(); $this->logInfo('Image uploaded successfully to RunwareAI.', ['task_uuid' => $taskUUID, 'response' => $response->json()]); return $response->json(); } catch (\Exception $e) { $this->logError('Image upload to RunwareAI failed.', ['error' => $e->getMessage(), 'image_path' => $imagePath]); throw $e; } } private function styleChangeRequest(string $prompt, string $seedImageUUID, string $modelId, ?string $parameters = null): array { $this->logInfo('Attempting style change request to RunwareAI.', ['prompt' => $prompt, 'seed_image_uuid' => $seedImageUUID]); if (!$this->apiProvider->api_url || !$this->apiProvider->token) { $this->logError('RunwareAI API URL or Token not configured for style change.', ['provider_name' => $this->apiProvider->name]); throw new \Exception('RunwareAI API URL or Token not configured.'); } $apiUrl = rtrim($this->apiProvider->api_url, '/'); $token = $this->apiProvider->token; $taskUUID = (string) Str::uuid(); $data = [ 'taskType' => 'imageInference', 'taskUUID' => $taskUUID, 'positivePrompt' => $prompt, 'seedImage' => $seedImageUUID, 'outputType' => 'base64Data', 'model' => $modelId, ]; $decodedParameters = json_decode($parameters, true) ?? []; foreach ($decodedParameters as $key => $value) { $data[$key] = $value; } try { $response = Http::withHeaders([ 'Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json', ])->post($apiUrl, [ $data ]); $response->throw(); $responseData = $response->json(); if (!isset($responseData['data'][0]['imageBase64Data'])) { throw new \Exception('AI service did not return base64 image data.'); } $base64Image = $responseData['data'][0]['imageBase64Data']; $this->logInfo('Style change request successful to RunwareAI.', ['task_uuid' => $taskUUID, 'response' => $responseData]); return ['base64Data' => $base64Image]; } catch (\Exception $e) { $errorData = []; /*if ($e instanceof \Illuminate\Http\Client\RequestException && $e->response) { $errorData['response_body'] = $e->response->body(); $errorData['response_status'] = $e->response->status(); }*/ $this->logError('Style change request to RunwareAI failed.', ['error' => $e->getMessage(), 'task_uuid' => $taskUUID] + $errorData); throw $e; } } }