Runware/ComfyUI fixes, dashboard links, import action, Leonardo plugin, widget, added status field and test connection button
This commit is contained in:
@@ -42,6 +42,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
} else {
|
||||
$this->logError('Failed to enable RunwareAi plugin.', ['provider_name' => $this->apiProvider->name]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -54,9 +55,10 @@ class RunwareAi implements ApiPluginInterface
|
||||
} else {
|
||||
$this->logError('Failed to disable RunwareAi plugin.', ['provider_name' => $this->apiProvider->name]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function getStyledImage(string $promptId): string
|
||||
{
|
||||
throw new \Exception('RunwareAi does not support fetching styled images by prompt ID.');
|
||||
@@ -65,6 +67,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
public function getStatus(string $imageUUID): array
|
||||
{
|
||||
$this->logDebug('Getting status for image.', ['image_uuid' => $imageUUID]);
|
||||
|
||||
// Implement RunwareAI specific status check
|
||||
return ['status' => 'unknown'];
|
||||
}
|
||||
@@ -72,6 +75,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
public function getProgress(string $imageUUID): array
|
||||
{
|
||||
$this->logDebug('Getting progress for image.', ['image_uuid' => $imageUUID]);
|
||||
|
||||
// Implement RunwareAI specific progress check
|
||||
return ['progress' => 0];
|
||||
}
|
||||
@@ -79,9 +83,9 @@ class RunwareAi implements ApiPluginInterface
|
||||
public function processImageStyleChange(\App\Models\Image $image, \App\Models\Style $style): array
|
||||
{
|
||||
// Step 1: Upload the original image
|
||||
$uploadResult = $this->upload(public_path('storage/' . $image->path));
|
||||
$uploadResult = $this->upload(public_path('storage/'.$image->path));
|
||||
|
||||
if (!isset($uploadResult['data'][0]['imageUUID'])) {
|
||||
if (! isset($uploadResult['data'][0]['imageUUID'])) {
|
||||
throw new \Exception('Image upload to AI service failed or returned no UUID.');
|
||||
}
|
||||
$seedImageUUID = $uploadResult['data'][0]['imageUUID'];
|
||||
@@ -89,7 +93,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
// Step 2: Request style change using the uploaded image's UUID
|
||||
$result = $this->styleChangeRequest($style, $seedImageUUID);
|
||||
|
||||
if (!isset($result['base64Data'])) {
|
||||
if (! isset($result['base64Data'])) {
|
||||
throw new \Exception('AI service did not return base64 image data.');
|
||||
}
|
||||
|
||||
@@ -101,41 +105,60 @@ class RunwareAi implements ApiPluginInterface
|
||||
$apiUrl = rtrim($data['api_url'], '/');
|
||||
$token = $data['token'] ?? null;
|
||||
|
||||
if (!$apiUrl || !$token) {
|
||||
if (! $apiUrl || ! $token) {
|
||||
$this->logError('RunwareAI connection test failed: API URL or Token missing.');
|
||||
return false;
|
||||
throw new \RuntimeException('API URL oder Token fehlt.');
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
])->timeout(5)->post($apiUrl, [
|
||||
$payload = [[
|
||||
'taskType' => 'authentication',
|
||||
'apiKey' => $token,
|
||||
'taskUUID' => (string) Str::uuid(),
|
||||
]);
|
||||
]];
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Content-Type' => 'application/json',
|
||||
'Accept' => 'application/json',
|
||||
])->timeout(5)->post($apiUrl, $payload);
|
||||
|
||||
$responseData = $response->json();
|
||||
|
||||
if ($response->successful() && isset($responseData['data']) && !isset($responseData['error'])) {
|
||||
$this->logInfo('RunwareAI connection test successful: Authentication successful.', [
|
||||
// Official Runware format: errors array with code/message.
|
||||
if (isset($responseData['errors'][0])) {
|
||||
$error = $responseData['errors'][0];
|
||||
$messageParts = [
|
||||
$error['code'] ?? 'error',
|
||||
$error['message'] ?? null,
|
||||
];
|
||||
$detail = implode(': ', array_filter($messageParts));
|
||||
|
||||
$this->logError('RunwareAI connection test failed: API returned error.', [
|
||||
'status' => $response->status(),
|
||||
'response' => $responseData,
|
||||
'error' => $error,
|
||||
]);
|
||||
return true;
|
||||
} else {
|
||||
$errorMessage = $responseData['error'] ?? 'Unknown error';
|
||||
$this->logError('RunwareAI connection test failed: Authentication failed.', [
|
||||
'status' => $response->status(),
|
||||
'response' => $responseData,
|
||||
'error_message' => $errorMessage,
|
||||
]);
|
||||
return false;
|
||||
|
||||
throw new \RuntimeException($detail ?: 'Runware API Fehler.');
|
||||
}
|
||||
|
||||
if ($response->failed()) {
|
||||
$this->logError('RunwareAI connection test failed: HTTP error.', [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body(),
|
||||
]);
|
||||
|
||||
throw new \RuntimeException('HTTP '.$response->status().' beim Test der Runware-API.');
|
||||
}
|
||||
|
||||
$this->logInfo('RunwareAI connection test successful: Authentication successful.', [
|
||||
'status' => $response->status(),
|
||||
'response' => $responseData,
|
||||
]);
|
||||
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
$this->logError('RunwareAI connection test failed: Exception caught.', ['error' => $e->getMessage()]);
|
||||
return false;
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,33 +166,36 @@ class RunwareAi implements ApiPluginInterface
|
||||
{
|
||||
$this->logInfo('Checking RunwareAI availability.');
|
||||
|
||||
if (!$this->apiProvider->enabled) {
|
||||
if (! $this->apiProvider->enabled) {
|
||||
$this->logDebug('RunwareAI provider is disabled.');
|
||||
|
||||
return [
|
||||
'available' => false,
|
||||
'reason' => 'Provider is disabled',
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($this->apiProvider->api_url)) {
|
||||
$this->logDebug('RunwareAI API URL is not configured.');
|
||||
|
||||
return [
|
||||
'available' => false,
|
||||
'reason' => 'API URL not configured',
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($this->apiProvider->token)) {
|
||||
$this->logDebug('RunwareAI API token is not configured.');
|
||||
|
||||
return [
|
||||
'available' => false,
|
||||
'reason' => 'API token not configured',
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -185,44 +211,47 @@ class RunwareAi implements ApiPluginInterface
|
||||
|
||||
$responseData = $response->json();
|
||||
|
||||
if ($response->successful() && isset($responseData['data']) && !isset($responseData['error'])) {
|
||||
if ($response->successful() && isset($responseData['data']) && ! isset($responseData['error'])) {
|
||||
$this->logInfo('RunwareAI is available.');
|
||||
|
||||
return [
|
||||
'available' => true,
|
||||
'reason' => 'Connection successful',
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
} else {
|
||||
$errorMessage = $responseData['error'] ?? 'Unknown error';
|
||||
$this->logError('RunwareAI connection failed.', [
|
||||
'status' => $response->status(),
|
||||
'error_message' => $errorMessage
|
||||
'error_message' => $errorMessage,
|
||||
]);
|
||||
|
||||
return [
|
||||
'available' => false,
|
||||
'reason' => 'Connection failed: ' . $errorMessage,
|
||||
'reason' => 'Connection failed: '.$errorMessage,
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logError('RunwareAI availability check failed.', ['error' => $e->getMessage()]);
|
||||
|
||||
return [
|
||||
'available' => false,
|
||||
'reason' => 'Connection error: ' . $e->getMessage(),
|
||||
'reason' => 'Connection error: '.$e->getMessage(),
|
||||
'provider_id' => $this->apiProvider->id,
|
||||
'provider_name' => $this->apiProvider->name
|
||||
'provider_name' => $this->apiProvider->name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function searchModels(string $searchTerm): array
|
||||
{
|
||||
$this->logInfo('Attempting model search on RunwareAI.', ['searchTerm' => $searchTerm]);
|
||||
if (!$this->apiProvider->api_url || !$this->apiProvider->token) {
|
||||
if (! $this->apiProvider->api_url || ! $this->apiProvider->token) {
|
||||
$this->logError('RunwareAI API URL or Token not configured for model search.', ['provider_name' => $this->apiProvider->name]);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -231,7 +260,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Authorization' => 'Bearer '.$token,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
])->timeout(10)->post($apiUrl, [
|
||||
@@ -242,12 +271,12 @@ class RunwareAi implements ApiPluginInterface
|
||||
'category' => 'checkpoint',
|
||||
'limit' => 100,
|
||||
'taskUUID' => (string) Str::uuid(),
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$responseData = $response->json();
|
||||
|
||||
if ($response->successful() && isset($responseData['data'][0]['results']) && !isset($responseData['error'])) {
|
||||
if ($response->successful() && isset($responseData['data'][0]['results']) && ! isset($responseData['error'])) {
|
||||
$models = [];
|
||||
foreach ($responseData['data'][0]['results'] as $model) {
|
||||
$models[] = [
|
||||
@@ -257,6 +286,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
];
|
||||
}
|
||||
$this->logInfo('Model search successful on RunwareAI.', ['searchTerm' => $searchTerm, 'modelsFound' => count($models)]);
|
||||
|
||||
return $models;
|
||||
} else {
|
||||
$errorMessage = $responseData['error'] ?? 'Unknown error';
|
||||
@@ -265,10 +295,12 @@ class RunwareAi implements ApiPluginInterface
|
||||
'response' => $responseData,
|
||||
'error_message' => $errorMessage,
|
||||
]);
|
||||
|
||||
return [];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logError('Model search failed on RunwareAI: Exception caught.', ['error' => $e->getMessage()]);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -276,7 +308,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
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) {
|
||||
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.');
|
||||
}
|
||||
@@ -285,11 +317,11 @@ class RunwareAi implements ApiPluginInterface
|
||||
$token = $this->apiProvider->token;
|
||||
$taskUUID = (string) Str::uuid();
|
||||
|
||||
$imageData = 'data:image/png;base64,' . base64_encode(file_get_contents($imagePath));
|
||||
$imageData = 'data:image/png;base64,'.base64_encode(file_get_contents($imagePath));
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Authorization' => 'Bearer '.$token,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
])->post($apiUrl, [
|
||||
@@ -297,11 +329,12 @@ class RunwareAi implements ApiPluginInterface
|
||||
'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]);
|
||||
@@ -312,7 +345,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
private function styleChangeRequest(\App\Models\Style $style, string $seedImageUUID): array
|
||||
{
|
||||
$this->logInfo('Attempting style change request to RunwareAI.', ['style_id' => $style->id, 'seed_image_uuid' => $seedImageUUID]);
|
||||
if (!$this->apiProvider->api_url || !$this->apiProvider->token) {
|
||||
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.');
|
||||
}
|
||||
@@ -331,7 +364,7 @@ class RunwareAi implements ApiPluginInterface
|
||||
'positivePrompt' => $style->prompt,
|
||||
'seedImage' => $seedImageUUID,
|
||||
'outputType' => 'base64Data',
|
||||
'model' => $style->aiModel->model_id
|
||||
'model' => $style->aiModel->model_id,
|
||||
];
|
||||
|
||||
foreach ($mergedParams as $key => $value) {
|
||||
@@ -340,22 +373,23 @@ class RunwareAi implements ApiPluginInterface
|
||||
|
||||
try {
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Authorization' => 'Bearer '.$token,
|
||||
'Accept' => 'application/json',
|
||||
])->post($apiUrl, [
|
||||
$data
|
||||
$data,
|
||||
]);
|
||||
|
||||
$response->throw();
|
||||
$responseData = $response->json();
|
||||
|
||||
if (!isset($responseData['data'][0]['imageBase64Data'])) {
|
||||
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 = [];
|
||||
@@ -367,4 +401,4 @@ class RunwareAi implements ApiPluginInterface
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user