@weirdfingers/baseboards 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +560 -469
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
- package/templates/README.md +0 -122
- package/templates/api/.env.example +0 -65
- package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
- package/templates/api/Dockerfile +0 -32
- package/templates/api/README.md +0 -264
- package/templates/api/alembic/env.py +0 -114
- package/templates/api/alembic/script.py.mako +0 -28
- package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
- package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
- package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
- package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
- package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
- package/templates/api/alembic.ini +0 -36
- package/templates/api/config/generators.yaml +0 -237
- package/templates/api/config/storage_config.yaml +0 -26
- package/templates/api/docs/ADDING_GENERATORS.md +0 -409
- package/templates/api/docs/GENERATORS_API.md +0 -502
- package/templates/api/docs/MIGRATIONS.md +0 -472
- package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
- package/templates/api/docs/storage_providers.md +0 -337
- package/templates/api/pyproject.toml +0 -205
- package/templates/api/src/boards/__init__.py +0 -10
- package/templates/api/src/boards/api/app.py +0 -172
- package/templates/api/src/boards/api/auth.py +0 -75
- package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
- package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
- package/templates/api/src/boards/api/endpoints/setup.py +0 -505
- package/templates/api/src/boards/api/endpoints/sse.py +0 -129
- package/templates/api/src/boards/api/endpoints/storage.py +0 -155
- package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
- package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
- package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
- package/templates/api/src/boards/auth/__init__.py +0 -15
- package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
- package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
- package/templates/api/src/boards/auth/adapters/base.py +0 -73
- package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
- package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
- package/templates/api/src/boards/auth/adapters/none.py +0 -102
- package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
- package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
- package/templates/api/src/boards/auth/context.py +0 -35
- package/templates/api/src/boards/auth/factory.py +0 -129
- package/templates/api/src/boards/auth/middleware.py +0 -221
- package/templates/api/src/boards/auth/provisioning.py +0 -129
- package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
- package/templates/api/src/boards/cli.py +0 -354
- package/templates/api/src/boards/config.py +0 -131
- package/templates/api/src/boards/database/__init__.py +0 -7
- package/templates/api/src/boards/database/cli.py +0 -110
- package/templates/api/src/boards/database/connection.py +0 -292
- package/templates/api/src/boards/database/models.py +0 -19
- package/templates/api/src/boards/database/seed_data.py +0 -182
- package/templates/api/src/boards/dbmodels/__init__.py +0 -441
- package/templates/api/src/boards/generators/__init__.py +0 -57
- package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
- package/templates/api/src/boards/generators/artifacts.py +0 -53
- package/templates/api/src/boards/generators/base.py +0 -144
- package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
- package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
- package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
- package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
- package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
- package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
- package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
- package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
- package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
- package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
- package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
- package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
- package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
- package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
- package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
- package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
- package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
- package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
- package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
- package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
- package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
- package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
- package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
- package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
- package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
- package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
- package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
- package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
- package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
- package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
- package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
- package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
- package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
- package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
- package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
- package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
- package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
- package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
- package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
- package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
- package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
- package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
- package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
- package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
- package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
- package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
- package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
- package/templates/api/src/boards/generators/loader.py +0 -253
- package/templates/api/src/boards/generators/registry.py +0 -114
- package/templates/api/src/boards/generators/resolution.py +0 -632
- package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
- package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
- package/templates/api/src/boards/graphql/__init__.py +0 -7
- package/templates/api/src/boards/graphql/access_control.py +0 -136
- package/templates/api/src/boards/graphql/mutations/root.py +0 -148
- package/templates/api/src/boards/graphql/queries/root.py +0 -116
- package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
- package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
- package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
- package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
- package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
- package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
- package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
- package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
- package/templates/api/src/boards/graphql/schema.py +0 -81
- package/templates/api/src/boards/graphql/types/board.py +0 -102
- package/templates/api/src/boards/graphql/types/generation.py +0 -166
- package/templates/api/src/boards/graphql/types/generator.py +0 -17
- package/templates/api/src/boards/graphql/types/user.py +0 -47
- package/templates/api/src/boards/jobs/repository.py +0 -153
- package/templates/api/src/boards/logging.py +0 -195
- package/templates/api/src/boards/middleware.py +0 -339
- package/templates/api/src/boards/progress/__init__.py +0 -4
- package/templates/api/src/boards/progress/models.py +0 -25
- package/templates/api/src/boards/progress/publisher.py +0 -64
- package/templates/api/src/boards/py.typed +0 -0
- package/templates/api/src/boards/redis_pool.py +0 -118
- package/templates/api/src/boards/storage/__init__.py +0 -52
- package/templates/api/src/boards/storage/base.py +0 -363
- package/templates/api/src/boards/storage/config.py +0 -187
- package/templates/api/src/boards/storage/factory.py +0 -288
- package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
- package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
- package/templates/api/src/boards/storage/implementations/local.py +0 -201
- package/templates/api/src/boards/storage/implementations/s3.py +0 -294
- package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
- package/templates/api/src/boards/tenant_isolation.py +0 -446
- package/templates/api/src/boards/validation.py +0 -262
- package/templates/api/src/boards/workers/__init__.py +0 -1
- package/templates/api/src/boards/workers/actors.py +0 -274
- package/templates/api/src/boards/workers/cli.py +0 -125
- package/templates/api/src/boards/workers/context.py +0 -348
- package/templates/api/src/boards/workers/middleware.py +0 -58
- package/templates/api/src/py.typed +0 -0
- package/templates/compose.web.yaml +0 -35
- package/templates/compose.yaml +0 -116
- package/templates/docker/env.example +0 -23
- package/templates/web/.env.example +0 -28
- package/templates/web/Dockerfile +0 -51
- package/templates/web/components.json +0 -22
- package/templates/web/imageLoader.js +0 -18
- package/templates/web/next-env.d.ts +0 -5
- package/templates/web/next.config.js +0 -36
- package/templates/web/package.json +0 -41
- package/templates/web/postcss.config.mjs +0 -7
- package/templates/web/public/favicon.ico +0 -0
- package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
- package/templates/web/src/app/globals.css +0 -123
- package/templates/web/src/app/layout.tsx +0 -31
- package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
- package/templates/web/src/app/page.tsx +0 -35
- package/templates/web/src/app/providers.tsx +0 -18
- package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
- package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
- package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
- package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
- package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
- package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
- package/templates/web/src/components/header.tsx +0 -32
- package/templates/web/src/components/theme-provider.tsx +0 -10
- package/templates/web/src/components/theme-toggle.tsx +0 -75
- package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
- package/templates/web/src/components/ui/button.tsx +0 -58
- package/templates/web/src/components/ui/card.tsx +0 -92
- package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
- package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
- package/templates/web/src/components/ui/toast.tsx +0 -128
- package/templates/web/src/components/ui/toaster.tsx +0 -35
- package/templates/web/src/components/ui/use-toast.ts +0 -187
- package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
- package/templates/web/src/lib/utils.ts +0 -6
- package/templates/web/tsconfig.json +0 -41
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
# Generators API Reference
|
|
2
|
-
|
|
3
|
-
This document provides detailed API reference for the Boards generators system.
|
|
4
|
-
|
|
5
|
-
## Core Classes
|
|
6
|
-
|
|
7
|
-
### BaseGenerator
|
|
8
|
-
|
|
9
|
-
Abstract base class for all generators.
|
|
10
|
-
|
|
11
|
-
```python
|
|
12
|
-
from boards.generators.base import BaseGenerator
|
|
13
|
-
|
|
14
|
-
class MyGenerator(BaseGenerator):
|
|
15
|
-
name: str # Unique identifier for the generator
|
|
16
|
-
artifact_type: str # Type of artifact produced ('image', 'video', 'audio', 'text', 'lora')
|
|
17
|
-
description: str # Human-readable description
|
|
18
|
-
|
|
19
|
-
def get_input_schema(self) -> Type[BaseModel]:
|
|
20
|
-
"""Return Pydantic model class for input validation."""
|
|
21
|
-
pass
|
|
22
|
-
|
|
23
|
-
async def generate(self, inputs: BaseModel) -> BaseModel:
|
|
24
|
-
"""Execute generation and return results."""
|
|
25
|
-
pass
|
|
26
|
-
|
|
27
|
-
async def estimate_cost(self, inputs: BaseModel) -> float:
|
|
28
|
-
"""Estimate cost in USD for this generation."""
|
|
29
|
-
pass
|
|
30
|
-
|
|
31
|
-
def get_output_schema(self) -> Type[BaseModel]:
|
|
32
|
-
"""Return Pydantic model class for output (optional override)."""
|
|
33
|
-
pass
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
#### Required Attributes
|
|
37
|
-
|
|
38
|
-
- **`name`**: Unique string identifier (e.g., `"flux-pro"`, `"whisper"`)
|
|
39
|
-
- **`artifact_type`**: One of `"image"`, `"video"`, `"audio"`, `"text"`, `"lora"`
|
|
40
|
-
- **`description`**: Brief description of what the generator does
|
|
41
|
-
|
|
42
|
-
#### Required Methods
|
|
43
|
-
|
|
44
|
-
- **`get_input_schema()`**: Return the Pydantic model class that defines valid inputs
|
|
45
|
-
- **`generate(inputs)`**: Core generation logic that produces artifacts
|
|
46
|
-
- **`estimate_cost(inputs)`**: Return estimated cost in USD as a float
|
|
47
|
-
|
|
48
|
-
## Artifact Types
|
|
49
|
-
|
|
50
|
-
### ImageArtifact
|
|
51
|
-
|
|
52
|
-
Represents generated or input images.
|
|
53
|
-
|
|
54
|
-
```python
|
|
55
|
-
from boards.generators.artifacts import ImageArtifact
|
|
56
|
-
|
|
57
|
-
artifact = ImageArtifact(
|
|
58
|
-
generation_id="gen_123", # ID of generation that created this
|
|
59
|
-
storage_url="https://...", # URL where image is stored
|
|
60
|
-
width=1024, # Image width in pixels
|
|
61
|
-
height=1024, # Image height in pixels
|
|
62
|
-
format="png" # Image format (png, jpg, webp, etc.)
|
|
63
|
-
)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### VideoArtifact
|
|
67
|
-
|
|
68
|
-
Represents generated or input videos.
|
|
69
|
-
|
|
70
|
-
```python
|
|
71
|
-
from boards.generators.artifacts import VideoArtifact
|
|
72
|
-
|
|
73
|
-
artifact = VideoArtifact(
|
|
74
|
-
generation_id="gen_456", # Required: generation ID
|
|
75
|
-
storage_url="https://...", # Required: storage location
|
|
76
|
-
width=1920, # Required: video width
|
|
77
|
-
height=1080, # Required: video height
|
|
78
|
-
format="mp4", # Required: video format
|
|
79
|
-
duration=60.5, # Optional: duration in seconds
|
|
80
|
-
fps=30.0 # Optional: frames per second
|
|
81
|
-
)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### AudioArtifact
|
|
85
|
-
|
|
86
|
-
Represents generated or input audio.
|
|
87
|
-
|
|
88
|
-
```python
|
|
89
|
-
from boards.generators.artifacts import AudioArtifact
|
|
90
|
-
|
|
91
|
-
artifact = AudioArtifact(
|
|
92
|
-
generation_id="gen_789", # Required: generation ID
|
|
93
|
-
storage_url="https://...", # Required: storage location
|
|
94
|
-
format="mp3", # Required: audio format
|
|
95
|
-
duration=120.0, # Optional: duration in seconds
|
|
96
|
-
sample_rate=44100, # Optional: sample rate in Hz
|
|
97
|
-
channels=2 # Optional: number of channels
|
|
98
|
-
)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### TextArtifact
|
|
102
|
-
|
|
103
|
-
Represents generated or input text.
|
|
104
|
-
|
|
105
|
-
```python
|
|
106
|
-
from boards.generators.artifacts import TextArtifact
|
|
107
|
-
|
|
108
|
-
artifact = TextArtifact(
|
|
109
|
-
generation_id="gen_text", # Required: generation ID
|
|
110
|
-
content="Generated text...", # Required: the actual text content
|
|
111
|
-
format="plain" # Optional: format (plain, markdown, html)
|
|
112
|
-
)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### LoRArtifact
|
|
116
|
-
|
|
117
|
-
Represents LoRA (Low-Rank Adaptation) models.
|
|
118
|
-
|
|
119
|
-
```python
|
|
120
|
-
from boards.generators.artifacts import LoRArtifact
|
|
121
|
-
|
|
122
|
-
artifact = LoRArtifact(
|
|
123
|
-
generation_id="gen_lora", # Required: generation ID
|
|
124
|
-
storage_url="https://...", # Required: storage location
|
|
125
|
-
base_model="sd-v1.5", # Required: base model name
|
|
126
|
-
format="safetensors", # Required: file format
|
|
127
|
-
trigger_words=["style1", "tag"] # Optional: trigger words list
|
|
128
|
-
)
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Generator Registry
|
|
132
|
-
|
|
133
|
-
### Global Registry
|
|
134
|
-
|
|
135
|
-
The system provides a global registry for managing generators:
|
|
136
|
-
|
|
137
|
-
```python
|
|
138
|
-
from boards.generators.registry import registry
|
|
139
|
-
|
|
140
|
-
# Register a generator
|
|
141
|
-
generator_instance = MyGenerator()
|
|
142
|
-
registry.register(generator_instance)
|
|
143
|
-
|
|
144
|
-
# Get a generator by name
|
|
145
|
-
generator = registry.get("my-generator")
|
|
146
|
-
|
|
147
|
-
# List all generators
|
|
148
|
-
all_generators = registry.list_all()
|
|
149
|
-
|
|
150
|
-
# List generators by artifact type
|
|
151
|
-
image_generators = registry.list_by_artifact_type("image")
|
|
152
|
-
|
|
153
|
-
# Check if generator exists
|
|
154
|
-
if "my-generator" in registry:
|
|
155
|
-
print("Generator is registered")
|
|
156
|
-
|
|
157
|
-
# Get count of registered generators
|
|
158
|
-
count = len(registry)
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### GeneratorRegistry Methods
|
|
162
|
-
|
|
163
|
-
```python
|
|
164
|
-
class GeneratorRegistry:
|
|
165
|
-
def register(self, generator: BaseGenerator) -> None:
|
|
166
|
-
"""Register a generator instance."""
|
|
167
|
-
|
|
168
|
-
def get(self, name: str) -> Optional[BaseGenerator]:
|
|
169
|
-
"""Get generator by name, returns None if not found."""
|
|
170
|
-
|
|
171
|
-
def list_all(self) -> List[BaseGenerator]:
|
|
172
|
-
"""Return all registered generators."""
|
|
173
|
-
|
|
174
|
-
def list_by_artifact_type(self, artifact_type: str) -> List[BaseGenerator]:
|
|
175
|
-
"""Return generators that produce the specified artifact type."""
|
|
176
|
-
|
|
177
|
-
def list_names(self) -> List[str]:
|
|
178
|
-
"""Return list of all registered generator names."""
|
|
179
|
-
|
|
180
|
-
def unregister(self, name: str) -> bool:
|
|
181
|
-
"""Remove generator by name. Returns True if found and removed."""
|
|
182
|
-
|
|
183
|
-
def clear(self) -> None:
|
|
184
|
-
"""Remove all registered generators."""
|
|
185
|
-
|
|
186
|
-
def __contains__(self, name: str) -> bool:
|
|
187
|
-
"""Check if generator with name is registered."""
|
|
188
|
-
|
|
189
|
-
def __len__(self) -> int:
|
|
190
|
-
"""Return number of registered generators."""
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## Artifact Resolution
|
|
194
|
-
|
|
195
|
-
### resolve_artifact()
|
|
196
|
-
|
|
197
|
-
Converts artifact references to local file paths for use with provider SDKs:
|
|
198
|
-
|
|
199
|
-
```python
|
|
200
|
-
from boards.generators.resolution import resolve_artifact
|
|
201
|
-
|
|
202
|
-
async def generate(self, inputs):
|
|
203
|
-
# Resolve artifacts to local file paths
|
|
204
|
-
audio_path = await resolve_artifact(inputs.audio_source)
|
|
205
|
-
video_path = await resolve_artifact(inputs.video_source)
|
|
206
|
-
|
|
207
|
-
# Now you can pass file paths to any provider SDK
|
|
208
|
-
result = await provider.process(audio=audio_path, video=video_path)
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
**Supported artifacts**: `AudioArtifact`, `VideoArtifact`, `ImageArtifact`, `LoRArtifact`
|
|
212
|
-
|
|
213
|
-
**Not supported**: `TextArtifact` (use `.content` property directly)
|
|
214
|
-
|
|
215
|
-
### Store Result Functions
|
|
216
|
-
|
|
217
|
-
Create artifact instances from generated content:
|
|
218
|
-
|
|
219
|
-
```python
|
|
220
|
-
from boards.generators.resolution import (
|
|
221
|
-
store_image_result,
|
|
222
|
-
store_video_result,
|
|
223
|
-
store_audio_result
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
# Store generated image
|
|
227
|
-
image_artifact = await store_image_result(
|
|
228
|
-
storage_url="https://storage.com/image.png",
|
|
229
|
-
format="png",
|
|
230
|
-
generation_id="gen_123",
|
|
231
|
-
width=1024,
|
|
232
|
-
height=1024
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
# Store generated video
|
|
236
|
-
video_artifact = await store_video_result(
|
|
237
|
-
storage_url="https://storage.com/video.mp4",
|
|
238
|
-
format="mp4",
|
|
239
|
-
generation_id="gen_456",
|
|
240
|
-
width=1920,
|
|
241
|
-
height=1080,
|
|
242
|
-
duration=60.0, # Optional
|
|
243
|
-
fps=30.0 # Optional
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
# Store generated audio
|
|
247
|
-
audio_artifact = await store_audio_result(
|
|
248
|
-
storage_url="https://storage.com/audio.mp3",
|
|
249
|
-
format="mp3",
|
|
250
|
-
generation_id="gen_789",
|
|
251
|
-
duration=120.0, # Optional
|
|
252
|
-
sample_rate=44100, # Optional
|
|
253
|
-
channels=2 # Optional
|
|
254
|
-
)
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## Pydantic Integration
|
|
258
|
-
|
|
259
|
-
### Input Schema Patterns
|
|
260
|
-
|
|
261
|
-
#### Basic Inputs
|
|
262
|
-
|
|
263
|
-
```python
|
|
264
|
-
from pydantic import BaseModel, Field
|
|
265
|
-
|
|
266
|
-
class BasicInput(BaseModel):
|
|
267
|
-
prompt: str = Field(description="Text prompt")
|
|
268
|
-
strength: float = Field(default=0.75, ge=0.0, le=1.0, description="Generation strength")
|
|
269
|
-
seed: Optional[int] = Field(None, description="Random seed")
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
#### Artifact Inputs
|
|
273
|
-
|
|
274
|
-
```python
|
|
275
|
-
class ArtifactInput(BaseModel):
|
|
276
|
-
image_source: ImageArtifact = Field(description="Input image")
|
|
277
|
-
audio_source: AudioArtifact = Field(description="Input audio")
|
|
278
|
-
reference_text: TextArtifact = Field(description="Reference text")
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
#### Validation and Constraints
|
|
282
|
-
|
|
283
|
-
```python
|
|
284
|
-
from pydantic import field_validator
|
|
285
|
-
|
|
286
|
-
class ValidatedInput(BaseModel):
|
|
287
|
-
prompt: str = Field(min_length=1, max_length=500)
|
|
288
|
-
quality: str = Field(pattern="^(low|medium|high)$")
|
|
289
|
-
dimensions: str = Field(pattern="^\\d+x\\d+$")
|
|
290
|
-
|
|
291
|
-
@field_validator('prompt')
|
|
292
|
-
@classmethod
|
|
293
|
-
def validate_prompt(cls, v):
|
|
294
|
-
if 'forbidden' in v.lower():
|
|
295
|
-
raise ValueError('Prompt contains forbidden content')
|
|
296
|
-
return v.strip()
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
#### Conditional Fields
|
|
300
|
-
|
|
301
|
-
```python
|
|
302
|
-
class ConditionalInput(BaseModel):
|
|
303
|
-
mode: str = Field(pattern="^(text|image)$")
|
|
304
|
-
text_prompt: Optional[str] = Field(None)
|
|
305
|
-
image_prompt: Optional[ImageArtifact] = Field(None)
|
|
306
|
-
|
|
307
|
-
@model_validator(mode='after')
|
|
308
|
-
def validate_conditional_fields(self):
|
|
309
|
-
if self.mode == 'text' and not self.text_prompt:
|
|
310
|
-
raise ValueError('text_prompt required when mode=text')
|
|
311
|
-
elif self.mode == 'image' and not self.image_prompt:
|
|
312
|
-
raise ValueError('image_prompt required when mode=image')
|
|
313
|
-
return self
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### Output Schema Patterns
|
|
317
|
-
|
|
318
|
-
#### Simple Outputs
|
|
319
|
-
|
|
320
|
-
```python
|
|
321
|
-
class SimpleOutput(BaseModel):
|
|
322
|
-
result: ImageArtifact
|
|
323
|
-
metadata: dict = Field(default_factory=dict)
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
#### Multiple Artifacts
|
|
327
|
-
|
|
328
|
-
```python
|
|
329
|
-
class MultiOutput(BaseModel):
|
|
330
|
-
images: List[ImageArtifact] = Field(description="Generated images")
|
|
331
|
-
preview: ImageArtifact = Field(description="Low-res preview")
|
|
332
|
-
generation_time: float = Field(description="Time taken in seconds")
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
## JSON Schema Generation
|
|
336
|
-
|
|
337
|
-
Pydantic models automatically generate JSON schemas for frontend integration:
|
|
338
|
-
|
|
339
|
-
```python
|
|
340
|
-
# Get JSON schema for frontend type generation
|
|
341
|
-
schema = MyInputClass.model_json_schema()
|
|
342
|
-
|
|
343
|
-
# Example output:
|
|
344
|
-
{
|
|
345
|
-
"type": "object",
|
|
346
|
-
"properties": {
|
|
347
|
-
"prompt": {
|
|
348
|
-
"type": "string",
|
|
349
|
-
"description": "Text prompt",
|
|
350
|
-
"minLength": 1,
|
|
351
|
-
"maxLength": 500
|
|
352
|
-
},
|
|
353
|
-
"strength": {
|
|
354
|
-
"type": "number",
|
|
355
|
-
"minimum": 0.0,
|
|
356
|
-
"maximum": 1.0,
|
|
357
|
-
"default": 0.75,
|
|
358
|
-
"description": "Generation strength"
|
|
359
|
-
}
|
|
360
|
-
},
|
|
361
|
-
"required": ["prompt"]
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
## Error Handling
|
|
366
|
-
|
|
367
|
-
### Common Error Patterns
|
|
368
|
-
|
|
369
|
-
```python
|
|
370
|
-
async def generate(self, inputs):
|
|
371
|
-
# Check environment variables
|
|
372
|
-
api_key = os.getenv("PROVIDER_API_KEY")
|
|
373
|
-
if not api_key:
|
|
374
|
-
raise ValueError(
|
|
375
|
-
"PROVIDER_API_KEY environment variable required. "
|
|
376
|
-
"Get your key from https://provider.com/keys"
|
|
377
|
-
)
|
|
378
|
-
|
|
379
|
-
# Provider-specific error handling
|
|
380
|
-
try:
|
|
381
|
-
result = await provider.generate(inputs)
|
|
382
|
-
except provider.AuthenticationError:
|
|
383
|
-
raise ValueError("Invalid API key - check PROVIDER_API_KEY")
|
|
384
|
-
except provider.RateLimitError as e:
|
|
385
|
-
raise ValueError(f"Rate limited - retry after {e.retry_after} seconds")
|
|
386
|
-
except provider.ValidationError as e:
|
|
387
|
-
raise ValueError(f"Invalid input: {e.message}")
|
|
388
|
-
except Exception as e:
|
|
389
|
-
raise RuntimeError(f"Generation failed: {str(e)}")
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### Best Practices
|
|
393
|
-
|
|
394
|
-
1. **Specific Error Messages**: Provide actionable error messages
|
|
395
|
-
2. **Environment Variable Checks**: Validate required configuration early
|
|
396
|
-
3. **Provider Error Translation**: Convert provider errors to user-friendly messages
|
|
397
|
-
4. **Resource Cleanup**: Clean up temporary files in finally blocks
|
|
398
|
-
|
|
399
|
-
## Testing
|
|
400
|
-
|
|
401
|
-
### Generator Testing Pattern
|
|
402
|
-
|
|
403
|
-
```python
|
|
404
|
-
import pytest
|
|
405
|
-
from unittest.mock import patch, AsyncMock
|
|
406
|
-
|
|
407
|
-
class TestMyGenerator:
|
|
408
|
-
def setup_method(self):
|
|
409
|
-
self.generator = MyGenerator()
|
|
410
|
-
|
|
411
|
-
def test_metadata(self):
|
|
412
|
-
assert self.generator.name == "my-generator"
|
|
413
|
-
assert self.generator.artifact_type == "image"
|
|
414
|
-
|
|
415
|
-
def test_input_schema(self):
|
|
416
|
-
schema_class = self.generator.get_input_schema()
|
|
417
|
-
assert schema_class == MyInputClass
|
|
418
|
-
|
|
419
|
-
# Test schema validation
|
|
420
|
-
valid_input = schema_class(prompt="test")
|
|
421
|
-
assert valid_input.prompt == "test"
|
|
422
|
-
|
|
423
|
-
@pytest.mark.asyncio
|
|
424
|
-
async def test_generate_success(self):
|
|
425
|
-
inputs = MyInputClass(prompt="test prompt")
|
|
426
|
-
|
|
427
|
-
with patch.dict(os.environ, {"API_KEY": "fake-key"}):
|
|
428
|
-
with patch('provider.generate') as mock_generate:
|
|
429
|
-
mock_generate.return_value = "fake_result_url"
|
|
430
|
-
|
|
431
|
-
result = await self.generator.generate(inputs)
|
|
432
|
-
|
|
433
|
-
assert isinstance(result, MyOutputClass)
|
|
434
|
-
mock_generate.assert_called_once()
|
|
435
|
-
|
|
436
|
-
@pytest.mark.asyncio
|
|
437
|
-
async def test_generate_missing_api_key(self):
|
|
438
|
-
inputs = MyInputClass(prompt="test")
|
|
439
|
-
|
|
440
|
-
with patch.dict(os.environ, {}, clear=True):
|
|
441
|
-
with pytest.raises(ValueError, match="API_KEY.*required"):
|
|
442
|
-
await self.generator.generate(inputs)
|
|
443
|
-
|
|
444
|
-
@pytest.mark.asyncio
|
|
445
|
-
async def test_estimate_cost(self):
|
|
446
|
-
inputs = MyInputClass(prompt="short")
|
|
447
|
-
cost = await self.generator.estimate_cost(inputs)
|
|
448
|
-
|
|
449
|
-
assert isinstance(cost, float)
|
|
450
|
-
assert cost > 0
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
## Integration Points
|
|
454
|
-
|
|
455
|
-
### Storage System Integration
|
|
456
|
-
|
|
457
|
-
Generators integrate with the Boards storage system through the resolution utilities:
|
|
458
|
-
|
|
459
|
-
```python
|
|
460
|
-
# The store_*_result functions will be implemented to:
|
|
461
|
-
# 1. Upload content to configured storage backend (S3, local, etc.)
|
|
462
|
-
# 2. Return artifact with proper storage_url
|
|
463
|
-
# 3. Handle metadata and thumbnails
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### Database Integration
|
|
467
|
-
|
|
468
|
-
Generated artifacts are automatically stored in the database with:
|
|
469
|
-
|
|
470
|
-
- Generation metadata (model, parameters, cost)
|
|
471
|
-
- Artifact metadata (dimensions, duration, format)
|
|
472
|
-
- Relationships to boards and users
|
|
473
|
-
- Audit trail information
|
|
474
|
-
|
|
475
|
-
### GraphQL API Integration
|
|
476
|
-
|
|
477
|
-
Registered generators are automatically exposed via GraphQL:
|
|
478
|
-
|
|
479
|
-
```graphql
|
|
480
|
-
query GetGenerators($artifactType: String) {
|
|
481
|
-
generators(artifactType: $artifactType) {
|
|
482
|
-
name
|
|
483
|
-
artifactType
|
|
484
|
-
description
|
|
485
|
-
inputSchema # JSON schema for frontend
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
mutation RunGeneration($generatorName: String!, $inputs: JSON!) {
|
|
490
|
-
runGeneration(generatorName: $generatorName, inputs: $inputs) {
|
|
491
|
-
id
|
|
492
|
-
status
|
|
493
|
-
result {
|
|
494
|
-
... on ImageArtifact {
|
|
495
|
-
storageUrl
|
|
496
|
-
width
|
|
497
|
-
height
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
```
|