Upload wizard:
- Refactored UploadWizard into modular steps (Step1FileUpload, Step2Details, Step3Publish)
- Extracted reusable hooks: useUploadMachine, useFileValidation, useVisionTags
- Extracted reusable components: CategorySelector, ContentTypeSelector
- Added TagPicker component (studio-style list picker with AI badge + new-tag insertion)
- Fixed TagInput auto-open bug (hasFocusedRef guard)
- Replaced TagInput with TagPicker in UploadSidebar
Vision AI tag suggestions:
- Add UploadVisionSuggestController: sync POST /api/uploads/{id}/vision-suggest
- Calls vision.klevze.net/analyze/all on upload completion (before step 2 opens)
- Two-phase useVisionTags: immediate gateway call + background DB polling
- Trigger fires on uploadReady (not step change) so tags arrive before user sees step 2
- Added vision.gateway config block with VISION_GATEWAY_URL env
Artwork versioning system:
- ArtworkVersion / ArtworkVersionEvent models
- ArtworkVersioningService: createNewVersion, restoreVersion, rate limiting, ranking decay
- Migrations: artwork_versions, artwork_version_events, versioning columns on artworks
- Studio API routes: GET versions, POST restore/{version_id}
- Feature tests: ArtworkVersioningTest (13 cases)
63 lines
2.6 KiB
PHP
63 lines
2.6 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
return [
|
||
'enabled' => env('VISION_ENABLED', true),
|
||
|
||
'queue' => env('VISION_QUEUE', 'default'),
|
||
|
||
'clip' => [
|
||
'base_url' => env('CLIP_BASE_URL', ''),
|
||
'endpoint' => env('CLIP_ANALYZE_ENDPOINT', '/analyze'),
|
||
'timeout_seconds' => (int) env('CLIP_TIMEOUT_SECONDS', 8),
|
||
'connect_timeout_seconds' => (int) env('CLIP_CONNECT_TIMEOUT_SECONDS', 2),
|
||
'retries' => (int) env('CLIP_HTTP_RETRIES', 1),
|
||
'retry_delay_ms' => (int) env('CLIP_HTTP_RETRY_DELAY_MS', 200),
|
||
],
|
||
|
||
'yolo' => [
|
||
'enabled' => env('YOLO_ENABLED', true),
|
||
'base_url' => env('YOLO_BASE_URL', ''),
|
||
'endpoint' => env('YOLO_ANALYZE_ENDPOINT', '/analyze'),
|
||
'timeout_seconds' => (int) env('YOLO_TIMEOUT_SECONDS', 8),
|
||
'connect_timeout_seconds' => (int) env('YOLO_CONNECT_TIMEOUT_SECONDS', 2),
|
||
'retries' => (int) env('YOLO_HTTP_RETRIES', 1),
|
||
'retry_delay_ms' => (int) env('YOLO_HTTP_RETRY_DELAY_MS', 200),
|
||
|
||
// Only run YOLO for photography content type.
|
||
'photography_only' => env('YOLO_PHOTOGRAPHY_ONLY', true),
|
||
],
|
||
|
||
// Which derivative variant to send to vision services.
|
||
'image_variant' => env('VISION_IMAGE_VARIANT', 'md'),
|
||
|
||
/*
|
||
|--------------------------------------------------------------------------
|
||
| Vision Gateway (aggregates CLIP + BLIP + YOLO via /analyze/all)
|
||
|--------------------------------------------------------------------------
|
||
| Falls back to CLIP base_url when VISION_GATEWAY_URL is not set.
|
||
*/
|
||
'gateway' => [
|
||
'base_url' => env('VISION_GATEWAY_URL', env('CLIP_BASE_URL', '')),
|
||
'timeout_seconds' => (int) env('VISION_GATEWAY_TIMEOUT', 10),
|
||
'connect_timeout_seconds'=> (int) env('VISION_GATEWAY_CONNECT_TIMEOUT', 3),
|
||
],
|
||
|
||
/*
|
||
|--------------------------------------------------------------------------
|
||
| LM Studio – local multimodal inference (tag generation)
|
||
|--------------------------------------------------------------------------
|
||
*/
|
||
'lm_studio' => [
|
||
'base_url' => env('LM_STUDIO_URL', 'http://172.28.16.1:8200'),
|
||
'model' => env('LM_STUDIO_MODEL', 'google/gemma-3-4b'),
|
||
'timeout' => (int) env('LM_STUDIO_TIMEOUT', 60),
|
||
'connect_timeout' => (int) env('LM_STUDIO_CONNECT_TIMEOUT', 5),
|
||
'temperature' => (float) env('LM_STUDIO_TEMPERATURE', 0.3),
|
||
'max_tokens' => (int) env('LM_STUDIO_MAX_TOKENS', 300),
|
||
// Maximum number of AI-suggested tags to keep per artwork.
|
||
'max_tags' => (int) env('LM_STUDIO_MAX_TAGS', 12),
|
||
],
|
||
];
|