@weirdfingers/baseboards 0.9.5 → 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 +561 -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,405 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Utilities for resolving generation IDs to artifact objects.
|
|
3
|
-
|
|
4
|
-
This module provides utilities for converting generation ID strings (UUIDs)
|
|
5
|
-
into typed artifact objects (ImageArtifact, AudioArtifact, etc.) with proper
|
|
6
|
-
validation of ownership and completion status.
|
|
7
|
-
|
|
8
|
-
The main approach is to automatically detect artifact fields via type introspection
|
|
9
|
-
and resolve them BEFORE Pydantic validation.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from typing import Any, TypeVar, get_args, get_origin
|
|
13
|
-
from uuid import UUID
|
|
14
|
-
|
|
15
|
-
from pydantic import BaseModel
|
|
16
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
17
|
-
|
|
18
|
-
from ..dbmodels import Generations
|
|
19
|
-
from ..jobs import repository as jobs_repo
|
|
20
|
-
from ..logging import get_logger
|
|
21
|
-
from .artifacts import AudioArtifact, ImageArtifact, TextArtifact, VideoArtifact
|
|
22
|
-
|
|
23
|
-
logger = get_logger(__name__)
|
|
24
|
-
|
|
25
|
-
# Type variable for artifact types
|
|
26
|
-
TArtifact = TypeVar("TArtifact", ImageArtifact, VideoArtifact, AudioArtifact, TextArtifact)
|
|
27
|
-
|
|
28
|
-
# Set of all artifact types for quick checking
|
|
29
|
-
ARTIFACT_TYPES = {ImageArtifact, VideoArtifact, AudioArtifact, TextArtifact}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def _extract_artifact_type(annotation: Any) -> type[TArtifact] | None:
|
|
33
|
-
"""Extract artifact type from a field annotation.
|
|
34
|
-
|
|
35
|
-
Handles both single artifacts (ImageArtifact) and lists (list[ImageArtifact]).
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
annotation: The type annotation from a Pydantic field
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
The artifact class if this is an artifact field, None otherwise
|
|
42
|
-
|
|
43
|
-
Examples:
|
|
44
|
-
_extract_artifact_type(ImageArtifact) -> ImageArtifact
|
|
45
|
-
_extract_artifact_type(list[ImageArtifact]) -> ImageArtifact
|
|
46
|
-
_extract_artifact_type(str) -> None
|
|
47
|
-
"""
|
|
48
|
-
# Direct artifact type (e.g., ImageArtifact)
|
|
49
|
-
if annotation in ARTIFACT_TYPES:
|
|
50
|
-
return annotation # type: ignore[return-value]
|
|
51
|
-
|
|
52
|
-
# List of artifacts (e.g., list[ImageArtifact])
|
|
53
|
-
origin = get_origin(annotation)
|
|
54
|
-
if origin is list:
|
|
55
|
-
args = get_args(annotation)
|
|
56
|
-
if args and args[0] in ARTIFACT_TYPES:
|
|
57
|
-
return args[0] # type: ignore[return-value]
|
|
58
|
-
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def extract_artifact_fields(
|
|
63
|
-
schema: type[BaseModel],
|
|
64
|
-
) -> dict[str, tuple[type[TArtifact], bool]]:
|
|
65
|
-
"""Automatically extract artifact fields from a Pydantic schema.
|
|
66
|
-
|
|
67
|
-
Inspects the schema's field annotations and returns a mapping of field names
|
|
68
|
-
to their artifact types and whether they expect a list.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
schema: Pydantic model class to inspect
|
|
72
|
-
|
|
73
|
-
Returns:
|
|
74
|
-
Dictionary mapping field names to (artifact_type, is_list) tuples
|
|
75
|
-
|
|
76
|
-
Example:
|
|
77
|
-
class MyInput(BaseModel):
|
|
78
|
-
prompt: str
|
|
79
|
-
image_source: ImageArtifact
|
|
80
|
-
video_sources: list[VideoArtifact]
|
|
81
|
-
|
|
82
|
-
extract_artifact_fields(MyInput)
|
|
83
|
-
# Returns: {"image_source": (ImageArtifact, False), "video_sources": (VideoArtifact, True)}
|
|
84
|
-
"""
|
|
85
|
-
artifact_fields: dict[str, tuple[type[TArtifact], bool]] = {}
|
|
86
|
-
|
|
87
|
-
for field_name, field_info in schema.model_fields.items():
|
|
88
|
-
artifact_type = _extract_artifact_type(field_info.annotation)
|
|
89
|
-
if artifact_type is not None:
|
|
90
|
-
# Check if the field is a list type
|
|
91
|
-
origin = get_origin(field_info.annotation)
|
|
92
|
-
is_list = origin is list
|
|
93
|
-
artifact_fields[field_name] = (artifact_type, is_list)
|
|
94
|
-
|
|
95
|
-
return artifact_fields
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def _get_artifact_type_name[
|
|
99
|
-
T: (
|
|
100
|
-
ImageArtifact,
|
|
101
|
-
VideoArtifact,
|
|
102
|
-
AudioArtifact,
|
|
103
|
-
TextArtifact,
|
|
104
|
-
)
|
|
105
|
-
](
|
|
106
|
-
artifact_class: type[T],
|
|
107
|
-
) -> str:
|
|
108
|
-
"""Get the database artifact_type string for an artifact class."""
|
|
109
|
-
type_map = {
|
|
110
|
-
ImageArtifact: "image",
|
|
111
|
-
VideoArtifact: "video",
|
|
112
|
-
AudioArtifact: "audio",
|
|
113
|
-
TextArtifact: "text",
|
|
114
|
-
}
|
|
115
|
-
artifact_type = type_map.get(artifact_class)
|
|
116
|
-
if artifact_type is None:
|
|
117
|
-
raise ValueError(f"Unsupported artifact class: {artifact_class}")
|
|
118
|
-
return artifact_type
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def _generation_to_artifact[
|
|
122
|
-
T: (
|
|
123
|
-
ImageArtifact,
|
|
124
|
-
VideoArtifact,
|
|
125
|
-
AudioArtifact,
|
|
126
|
-
TextArtifact,
|
|
127
|
-
)
|
|
128
|
-
](generation: Generations, artifact_class: type[T]) -> T:
|
|
129
|
-
"""Convert a Generations database record to an artifact object.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
generation: Database generation record
|
|
133
|
-
artifact_class: Target artifact class (ImageArtifact, VideoArtifact, etc.)
|
|
134
|
-
|
|
135
|
-
Returns:
|
|
136
|
-
Artifact object populated from the generation record
|
|
137
|
-
|
|
138
|
-
Raises:
|
|
139
|
-
ValueError: If generation is missing required fields or data
|
|
140
|
-
"""
|
|
141
|
-
if not generation.storage_url:
|
|
142
|
-
raise ValueError(
|
|
143
|
-
f"Generation {generation.id} has no storage_url - generation may not be completed"
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
# Get output metadata
|
|
147
|
-
metadata = generation.output_metadata or {}
|
|
148
|
-
|
|
149
|
-
# Build artifact based on type
|
|
150
|
-
if artifact_class == ImageArtifact:
|
|
151
|
-
width = metadata.get("width")
|
|
152
|
-
height = metadata.get("height")
|
|
153
|
-
return ImageArtifact(
|
|
154
|
-
generation_id=str(generation.id),
|
|
155
|
-
storage_url=generation.storage_url,
|
|
156
|
-
format=metadata.get("format", "png"),
|
|
157
|
-
width=width,
|
|
158
|
-
height=height,
|
|
159
|
-
) # type: ignore[return-value]
|
|
160
|
-
|
|
161
|
-
elif artifact_class == VideoArtifact:
|
|
162
|
-
width = metadata.get("width")
|
|
163
|
-
height = metadata.get("height")
|
|
164
|
-
return VideoArtifact(
|
|
165
|
-
generation_id=str(generation.id),
|
|
166
|
-
storage_url=generation.storage_url,
|
|
167
|
-
format=metadata.get("format", "mp4"),
|
|
168
|
-
width=width,
|
|
169
|
-
height=height,
|
|
170
|
-
duration=metadata.get("duration"),
|
|
171
|
-
fps=metadata.get("fps"),
|
|
172
|
-
) # type: ignore[return-value]
|
|
173
|
-
|
|
174
|
-
elif artifact_class == AudioArtifact:
|
|
175
|
-
return AudioArtifact(
|
|
176
|
-
generation_id=str(generation.id),
|
|
177
|
-
storage_url=generation.storage_url,
|
|
178
|
-
format=metadata.get("format", "mp3"),
|
|
179
|
-
duration=metadata.get("duration"),
|
|
180
|
-
sample_rate=metadata.get("sample_rate"),
|
|
181
|
-
channels=metadata.get("channels"),
|
|
182
|
-
) # type: ignore[return-value]
|
|
183
|
-
|
|
184
|
-
elif artifact_class == TextArtifact:
|
|
185
|
-
content = metadata.get("content")
|
|
186
|
-
if content is None:
|
|
187
|
-
raise ValueError(f"Generation {generation.id} missing text content in output_metadata")
|
|
188
|
-
return TextArtifact(
|
|
189
|
-
generation_id=str(generation.id),
|
|
190
|
-
storage_url=generation.storage_url,
|
|
191
|
-
format=metadata.get("format", "plain"),
|
|
192
|
-
content=content,
|
|
193
|
-
) # type: ignore[return-value]
|
|
194
|
-
|
|
195
|
-
else:
|
|
196
|
-
raise ValueError(f"Unsupported artifact class: {artifact_class}")
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
async def resolve_generation_ids_to_artifacts[
|
|
200
|
-
T: (
|
|
201
|
-
ImageArtifact,
|
|
202
|
-
VideoArtifact,
|
|
203
|
-
AudioArtifact,
|
|
204
|
-
TextArtifact,
|
|
205
|
-
)
|
|
206
|
-
](
|
|
207
|
-
generation_ids: list[str | UUID],
|
|
208
|
-
artifact_class: type[T],
|
|
209
|
-
session: AsyncSession,
|
|
210
|
-
tenant_id: UUID,
|
|
211
|
-
) -> list[T]:
|
|
212
|
-
"""Convert a list of generation IDs to typed artifact objects.
|
|
213
|
-
|
|
214
|
-
This function:
|
|
215
|
-
1. Queries the database for each generation ID
|
|
216
|
-
2. Validates the generation is completed
|
|
217
|
-
3. Validates the artifact type matches
|
|
218
|
-
4. Validates the user has access (tenant_id matches)
|
|
219
|
-
5. Converts to the appropriate artifact object
|
|
220
|
-
|
|
221
|
-
Args:
|
|
222
|
-
generation_ids: List of generation IDs (as strings or UUIDs)
|
|
223
|
-
artifact_class: Target artifact class (ImageArtifact, VideoArtifact, etc.)
|
|
224
|
-
session: Database session for queries
|
|
225
|
-
tenant_id: Tenant ID for access validation
|
|
226
|
-
|
|
227
|
-
Returns:
|
|
228
|
-
List of artifact objects
|
|
229
|
-
|
|
230
|
-
Raises:
|
|
231
|
-
ValueError: If any generation is not found, not completed, wrong type, or access denied
|
|
232
|
-
"""
|
|
233
|
-
expected_artifact_type = _get_artifact_type_name(artifact_class)
|
|
234
|
-
artifacts: list[T] = []
|
|
235
|
-
|
|
236
|
-
for gen_id in generation_ids:
|
|
237
|
-
# Query generation from database
|
|
238
|
-
try:
|
|
239
|
-
generation = await jobs_repo.get_generation(session, gen_id)
|
|
240
|
-
except Exception as e:
|
|
241
|
-
raise ValueError(f"Generation {gen_id} not found") from e
|
|
242
|
-
|
|
243
|
-
# Validate tenant access
|
|
244
|
-
if generation.tenant_id != tenant_id:
|
|
245
|
-
raise ValueError(f"Access denied to generation {gen_id} - tenant mismatch")
|
|
246
|
-
|
|
247
|
-
# Validate completion status
|
|
248
|
-
if generation.status != "completed":
|
|
249
|
-
raise ValueError(f"Generation {gen_id} is not completed (status: {generation.status})")
|
|
250
|
-
|
|
251
|
-
# Validate artifact type
|
|
252
|
-
if generation.artifact_type != expected_artifact_type:
|
|
253
|
-
raise ValueError(
|
|
254
|
-
f"Generation {gen_id} has wrong artifact type: "
|
|
255
|
-
f"expected {expected_artifact_type}, got {generation.artifact_type}"
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
# Convert to artifact object
|
|
259
|
-
try:
|
|
260
|
-
artifact = _generation_to_artifact(generation, artifact_class)
|
|
261
|
-
artifacts.append(artifact)
|
|
262
|
-
except ValueError as e:
|
|
263
|
-
raise ValueError(f"Failed to convert generation {gen_id} to artifact: {e}") from e
|
|
264
|
-
|
|
265
|
-
return artifacts
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
async def resolve_input_artifacts(
|
|
269
|
-
input_params: dict[str, Any],
|
|
270
|
-
schema: type[BaseModel],
|
|
271
|
-
session: AsyncSession,
|
|
272
|
-
tenant_id: UUID,
|
|
273
|
-
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
|
|
274
|
-
"""Resolve generation IDs to artifact objects in input parameters.
|
|
275
|
-
|
|
276
|
-
This function automatically detects artifact fields from the Pydantic schema
|
|
277
|
-
via type introspection, then resolves generation ID strings to typed artifact
|
|
278
|
-
objects before Pydantic validation.
|
|
279
|
-
|
|
280
|
-
The function respects the field's type annotation:
|
|
281
|
-
- If field is `ImageArtifact`, input can be a single ID string → returns single artifact
|
|
282
|
-
- If field is `list[ImageArtifact]`, input can be a list of IDs → returns list of artifacts
|
|
283
|
-
(always a list, even if only one ID is provided)
|
|
284
|
-
|
|
285
|
-
Usage in generator input schema (no special declarations needed!):
|
|
286
|
-
class MyGeneratorInput(BaseModel):
|
|
287
|
-
prompt: str = Field(...)
|
|
288
|
-
image_source: ImageArtifact = Field(...) # Automatically detected
|
|
289
|
-
video_sources: list[VideoArtifact] = Field(...) # Also detected
|
|
290
|
-
|
|
291
|
-
Usage in actors.py:
|
|
292
|
-
# Artifacts are automatically detected and resolved
|
|
293
|
-
resolved_params, lineage_metadata = await resolve_input_artifacts(
|
|
294
|
-
input_params,
|
|
295
|
-
MyGeneratorInput, # Just pass the schema class
|
|
296
|
-
session,
|
|
297
|
-
tenant_id,
|
|
298
|
-
)
|
|
299
|
-
# Now validate with resolved artifacts
|
|
300
|
-
typed_inputs = MyGeneratorInput.model_validate(resolved_params)
|
|
301
|
-
|
|
302
|
-
Args:
|
|
303
|
-
input_params: Raw input parameters dictionary (may contain generation IDs)
|
|
304
|
-
schema: Pydantic model class to inspect for artifact fields
|
|
305
|
-
session: Database session for queries
|
|
306
|
-
tenant_id: Tenant ID for access validation
|
|
307
|
-
|
|
308
|
-
Returns:
|
|
309
|
-
Tuple of (resolved_params, lineage_metadata):
|
|
310
|
-
- resolved_params: Updated input_params dictionary with generation IDs resolved to artifacts
|
|
311
|
-
- lineage_metadata: List of dicts with generation_id, role, and artifact_type for lineage
|
|
312
|
-
|
|
313
|
-
Raises:
|
|
314
|
-
ValueError: If any generation ID cannot be resolved or validated
|
|
315
|
-
"""
|
|
316
|
-
# Automatically extract artifact fields from schema
|
|
317
|
-
artifact_field_map = extract_artifact_fields(schema)
|
|
318
|
-
|
|
319
|
-
# If no artifact fields, just return original params with empty lineage
|
|
320
|
-
if not artifact_field_map:
|
|
321
|
-
return input_params, []
|
|
322
|
-
|
|
323
|
-
# Create a new dict with resolved artifacts
|
|
324
|
-
# Use dict constructor to avoid shallow copy issues
|
|
325
|
-
resolved_params = dict(input_params)
|
|
326
|
-
lineage_metadata: list[dict[str, Any]] = []
|
|
327
|
-
|
|
328
|
-
for field_name, (artifact_class, expects_list) in artifact_field_map.items():
|
|
329
|
-
field_value = resolved_params.get(field_name)
|
|
330
|
-
|
|
331
|
-
# Skip if field is not present
|
|
332
|
-
if field_value is None:
|
|
333
|
-
continue
|
|
334
|
-
|
|
335
|
-
# Skip if already artifacts (already resolved)
|
|
336
|
-
if isinstance(field_value, list) and all(
|
|
337
|
-
isinstance(item, artifact_class) for item in field_value
|
|
338
|
-
):
|
|
339
|
-
continue
|
|
340
|
-
|
|
341
|
-
# Also check for single artifact (only if field expects a single artifact)
|
|
342
|
-
if not expects_list and isinstance(field_value, artifact_class):
|
|
343
|
-
continue
|
|
344
|
-
|
|
345
|
-
# Convert field value to list of UUIDs
|
|
346
|
-
generation_ids: list[str | UUID]
|
|
347
|
-
if isinstance(field_value, str):
|
|
348
|
-
# Single generation ID - convert to list for processing
|
|
349
|
-
generation_ids = [field_value]
|
|
350
|
-
elif isinstance(field_value, list):
|
|
351
|
-
# List of generation IDs - ensure all are strings
|
|
352
|
-
# Convert each item to str to ensure type consistency
|
|
353
|
-
generation_ids = [str(item) for item in field_value]
|
|
354
|
-
else:
|
|
355
|
-
raise ValueError(
|
|
356
|
-
f"Field '{field_name}' must be a generation ID (UUID string) "
|
|
357
|
-
f"or list of generation IDs, got: {type(field_value)}"
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
# Resolve to artifacts
|
|
361
|
-
try:
|
|
362
|
-
artifacts = await resolve_generation_ids_to_artifacts(
|
|
363
|
-
generation_ids, artifact_class, session, tenant_id
|
|
364
|
-
)
|
|
365
|
-
except ValueError as e:
|
|
366
|
-
raise ValueError(f"Failed to resolve field '{field_name}': {e}") from e
|
|
367
|
-
|
|
368
|
-
# Capture lineage metadata for each artifact
|
|
369
|
-
artifact_type_name = _get_artifact_type_name(artifact_class)
|
|
370
|
-
for gen_id in generation_ids:
|
|
371
|
-
lineage_metadata.append(
|
|
372
|
-
{
|
|
373
|
-
"generation_id": str(gen_id),
|
|
374
|
-
"role": field_name, # Field name IS the role!
|
|
375
|
-
"artifact_type": artifact_type_name,
|
|
376
|
-
}
|
|
377
|
-
)
|
|
378
|
-
|
|
379
|
-
# Update params with resolved artifacts
|
|
380
|
-
# If field expects a single artifact (not a list), unwrap the first artifact
|
|
381
|
-
# Otherwise, keep as a list (even if there's only one artifact)
|
|
382
|
-
if expects_list:
|
|
383
|
-
resolved_value = artifacts
|
|
384
|
-
else:
|
|
385
|
-
# Field expects a single artifact, so unwrap
|
|
386
|
-
if len(artifacts) != 1:
|
|
387
|
-
raise ValueError(
|
|
388
|
-
f"Field '{field_name}' expects a single artifact, "
|
|
389
|
-
f"but got {len(artifacts)} generation IDs"
|
|
390
|
-
)
|
|
391
|
-
resolved_value = artifacts[0]
|
|
392
|
-
|
|
393
|
-
# Debug logging
|
|
394
|
-
logger.debug(
|
|
395
|
-
"Resolved artifact field",
|
|
396
|
-
field_name=field_name,
|
|
397
|
-
expects_list=expects_list,
|
|
398
|
-
artifacts_type=type(artifacts),
|
|
399
|
-
artifacts_len=len(artifacts),
|
|
400
|
-
resolved_value_type=type(resolved_value),
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
resolved_params[field_name] = resolved_value
|
|
404
|
-
|
|
405
|
-
return resolved_params, lineage_metadata
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Artifact type definitions for the Boards generators system.
|
|
3
|
-
|
|
4
|
-
These Pydantic models represent different types of generated content
|
|
5
|
-
that can be used as inputs and outputs for generators.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from pydantic import BaseModel, Field
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class DigitalArtifact(BaseModel):
|
|
12
|
-
"""Represents a digital artifact from a generation."""
|
|
13
|
-
|
|
14
|
-
generation_id: str = Field(description="ID of the generation that created this artifact")
|
|
15
|
-
storage_url: str = Field(description="URL where the digital file is stored")
|
|
16
|
-
format: str = Field(description="Digital format (png, jpg, webp, etc.)")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class AudioArtifact(DigitalArtifact):
|
|
20
|
-
"""Represents an audio file artifact from a generation."""
|
|
21
|
-
|
|
22
|
-
duration: float | None = Field(None, description="Duration in seconds")
|
|
23
|
-
sample_rate: int | None = Field(None, description="Sample rate in Hz")
|
|
24
|
-
channels: int | None = Field(None, description="Number of audio channels")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class VideoArtifact(DigitalArtifact):
|
|
28
|
-
"""Represents a video file artifact from a generation."""
|
|
29
|
-
|
|
30
|
-
duration: float | None = Field(None, description="Duration in seconds")
|
|
31
|
-
width: int | None = Field(None, description="Video width in pixels")
|
|
32
|
-
height: int | None = Field(None, description="Video height in pixels")
|
|
33
|
-
fps: float | None = Field(None, description="Frames per second")
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class ImageArtifact(DigitalArtifact):
|
|
37
|
-
"""Represents an image file artifact from a generation."""
|
|
38
|
-
|
|
39
|
-
width: int | None = Field(None, description="Image width in pixels")
|
|
40
|
-
height: int | None = Field(None, description="Image height in pixels")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class TextArtifact(DigitalArtifact):
|
|
44
|
-
"""Represents a text artifact from a generation."""
|
|
45
|
-
|
|
46
|
-
content: str = Field(description="The generated text content")
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class LoRArtifact(DigitalArtifact):
|
|
50
|
-
"""Represents a LoRA (Low-Rank Adaptation) model artifact."""
|
|
51
|
-
|
|
52
|
-
base_model: str = Field(description="Base model this LoRA was trained on")
|
|
53
|
-
trigger_words: list[str] | None = Field(None, description="Trigger words for this LoRA")
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Base generator classes and interfaces for the Boards generators system.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from abc import ABC, abstractmethod
|
|
6
|
-
from typing import Protocol, runtime_checkable
|
|
7
|
-
|
|
8
|
-
from pydantic import BaseModel
|
|
9
|
-
|
|
10
|
-
from ..progress.models import ProgressUpdate
|
|
11
|
-
from .artifacts import (
|
|
12
|
-
AudioArtifact,
|
|
13
|
-
DigitalArtifact,
|
|
14
|
-
ImageArtifact,
|
|
15
|
-
TextArtifact,
|
|
16
|
-
VideoArtifact,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class GeneratorResult(BaseModel):
|
|
21
|
-
"""All generators return a list of urls to the artifacts they produce."""
|
|
22
|
-
|
|
23
|
-
outputs: list[DigitalArtifact]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class BaseGenerator(ABC):
|
|
27
|
-
"""
|
|
28
|
-
Abstract base class for all generators in the Boards system.
|
|
29
|
-
|
|
30
|
-
Generators define input/output schemas using Pydantic models and implement
|
|
31
|
-
the generation logic using provider SDKs directly.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
# Class attributes that subclasses must define
|
|
35
|
-
name: str
|
|
36
|
-
artifact_type: str # 'image', 'video', 'audio', 'text', 'lora'
|
|
37
|
-
description: str
|
|
38
|
-
|
|
39
|
-
@abstractmethod
|
|
40
|
-
def get_input_schema(self) -> type[BaseModel]:
|
|
41
|
-
"""
|
|
42
|
-
Return the Pydantic model class that defines the input schema for this generator.
|
|
43
|
-
|
|
44
|
-
Returns:
|
|
45
|
-
Type[BaseModel]: Pydantic model class for input validation
|
|
46
|
-
"""
|
|
47
|
-
pass
|
|
48
|
-
|
|
49
|
-
@abstractmethod
|
|
50
|
-
async def generate(
|
|
51
|
-
self, inputs: BaseModel, context: "GeneratorExecutionContext"
|
|
52
|
-
) -> GeneratorResult:
|
|
53
|
-
"""
|
|
54
|
-
Execute the generation process using the provided inputs.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
inputs: Validated input data matching the input schema
|
|
58
|
-
|
|
59
|
-
Returns:
|
|
60
|
-
BaseModel: Generated output matching the output schema
|
|
61
|
-
"""
|
|
62
|
-
pass
|
|
63
|
-
|
|
64
|
-
@abstractmethod
|
|
65
|
-
async def estimate_cost(self, inputs: BaseModel) -> float:
|
|
66
|
-
"""
|
|
67
|
-
Estimate the cost of running this generation in USD.
|
|
68
|
-
|
|
69
|
-
Args:
|
|
70
|
-
inputs: Input data for cost estimation
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
float: Estimated cost in USD
|
|
74
|
-
"""
|
|
75
|
-
pass
|
|
76
|
-
|
|
77
|
-
def __repr__(self) -> str:
|
|
78
|
-
return f"<{self.__class__.__name__}(name='{self.name}', type='{self.artifact_type}')>"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
@runtime_checkable
|
|
82
|
-
class GeneratorExecutionContext(Protocol):
|
|
83
|
-
"""Typed protocol for the execution context passed to generators.
|
|
84
|
-
|
|
85
|
-
This protocol defines the interface that generators can use to interact
|
|
86
|
-
with storage, database, and progress tracking systems.
|
|
87
|
-
"""
|
|
88
|
-
|
|
89
|
-
async def resolve_artifact(self, artifact: DigitalArtifact) -> str:
|
|
90
|
-
"""Resolve an artifact to a local file path for use with provider SDKs."""
|
|
91
|
-
...
|
|
92
|
-
|
|
93
|
-
async def store_image_result(
|
|
94
|
-
self,
|
|
95
|
-
storage_url: str,
|
|
96
|
-
format: str,
|
|
97
|
-
width: int | None = None,
|
|
98
|
-
height: int | None = None,
|
|
99
|
-
output_index: int = 0,
|
|
100
|
-
) -> ImageArtifact:
|
|
101
|
-
"""Store an image result to permanent storage."""
|
|
102
|
-
...
|
|
103
|
-
|
|
104
|
-
async def store_video_result(
|
|
105
|
-
self,
|
|
106
|
-
storage_url: str,
|
|
107
|
-
format: str,
|
|
108
|
-
width: int | None = None,
|
|
109
|
-
height: int | None = None,
|
|
110
|
-
duration: float | None = None,
|
|
111
|
-
fps: float | None = None,
|
|
112
|
-
output_index: int = 0,
|
|
113
|
-
) -> VideoArtifact:
|
|
114
|
-
"""Store a video result to permanent storage."""
|
|
115
|
-
...
|
|
116
|
-
|
|
117
|
-
async def store_audio_result(
|
|
118
|
-
self,
|
|
119
|
-
storage_url: str,
|
|
120
|
-
format: str,
|
|
121
|
-
duration: float | None = None,
|
|
122
|
-
sample_rate: int | None = None,
|
|
123
|
-
channels: int | None = None,
|
|
124
|
-
output_index: int = 0,
|
|
125
|
-
) -> AudioArtifact:
|
|
126
|
-
"""Store an audio result to permanent storage."""
|
|
127
|
-
...
|
|
128
|
-
|
|
129
|
-
async def store_text_result(
|
|
130
|
-
self,
|
|
131
|
-
content: str,
|
|
132
|
-
format: str,
|
|
133
|
-
output_index: int = 0,
|
|
134
|
-
) -> TextArtifact:
|
|
135
|
-
"""Store a text result to permanent storage."""
|
|
136
|
-
...
|
|
137
|
-
|
|
138
|
-
async def publish_progress(self, update: ProgressUpdate) -> None:
|
|
139
|
-
"""Publish a progress update for this generation."""
|
|
140
|
-
...
|
|
141
|
-
|
|
142
|
-
async def set_external_job_id(self, external_id: str) -> None:
|
|
143
|
-
"""Set the external job ID from the provider (e.g., Replicate prediction ID)."""
|
|
144
|
-
...
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Built-in generator implementations for the Boards system.
|
|
3
|
-
|
|
4
|
-
This package contains example generators that demonstrate how to integrate
|
|
5
|
-
various AI services using their native SDKs.
|
|
6
|
-
|
|
7
|
-
Generators are organized by provider (Replicate, Fal, OpenAI, etc.).
|
|
8
|
-
|
|
9
|
-
Import this module to automatically register all built-in generators:
|
|
10
|
-
import boards.generators.implementations
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
# Import all provider modules to make them available
|
|
14
|
-
from . import fal, openai, replicate
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""Fal.ai provider generators."""
|
|
2
|
-
|
|
3
|
-
from . import audio, image, video
|
|
4
|
-
from .image import (
|
|
5
|
-
FalFluxProUltraGenerator,
|
|
6
|
-
FalNanoBananaEditGenerator,
|
|
7
|
-
FalNanoBananaGenerator,
|
|
8
|
-
)
|
|
9
|
-
from .video import (
|
|
10
|
-
FalKlingVideoV25TurboProTextToVideoGenerator,
|
|
11
|
-
FalSyncLipsyncV2Generator,
|
|
12
|
-
FalVeo31FirstLastFrameToVideoGenerator,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
# Maintain alphabetical order
|
|
16
|
-
__all__ = [
|
|
17
|
-
# Image generators
|
|
18
|
-
"FalFluxProUltraGenerator",
|
|
19
|
-
"FalNanoBananaEditGenerator",
|
|
20
|
-
"FalNanoBananaGenerator",
|
|
21
|
-
# Video generators
|
|
22
|
-
"FalKlingVideoV25TurboProTextToVideoGenerator",
|
|
23
|
-
"FalSyncLipsyncV2Generator",
|
|
24
|
-
"FalVeo31FirstLastFrameToVideoGenerator",
|
|
25
|
-
]
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from .beatoven_music_generation import FalBeatovenMusicGenerationGenerator
|
|
2
|
-
from .beatoven_sound_effect_generation import FalBeatovenSoundEffectGenerationGenerator
|
|
3
|
-
from .chatterbox_text_to_speech import FalChatterboxTextToSpeechGenerator
|
|
4
|
-
from .chatterbox_tts_turbo import FalChatterboxTtsTurboGenerator
|
|
5
|
-
from .elevenlabs_sound_effects_v2 import FalElevenlabsSoundEffectsV2Generator
|
|
6
|
-
from .elevenlabs_tts_eleven_v3 import FalElevenlabsTtsElevenV3Generator
|
|
7
|
-
from .fal_elevenlabs_tts_turbo_v2_5 import FalElevenlabsTtsTurboV25Generator
|
|
8
|
-
from .fal_minimax_speech_26_hd import FalMinimaxSpeech26HdGenerator
|
|
9
|
-
from .minimax_music_v2 import FalMinimaxMusicV2Generator
|
|
10
|
-
from .minimax_speech_2_6_turbo import FalMinimaxSpeech26TurboGenerator
|
|
11
|
-
|
|
12
|
-
__all__ = [
|
|
13
|
-
"FalBeatovenMusicGenerationGenerator",
|
|
14
|
-
"FalBeatovenSoundEffectGenerationGenerator",
|
|
15
|
-
"FalChatterboxTextToSpeechGenerator",
|
|
16
|
-
"FalChatterboxTtsTurboGenerator",
|
|
17
|
-
"FalElevenlabsSoundEffectsV2Generator",
|
|
18
|
-
"FalElevenlabsTtsElevenV3Generator",
|
|
19
|
-
"FalElevenlabsTtsTurboV25Generator",
|
|
20
|
-
"FalMinimaxMusicV2Generator",
|
|
21
|
-
"FalMinimaxSpeech26HdGenerator",
|
|
22
|
-
"FalMinimaxSpeech26TurboGenerator",
|
|
23
|
-
]
|