feat(ai): add runware model search and model-constrained img2img
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Filament\Resources\AiStyles;
|
||||
use App\Filament\Clusters\RareAdmin\RareAdminCluster;
|
||||
use App\Filament\Resources\AiStyles\Pages\ManageAiStyles;
|
||||
use App\Models\AiStyle;
|
||||
use App\Services\AiEditing\RunwareModelSearchService;
|
||||
use App\Services\Audit\SuperAdminAuditLogger;
|
||||
use BackedEnum;
|
||||
use Filament\Actions;
|
||||
@@ -15,6 +16,8 @@ use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Components\Utilities\Set;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
@@ -82,10 +85,74 @@ class AiStyleResource extends Resource
|
||||
])
|
||||
->required()
|
||||
->default('runware'),
|
||||
TextInput::make('provider_model')
|
||||
->maxLength(120),
|
||||
Select::make('provider_model')
|
||||
->label('Runware model (AIR)')
|
||||
->searchable()
|
||||
->getSearchResultsUsing(static fn (string $search): array => app(RunwareModelSearchService::class)->searchOptions($search))
|
||||
->getOptionLabelUsing(static fn (mixed $value): ?string => app(RunwareModelSearchService::class)->labelForModel($value))
|
||||
->helperText('Start typing to search models from runware.ai.')
|
||||
->native(false)
|
||||
->live()
|
||||
->afterStateUpdated(static function (Set $set, ?string $state): void {
|
||||
self::applySelectedRunwareModel($set, $state);
|
||||
}),
|
||||
])
|
||||
->columns(2),
|
||||
Section::make('Runware Generation')
|
||||
->schema([
|
||||
TextInput::make('metadata.runware.generation.width')
|
||||
->label('Width')
|
||||
->numeric()
|
||||
->minValue(64)
|
||||
->maxValue(4096)
|
||||
->step(64)
|
||||
->helperText(static fn (Get $get): ?string => self::dimensionConstraintHint($get, 'width')),
|
||||
TextInput::make('metadata.runware.generation.height')
|
||||
->label('Height')
|
||||
->numeric()
|
||||
->minValue(64)
|
||||
->maxValue(4096)
|
||||
->step(64)
|
||||
->helperText(static fn (Get $get): ?string => self::dimensionConstraintHint($get, 'height')),
|
||||
TextInput::make('metadata.runware.generation.steps')
|
||||
->label('Steps')
|
||||
->numeric()
|
||||
->minValue(1)
|
||||
->maxValue(150)
|
||||
->helperText(static fn (Get $get): ?string => self::rangeConstraintHint($get, 'steps')),
|
||||
TextInput::make('metadata.runware.generation.cfg_scale')
|
||||
->label('CFG Scale')
|
||||
->numeric()
|
||||
->minValue(0)
|
||||
->maxValue(30)
|
||||
->step(0.1)
|
||||
->helperText(static fn (Get $get): ?string => self::rangeConstraintHint($get, 'cfg_scale')),
|
||||
TextInput::make('metadata.runware.generation.strength')
|
||||
->label('Strength')
|
||||
->numeric()
|
||||
->minValue(0)
|
||||
->maxValue(1)
|
||||
->step(0.01)
|
||||
->helperText(static fn (Get $get): ?string => self::rangeConstraintHint($get, 'strength')),
|
||||
Select::make('metadata.runware.generation.output_format')
|
||||
->label('Output format')
|
||||
->options([
|
||||
'JPG' => 'JPG',
|
||||
'PNG' => 'PNG',
|
||||
'WEBP' => 'WEBP',
|
||||
])
|
||||
->default('JPG')
|
||||
->native(false),
|
||||
Select::make('metadata.runware.generation.delivery_method')
|
||||
->label('Delivery method')
|
||||
->options([
|
||||
'async' => 'async (queue + poll)',
|
||||
'sync' => 'sync',
|
||||
])
|
||||
->default('async')
|
||||
->native(false),
|
||||
])
|
||||
->columns(3),
|
||||
Section::make('Prompts')
|
||||
->schema([
|
||||
Textarea::make('description')
|
||||
@@ -160,4 +227,79 @@ class AiStyleResource extends Resource
|
||||
'index' => ManageAiStyles::route('/'),
|
||||
];
|
||||
}
|
||||
|
||||
private static function applySelectedRunwareModel(Set $set, ?string $air): void
|
||||
{
|
||||
if (! is_string($air) || trim($air) === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$model = app(RunwareModelSearchService::class)->findByAir($air);
|
||||
if (! is_array($model)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$set('metadata.runware.model.air', $model['air']);
|
||||
$set('metadata.runware.model.name', $model['name']);
|
||||
$set('metadata.runware.model.architecture', $model['architecture']);
|
||||
$set('metadata.runware.model.category', $model['category']);
|
||||
|
||||
foreach ((array) ($model['constraints'] ?? []) as $key => $value) {
|
||||
$set("metadata.runware.constraints.{$key}", $value);
|
||||
}
|
||||
|
||||
self::setIfNumeric($set, 'metadata.runware.generation.width', $model['defaults']['width'] ?? null);
|
||||
self::setIfNumeric($set, 'metadata.runware.generation.height', $model['defaults']['height'] ?? null);
|
||||
self::setIfNumeric($set, 'metadata.runware.generation.steps', $model['defaults']['steps'] ?? null);
|
||||
self::setIfNumeric($set, 'metadata.runware.generation.cfg_scale', $model['defaults']['cfg_scale'] ?? null);
|
||||
}
|
||||
|
||||
private static function setIfNumeric(Set $set, string $path, mixed $value): void
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
$set($path, $value);
|
||||
}
|
||||
}
|
||||
|
||||
private static function dimensionConstraintHint(Get $get, string $dimension): ?string
|
||||
{
|
||||
$min = $get("metadata.runware.constraints.min_{$dimension}");
|
||||
$max = $get("metadata.runware.constraints.max_{$dimension}");
|
||||
$step = $get("metadata.runware.constraints.{$dimension}_step");
|
||||
|
||||
if (! is_numeric($min) && ! is_numeric($max) && ! is_numeric($step)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = [];
|
||||
if (is_numeric($min) || is_numeric($max)) {
|
||||
$parts[] = sprintf(
|
||||
'Model range: %s - %s',
|
||||
is_numeric($min) ? (string) (int) $min : '?',
|
||||
is_numeric($max) ? (string) (int) $max : '?'
|
||||
);
|
||||
}
|
||||
|
||||
if (is_numeric($step) && (int) $step > 0) {
|
||||
$parts[] = sprintf('Step: %d', (int) $step);
|
||||
}
|
||||
|
||||
return $parts !== [] ? implode(' | ', $parts) : null;
|
||||
}
|
||||
|
||||
private static function rangeConstraintHint(Get $get, string $field): ?string
|
||||
{
|
||||
$min = $get("metadata.runware.constraints.min_{$field}");
|
||||
$max = $get("metadata.runware.constraints.max_{$field}");
|
||||
|
||||
if (! is_numeric($min) && ! is_numeric($max)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'Model range: %s - %s',
|
||||
is_numeric($min) ? trim((string) $min) : '?',
|
||||
is_numeric($max) ? trim((string) $max) : '?'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user