@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.
Files changed (237) hide show
  1. package/dist/index.js +561 -469
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -5
  4. package/templates/README.md +0 -122
  5. package/templates/api/.env.example +0 -65
  6. package/templates/api/ARTIFACT_RESOLUTION_GUIDE.md +0 -148
  7. package/templates/api/Dockerfile +0 -32
  8. package/templates/api/README.md +0 -264
  9. package/templates/api/alembic/env.py +0 -114
  10. package/templates/api/alembic/script.py.mako +0 -28
  11. package/templates/api/alembic/versions/20250101_000000_initial_schema.py +0 -506
  12. package/templates/api/alembic/versions/20251022_174729_remove_provider_name_from_generations.py +0 -75
  13. package/templates/api/alembic/versions/20251023_165852_switch_to_declarative_base_and_mapping.py +0 -467
  14. package/templates/api/alembic/versions/20251202_000000_add_artifact_lineage.py +0 -134
  15. package/templates/api/alembic/versions/2025925_62735_add_seed_data_for_default_tenant.py +0 -88
  16. package/templates/api/alembic.ini +0 -36
  17. package/templates/api/config/generators.yaml +0 -237
  18. package/templates/api/config/storage_config.yaml +0 -26
  19. package/templates/api/docs/ADDING_GENERATORS.md +0 -409
  20. package/templates/api/docs/GENERATORS_API.md +0 -502
  21. package/templates/api/docs/MIGRATIONS.md +0 -472
  22. package/templates/api/docs/TESTING_LIVE_APIS.md +0 -417
  23. package/templates/api/docs/storage_providers.md +0 -337
  24. package/templates/api/pyproject.toml +0 -205
  25. package/templates/api/src/boards/__init__.py +0 -10
  26. package/templates/api/src/boards/api/app.py +0 -172
  27. package/templates/api/src/boards/api/auth.py +0 -75
  28. package/templates/api/src/boards/api/endpoints/__init__.py +0 -3
  29. package/templates/api/src/boards/api/endpoints/jobs.py +0 -76
  30. package/templates/api/src/boards/api/endpoints/setup.py +0 -505
  31. package/templates/api/src/boards/api/endpoints/sse.py +0 -129
  32. package/templates/api/src/boards/api/endpoints/storage.py +0 -155
  33. package/templates/api/src/boards/api/endpoints/tenant_registration.py +0 -296
  34. package/templates/api/src/boards/api/endpoints/uploads.py +0 -149
  35. package/templates/api/src/boards/api/endpoints/webhooks.py +0 -13
  36. package/templates/api/src/boards/auth/__init__.py +0 -15
  37. package/templates/api/src/boards/auth/adapters/__init__.py +0 -27
  38. package/templates/api/src/boards/auth/adapters/auth0.py +0 -220
  39. package/templates/api/src/boards/auth/adapters/base.py +0 -73
  40. package/templates/api/src/boards/auth/adapters/clerk.py +0 -172
  41. package/templates/api/src/boards/auth/adapters/jwt.py +0 -122
  42. package/templates/api/src/boards/auth/adapters/none.py +0 -102
  43. package/templates/api/src/boards/auth/adapters/oidc.py +0 -284
  44. package/templates/api/src/boards/auth/adapters/supabase.py +0 -110
  45. package/templates/api/src/boards/auth/context.py +0 -35
  46. package/templates/api/src/boards/auth/factory.py +0 -129
  47. package/templates/api/src/boards/auth/middleware.py +0 -221
  48. package/templates/api/src/boards/auth/provisioning.py +0 -129
  49. package/templates/api/src/boards/auth/tenant_extraction.py +0 -278
  50. package/templates/api/src/boards/cli.py +0 -354
  51. package/templates/api/src/boards/config.py +0 -131
  52. package/templates/api/src/boards/database/__init__.py +0 -7
  53. package/templates/api/src/boards/database/cli.py +0 -110
  54. package/templates/api/src/boards/database/connection.py +0 -292
  55. package/templates/api/src/boards/database/models.py +0 -19
  56. package/templates/api/src/boards/database/seed_data.py +0 -182
  57. package/templates/api/src/boards/dbmodels/__init__.py +0 -441
  58. package/templates/api/src/boards/generators/__init__.py +0 -57
  59. package/templates/api/src/boards/generators/artifact_resolution.py +0 -405
  60. package/templates/api/src/boards/generators/artifacts.py +0 -53
  61. package/templates/api/src/boards/generators/base.py +0 -144
  62. package/templates/api/src/boards/generators/implementations/__init__.py +0 -14
  63. package/templates/api/src/boards/generators/implementations/fal/__init__.py +0 -25
  64. package/templates/api/src/boards/generators/implementations/fal/audio/__init__.py +0 -23
  65. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_music_generation.py +0 -171
  66. package/templates/api/src/boards/generators/implementations/fal/audio/beatoven_sound_effect_generation.py +0 -167
  67. package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_text_to_speech.py +0 -176
  68. package/templates/api/src/boards/generators/implementations/fal/audio/chatterbox_tts_turbo.py +0 -195
  69. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_sound_effects_v2.py +0 -194
  70. package/templates/api/src/boards/generators/implementations/fal/audio/elevenlabs_tts_eleven_v3.py +0 -209
  71. package/templates/api/src/boards/generators/implementations/fal/audio/fal_elevenlabs_tts_turbo_v2_5.py +0 -206
  72. package/templates/api/src/boards/generators/implementations/fal/audio/fal_minimax_speech_26_hd.py +0 -237
  73. package/templates/api/src/boards/generators/implementations/fal/audio/minimax_music_v2.py +0 -173
  74. package/templates/api/src/boards/generators/implementations/fal/audio/minimax_speech_2_6_turbo.py +0 -221
  75. package/templates/api/src/boards/generators/implementations/fal/image/__init__.py +0 -63
  76. package/templates/api/src/boards/generators/implementations/fal/image/bytedance_seedream_v45_edit.py +0 -219
  77. package/templates/api/src/boards/generators/implementations/fal/image/clarity_upscaler.py +0 -220
  78. package/templates/api/src/boards/generators/implementations/fal/image/crystal_upscaler.py +0 -173
  79. package/templates/api/src/boards/generators/implementations/fal/image/fal_ideogram_character.py +0 -227
  80. package/templates/api/src/boards/generators/implementations/fal/image/flux_2.py +0 -203
  81. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_edit.py +0 -230
  82. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro.py +0 -204
  83. package/templates/api/src/boards/generators/implementations/fal/image/flux_2_pro_edit.py +0 -221
  84. package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_kontext.py +0 -216
  85. package/templates/api/src/boards/generators/implementations/fal/image/flux_pro_ultra.py +0 -197
  86. package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image.py +0 -177
  87. package/templates/api/src/boards/generators/implementations/fal/image/gemini_25_flash_image_edit.py +0 -208
  88. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_15_edit.py +0 -216
  89. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_5.py +0 -177
  90. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_edit_image.py +0 -182
  91. package/templates/api/src/boards/generators/implementations/fal/image/gpt_image_1_mini.py +0 -167
  92. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_character_edit.py +0 -299
  93. package/templates/api/src/boards/generators/implementations/fal/image/ideogram_v2.py +0 -190
  94. package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview.py +0 -191
  95. package/templates/api/src/boards/generators/implementations/fal/image/imagen4_preview_fast.py +0 -179
  96. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana.py +0 -183
  97. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_edit.py +0 -212
  98. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro.py +0 -179
  99. package/templates/api/src/boards/generators/implementations/fal/image/nano_banana_pro_edit.py +0 -226
  100. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image.py +0 -249
  101. package/templates/api/src/boards/generators/implementations/fal/image/qwen_image_edit.py +0 -244
  102. package/templates/api/src/boards/generators/implementations/fal/image/reve_edit.py +0 -178
  103. package/templates/api/src/boards/generators/implementations/fal/image/reve_text_to_image.py +0 -155
  104. package/templates/api/src/boards/generators/implementations/fal/image/seedream_v45_text_to_image.py +0 -180
  105. package/templates/api/src/boards/generators/implementations/fal/utils.py +0 -61
  106. package/templates/api/src/boards/generators/implementations/fal/video/__init__.py +0 -77
  107. package/templates/api/src/boards/generators/implementations/fal/video/bytedance_seedance_v1_pro_text_to_video.py +0 -209
  108. package/templates/api/src/boards/generators/implementations/fal/video/creatify_lipsync.py +0 -161
  109. package/templates/api/src/boards/generators/implementations/fal/video/fal_bytedance_seedance_v1_pro_image_to_video.py +0 -222
  110. package/templates/api/src/boards/generators/implementations/fal/video/fal_minimax_hailuo_02_standard_text_to_video.py +0 -152
  111. package/templates/api/src/boards/generators/implementations/fal/video/fal_pixverse_lipsync.py +0 -197
  112. package/templates/api/src/boards/generators/implementations/fal/video/fal_sora_2_text_to_video.py +0 -173
  113. package/templates/api/src/boards/generators/implementations/fal/video/infinitalk.py +0 -221
  114. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_pro.py +0 -168
  115. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_ai_avatar_v2_standard.py +0 -159
  116. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_image_to_video.py +0 -175
  117. package/templates/api/src/boards/generators/implementations/fal/video/kling_video_v2_5_turbo_pro_text_to_video.py +0 -168
  118. package/templates/api/src/boards/generators/implementations/fal/video/minimax_hailuo_2_3_pro_image_to_video.py +0 -153
  119. package/templates/api/src/boards/generators/implementations/fal/video/sora2_image_to_video.py +0 -172
  120. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_image_to_video_pro.py +0 -175
  121. package/templates/api/src/boards/generators/implementations/fal/video/sora_2_text_to_video_pro.py +0 -163
  122. package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2.py +0 -167
  123. package/templates/api/src/boards/generators/implementations/fal/video/sync_lipsync_v2_pro.py +0 -155
  124. package/templates/api/src/boards/generators/implementations/fal/video/veed_fabric_1_0.py +0 -180
  125. package/templates/api/src/boards/generators/implementations/fal/video/veed_lipsync.py +0 -174
  126. package/templates/api/src/boards/generators/implementations/fal/video/veo3.py +0 -194
  127. package/templates/api/src/boards/generators/implementations/fal/video/veo31.py +0 -190
  128. package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast.py +0 -190
  129. package/templates/api/src/boards/generators/implementations/fal/video/veo31_fast_image_to_video.py +0 -191
  130. package/templates/api/src/boards/generators/implementations/fal/video/veo31_first_last_frame_to_video.py +0 -187
  131. package/templates/api/src/boards/generators/implementations/fal/video/veo31_image_to_video.py +0 -183
  132. package/templates/api/src/boards/generators/implementations/fal/video/veo31_reference_to_video.py +0 -172
  133. package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_image_to_video.py +0 -212
  134. package/templates/api/src/boards/generators/implementations/fal/video/wan_25_preview_text_to_video.py +0 -208
  135. package/templates/api/src/boards/generators/implementations/fal/video/wan_pro_image_to_video.py +0 -158
  136. package/templates/api/src/boards/generators/implementations/kie/__init__.py +0 -11
  137. package/templates/api/src/boards/generators/implementations/kie/base.py +0 -316
  138. package/templates/api/src/boards/generators/implementations/kie/image/__init__.py +0 -3
  139. package/templates/api/src/boards/generators/implementations/kie/image/nano_banana_edit.py +0 -190
  140. package/templates/api/src/boards/generators/implementations/kie/utils.py +0 -98
  141. package/templates/api/src/boards/generators/implementations/kie/video/__init__.py +0 -8
  142. package/templates/api/src/boards/generators/implementations/kie/video/veo3.py +0 -161
  143. package/templates/api/src/boards/generators/implementations/openai/__init__.py +0 -1
  144. package/templates/api/src/boards/generators/implementations/openai/audio/__init__.py +0 -1
  145. package/templates/api/src/boards/generators/implementations/openai/audio/whisper.py +0 -69
  146. package/templates/api/src/boards/generators/implementations/openai/image/__init__.py +0 -1
  147. package/templates/api/src/boards/generators/implementations/openai/image/dalle3.py +0 -96
  148. package/templates/api/src/boards/generators/implementations/replicate/__init__.py +0 -1
  149. package/templates/api/src/boards/generators/implementations/replicate/image/__init__.py +0 -1
  150. package/templates/api/src/boards/generators/implementations/replicate/image/flux_pro.py +0 -88
  151. package/templates/api/src/boards/generators/implementations/replicate/video/__init__.py +0 -1
  152. package/templates/api/src/boards/generators/implementations/replicate/video/lipsync.py +0 -73
  153. package/templates/api/src/boards/generators/loader.py +0 -253
  154. package/templates/api/src/boards/generators/registry.py +0 -114
  155. package/templates/api/src/boards/generators/resolution.py +0 -632
  156. package/templates/api/src/boards/generators/testmods/class_gen.py +0 -34
  157. package/templates/api/src/boards/generators/testmods/import_side_effect.py +0 -35
  158. package/templates/api/src/boards/graphql/__init__.py +0 -7
  159. package/templates/api/src/boards/graphql/access_control.py +0 -136
  160. package/templates/api/src/boards/graphql/mutations/root.py +0 -148
  161. package/templates/api/src/boards/graphql/queries/root.py +0 -116
  162. package/templates/api/src/boards/graphql/resolvers/__init__.py +0 -8
  163. package/templates/api/src/boards/graphql/resolvers/auth.py +0 -12
  164. package/templates/api/src/boards/graphql/resolvers/board.py +0 -1053
  165. package/templates/api/src/boards/graphql/resolvers/generation.py +0 -666
  166. package/templates/api/src/boards/graphql/resolvers/generator.py +0 -50
  167. package/templates/api/src/boards/graphql/resolvers/lineage.py +0 -381
  168. package/templates/api/src/boards/graphql/resolvers/upload.py +0 -463
  169. package/templates/api/src/boards/graphql/resolvers/user.py +0 -25
  170. package/templates/api/src/boards/graphql/schema.py +0 -81
  171. package/templates/api/src/boards/graphql/types/board.py +0 -102
  172. package/templates/api/src/boards/graphql/types/generation.py +0 -166
  173. package/templates/api/src/boards/graphql/types/generator.py +0 -17
  174. package/templates/api/src/boards/graphql/types/user.py +0 -47
  175. package/templates/api/src/boards/jobs/repository.py +0 -153
  176. package/templates/api/src/boards/logging.py +0 -195
  177. package/templates/api/src/boards/middleware.py +0 -339
  178. package/templates/api/src/boards/progress/__init__.py +0 -4
  179. package/templates/api/src/boards/progress/models.py +0 -25
  180. package/templates/api/src/boards/progress/publisher.py +0 -64
  181. package/templates/api/src/boards/py.typed +0 -0
  182. package/templates/api/src/boards/redis_pool.py +0 -118
  183. package/templates/api/src/boards/storage/__init__.py +0 -52
  184. package/templates/api/src/boards/storage/base.py +0 -363
  185. package/templates/api/src/boards/storage/config.py +0 -187
  186. package/templates/api/src/boards/storage/factory.py +0 -288
  187. package/templates/api/src/boards/storage/implementations/__init__.py +0 -27
  188. package/templates/api/src/boards/storage/implementations/gcs.py +0 -340
  189. package/templates/api/src/boards/storage/implementations/local.py +0 -201
  190. package/templates/api/src/boards/storage/implementations/s3.py +0 -294
  191. package/templates/api/src/boards/storage/implementations/supabase.py +0 -218
  192. package/templates/api/src/boards/tenant_isolation.py +0 -446
  193. package/templates/api/src/boards/validation.py +0 -262
  194. package/templates/api/src/boards/workers/__init__.py +0 -1
  195. package/templates/api/src/boards/workers/actors.py +0 -274
  196. package/templates/api/src/boards/workers/cli.py +0 -125
  197. package/templates/api/src/boards/workers/context.py +0 -348
  198. package/templates/api/src/boards/workers/middleware.py +0 -58
  199. package/templates/api/src/py.typed +0 -0
  200. package/templates/compose.web.yaml +0 -35
  201. package/templates/compose.yaml +0 -116
  202. package/templates/docker/env.example +0 -23
  203. package/templates/web/.env.example +0 -28
  204. package/templates/web/Dockerfile +0 -51
  205. package/templates/web/components.json +0 -22
  206. package/templates/web/imageLoader.js +0 -18
  207. package/templates/web/next-env.d.ts +0 -5
  208. package/templates/web/next.config.js +0 -36
  209. package/templates/web/package.json +0 -41
  210. package/templates/web/postcss.config.mjs +0 -7
  211. package/templates/web/public/favicon.ico +0 -0
  212. package/templates/web/src/app/boards/[boardId]/page.tsx +0 -353
  213. package/templates/web/src/app/globals.css +0 -123
  214. package/templates/web/src/app/layout.tsx +0 -31
  215. package/templates/web/src/app/lineage/[generationId]/page.tsx +0 -235
  216. package/templates/web/src/app/page.tsx +0 -35
  217. package/templates/web/src/app/providers.tsx +0 -18
  218. package/templates/web/src/components/boards/ArtifactInputSlots.tsx +0 -206
  219. package/templates/web/src/components/boards/ArtifactPreview.tsx +0 -466
  220. package/templates/web/src/components/boards/GenerationGrid.tsx +0 -282
  221. package/templates/web/src/components/boards/GenerationInput.tsx +0 -370
  222. package/templates/web/src/components/boards/GeneratorSelector.tsx +0 -272
  223. package/templates/web/src/components/boards/UploadArtifact.tsx +0 -563
  224. package/templates/web/src/components/header.tsx +0 -32
  225. package/templates/web/src/components/theme-provider.tsx +0 -10
  226. package/templates/web/src/components/theme-toggle.tsx +0 -75
  227. package/templates/web/src/components/ui/alert-dialog.tsx +0 -157
  228. package/templates/web/src/components/ui/button.tsx +0 -58
  229. package/templates/web/src/components/ui/card.tsx +0 -92
  230. package/templates/web/src/components/ui/dropdown-menu.tsx +0 -200
  231. package/templates/web/src/components/ui/navigation-menu.tsx +0 -168
  232. package/templates/web/src/components/ui/toast.tsx +0 -128
  233. package/templates/web/src/components/ui/toaster.tsx +0 -35
  234. package/templates/web/src/components/ui/use-toast.ts +0 -187
  235. package/templates/web/src/hooks/useGeneratorMRU.ts +0 -57
  236. package/templates/web/src/lib/utils.ts +0 -6
  237. package/templates/web/tsconfig.json +0 -41
@@ -1,348 +0,0 @@
1
- """Execution context passed to generators for storage/DB/progress access."""
2
-
3
- from __future__ import annotations
4
-
5
- from uuid import UUID, uuid4
6
-
7
- from ..database.connection import get_async_session
8
- from ..generators import resolution
9
- from ..generators.artifacts import (
10
- AudioArtifact,
11
- ImageArtifact,
12
- TextArtifact,
13
- VideoArtifact,
14
- )
15
- from ..jobs import repository as jobs_repo
16
- from ..logging import get_logger
17
- from ..progress.models import ProgressUpdate
18
- from ..progress.publisher import ProgressPublisher
19
- from ..storage.base import StorageManager
20
-
21
- logger = get_logger(__name__)
22
-
23
-
24
- class GeneratorExecutionContext:
25
- def __init__(
26
- self,
27
- generation_id: UUID,
28
- publisher: ProgressPublisher,
29
- storage_manager: StorageManager,
30
- tenant_id: UUID,
31
- board_id: UUID,
32
- user_id: UUID,
33
- generator_name: str,
34
- artifact_type: str,
35
- input_params: dict,
36
- ) -> None:
37
- self.generation_id = str(generation_id)
38
- self.publisher = publisher
39
- self.storage_manager = storage_manager
40
- self.tenant_id = str(tenant_id)
41
- self.board_id = str(board_id)
42
- self.user_id = str(user_id)
43
- self.generator_name = generator_name
44
- self.artifact_type = artifact_type
45
- self.input_params = input_params
46
- self._batch_id: str | None = None
47
- self._batch_generations: list[str] = []
48
- logger.info(
49
- "Created execution context",
50
- generation_id=str(generation_id),
51
- tenant_id=str(tenant_id),
52
- board_id=str(board_id),
53
- )
54
-
55
- async def resolve_artifact(self, artifact) -> str:
56
- """Resolve an artifact to a file path."""
57
- logger.debug("Resolving artifact", generation_id=self.generation_id)
58
- try:
59
- result = await resolution.resolve_artifact(artifact)
60
- logger.debug("Artifact resolved successfully", result=result)
61
- return result
62
- except Exception as e:
63
- logger.error("Failed to resolve artifact", error=str(e))
64
- raise
65
-
66
- async def store_image_result(
67
- self,
68
- storage_url: str,
69
- format: str,
70
- width: int | None = None,
71
- height: int | None = None,
72
- output_index: int = 0,
73
- ) -> ImageArtifact:
74
- """Store image generation result.
75
-
76
- Args:
77
- storage_url: URL to download the image from
78
- format: Image format (png, jpg, etc.)
79
- width: Image width in pixels (optional)
80
- height: Image height in pixels (optional)
81
- output_index: Index of this output in a batch (0 for primary, 1+ for additional)
82
-
83
- Returns:
84
- ImageArtifact with the generation_id set appropriately
85
- """
86
- logger.debug(
87
- "Storing image result",
88
- generation_id=self.generation_id,
89
- output_index=output_index,
90
- )
91
- try:
92
- # Determine which generation_id to use
93
- target_generation_id = await self._get_or_create_generation_for_output(output_index)
94
-
95
- result = await resolution.store_image_result(
96
- storage_manager=self.storage_manager,
97
- generation_id=target_generation_id,
98
- tenant_id=self.tenant_id,
99
- board_id=self.board_id,
100
- storage_url=storage_url,
101
- format=format,
102
- width=width,
103
- height=height,
104
- )
105
- logger.info(
106
- "Image result stored",
107
- generation_id=target_generation_id,
108
- output_index=output_index,
109
- )
110
- return result
111
- except Exception as e:
112
- logger.error("Failed to store image result", error=str(e))
113
- raise
114
-
115
- async def store_video_result(
116
- self,
117
- storage_url: str,
118
- format: str,
119
- width: int | None = None,
120
- height: int | None = None,
121
- duration: float | None = None,
122
- fps: float | None = None,
123
- output_index: int = 0,
124
- ) -> VideoArtifact:
125
- """Store video generation result.
126
-
127
- Args:
128
- storage_url: URL to download the video from
129
- format: Video format (mp4, webm, etc.)
130
- width: Video width in pixels (optional)
131
- height: Video height in pixels (optional)
132
- duration: Video duration in seconds (optional)
133
- fps: Frames per second (optional)
134
- output_index: Index of this output in a batch (0 for primary, 1+ for additional)
135
-
136
- Returns:
137
- VideoArtifact with the generation_id set appropriately
138
- """
139
- logger.debug(
140
- "Storing video result",
141
- generation_id=self.generation_id,
142
- output_index=output_index,
143
- )
144
- try:
145
- # Determine which generation_id to use
146
- target_generation_id = await self._get_or_create_generation_for_output(output_index)
147
-
148
- result = await resolution.store_video_result(
149
- storage_manager=self.storage_manager,
150
- generation_id=target_generation_id,
151
- tenant_id=self.tenant_id,
152
- board_id=self.board_id,
153
- storage_url=storage_url,
154
- format=format,
155
- width=width,
156
- height=height,
157
- duration=duration,
158
- fps=fps,
159
- )
160
- logger.info(
161
- "Video result stored",
162
- generation_id=target_generation_id,
163
- output_index=output_index,
164
- )
165
- return result
166
- except Exception as e:
167
- logger.error("Failed to store video result", error=str(e))
168
- raise
169
-
170
- async def store_audio_result(
171
- self,
172
- storage_url: str,
173
- format: str,
174
- duration: float | None = None,
175
- sample_rate: int | None = None,
176
- channels: int | None = None,
177
- output_index: int = 0,
178
- ) -> AudioArtifact:
179
- """Store audio generation result.
180
-
181
- Args:
182
- storage_url: URL to download the audio from
183
- format: Audio format (mp3, wav, etc.)
184
- duration: Audio duration in seconds (optional)
185
- sample_rate: Sample rate in Hz (optional)
186
- channels: Number of audio channels (optional)
187
- output_index: Index of this output in a batch (0 for primary, 1+ for additional)
188
-
189
- Returns:
190
- AudioArtifact with the generation_id set appropriately
191
- """
192
- logger.debug(
193
- "Storing audio result",
194
- generation_id=self.generation_id,
195
- output_index=output_index,
196
- )
197
- try:
198
- # Determine which generation_id to use
199
- target_generation_id = await self._get_or_create_generation_for_output(output_index)
200
-
201
- result = await resolution.store_audio_result(
202
- storage_manager=self.storage_manager,
203
- generation_id=target_generation_id,
204
- tenant_id=self.tenant_id,
205
- board_id=self.board_id,
206
- storage_url=storage_url,
207
- format=format,
208
- duration=duration,
209
- sample_rate=sample_rate,
210
- channels=channels,
211
- )
212
- logger.info(
213
- "Audio result stored",
214
- generation_id=target_generation_id,
215
- output_index=output_index,
216
- )
217
- return result
218
- except Exception as e:
219
- logger.error("Failed to store audio result", error=str(e))
220
- raise
221
-
222
- async def store_text_result(
223
- self,
224
- content: str,
225
- format: str,
226
- output_index: int = 0,
227
- ) -> TextArtifact:
228
- """Store text generation result.
229
-
230
- Args:
231
- content: Text content to store
232
- format: Text format (plain, markdown, html, etc.)
233
- output_index: Index of this output in a batch (0 for primary, 1+ for additional)
234
-
235
- Returns:
236
- TextArtifact with the generation_id set appropriately
237
- """
238
- logger.debug(
239
- "Storing text result",
240
- generation_id=self.generation_id,
241
- output_index=output_index,
242
- )
243
- try:
244
- # Determine which generation_id to use
245
- target_generation_id = await self._get_or_create_generation_for_output(output_index)
246
-
247
- result = await resolution.store_text_result(
248
- storage_manager=self.storage_manager,
249
- generation_id=target_generation_id,
250
- tenant_id=self.tenant_id,
251
- board_id=self.board_id,
252
- content=content,
253
- format=format,
254
- )
255
- logger.info(
256
- "Text result stored",
257
- generation_id=target_generation_id,
258
- output_index=output_index,
259
- )
260
- return result
261
- except Exception as e:
262
- logger.error("Failed to store text result", error=str(e))
263
- raise
264
-
265
- async def publish_progress(self, update: ProgressUpdate) -> None:
266
- """Publish progress update for the generation."""
267
- logger.debug(
268
- "Publishing progress",
269
- generation_id=self.generation_id,
270
- status=update.status,
271
- progress=update.progress,
272
- )
273
- try:
274
- await self.publisher.publish_progress(self.generation_id, update)
275
- except Exception as e:
276
- logger.error(
277
- "Failed to publish progress update - "
278
- "generation will continue but progress may not be visible",
279
- generation_id=self.generation_id,
280
- status=update.status,
281
- progress=update.progress,
282
- error=str(e),
283
- error_type=type(e).__name__,
284
- )
285
- # Don't raise here - progress updates are non-critical
286
- # The generation should continue even if progress updates fail
287
-
288
- async def set_external_job_id(self, external_id: str) -> None:
289
- """Set the external job ID from the provider."""
290
- logger.info(
291
- "Setting external job ID",
292
- external_job_id=external_id,
293
- generation_id=self.generation_id,
294
- )
295
- async with get_async_session() as session:
296
- await jobs_repo.set_external_job_id(session, self.generation_id, external_id)
297
-
298
- async def _get_or_create_generation_for_output(self, output_index: int) -> str:
299
- """Get or create a generation record for the given output index.
300
-
301
- Args:
302
- output_index: Index of the output (0 for primary, 1+ for batch outputs)
303
-
304
- Returns:
305
- generation_id to use for storing this output
306
- """
307
- # Index 0 is always the primary generation
308
- if output_index == 0:
309
- return self.generation_id
310
-
311
- # For batch outputs, ensure we have a batch_id
312
- if self._batch_id is None:
313
- self._batch_id = str(uuid4())
314
- logger.debug(
315
- "Created batch_id for multi-output generation",
316
- batch_id=self._batch_id,
317
- primary_generation_id=self.generation_id,
318
- )
319
-
320
- # Check if we've already created a generation for this index
321
- batch_index = output_index - 1 # Adjust since index 0 is primary
322
- if batch_index < len(self._batch_generations):
323
- return self._batch_generations[batch_index]
324
-
325
- # Create new batch generation record
326
- async with get_async_session() as session:
327
- batch_gen_id = await jobs_repo.create_batch_generation(
328
- session,
329
- tenant_id=UUID(self.tenant_id),
330
- board_id=UUID(self.board_id),
331
- user_id=UUID(self.user_id),
332
- generator_name=self.generator_name,
333
- artifact_type=self.artifact_type,
334
- input_params=self.input_params,
335
- batch_id=self._batch_id,
336
- batch_index=output_index,
337
- )
338
- await session.commit()
339
-
340
- self._batch_generations.append(batch_gen_id)
341
- logger.info(
342
- "Created batch generation record",
343
- batch_generation_id=batch_gen_id,
344
- primary_generation_id=self.generation_id,
345
- batch_id=self._batch_id,
346
- batch_index=output_index,
347
- )
348
- return batch_gen_id
@@ -1,58 +0,0 @@
1
- """Dramatiq middleware for worker process initialization.
2
-
3
- This module provides custom middleware for managing worker lifecycle,
4
- particularly for loading generators during worker startup.
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- from typing import TYPE_CHECKING
10
-
11
- from dramatiq.middleware import Middleware
12
-
13
- from ..config import initialize_generator_api_keys
14
- from ..generators.loader import load_generators_from_config
15
- from ..generators.registry import registry as generator_registry
16
- from ..logging import get_logger
17
-
18
- if TYPE_CHECKING:
19
- from dramatiq import Broker, Worker
20
-
21
- logger = get_logger(__name__)
22
-
23
-
24
- class GeneratorLoaderMiddleware(Middleware):
25
- """Middleware to load generators when worker process starts.
26
-
27
- This ensures that generators are registered in each worker process's
28
- registry before any jobs are processed. Since Dramatiq uses multiprocessing,
29
- each worker process gets its own copy of the registry, so initialization
30
- must happen in each process.
31
-
32
- The before_worker_boot hook runs once per worker process at startup,
33
- before any actors are executed. Worker processes are long-running and
34
- reused across many jobs, so this initialization overhead happens only
35
- once per worker lifetime.
36
- """
37
-
38
- def before_worker_boot(self, broker: Broker, worker: Worker) -> None:
39
- """Load generators when worker process starts.
40
-
41
- Args:
42
- broker: The Dramatiq broker instance
43
- worker: The worker process instance
44
- """
45
- logger.info("Loading generators in worker process", worker_id=id(worker))
46
-
47
- # Initialize generator API keys before loading generators
48
- initialize_generator_api_keys()
49
- logger.info("Generator API keys initialized in worker process")
50
-
51
- load_generators_from_config()
52
-
53
- logger.info(
54
- "Generators loaded in worker process",
55
- worker_id=id(worker),
56
- generator_count=len(generator_registry.list_names()),
57
- generators=generator_registry.list_names(),
58
- )
File without changes
@@ -1,35 +0,0 @@
1
- # Docker Compose Overlay - Web Service
2
- #
3
- # This overlay adds the web (frontend) service as a production-built container.
4
- # Use this overlay when you want to run the full stack including the frontend.
5
- #
6
- # Usage:
7
- # docker compose -f compose.yaml up -d # Backend only (no web)
8
- # docker compose -f compose.yaml -f compose.web.yaml up -d # Full stack with web
9
- #
10
- # The web service runs a production build (no hot-reload, no volume mounts).
11
- # For app development mode where you run the frontend locally, skip this overlay.
12
-
13
- services:
14
- web:
15
- build:
16
- context: ./web
17
- dockerfile: ../Dockerfile.web
18
- args:
19
- NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:8800}
20
- NEXT_PUBLIC_GRAPHQL_URL: ${NEXT_PUBLIC_GRAPHQL_URL:-http://localhost:8800/graphql}
21
- env_file: web/.env
22
- environment:
23
- - INTERNAL_API_URL=http://api:8800
24
- depends_on:
25
- api:
26
- condition: service_healthy
27
- ports:
28
- - "${WEB_PORT:-3300}:3000"
29
- healthcheck:
30
- test: ["CMD", "curl", "-f", "http://localhost:3000/"]
31
- interval: 5s
32
- timeout: 3s
33
- retries: 50
34
- networks:
35
- - internal
@@ -1,116 +0,0 @@
1
- # Docker Compose Configuration for Baseboards
2
- name: ${PROJECT_NAME:-baseboards}
3
-
4
- services:
5
- db:
6
- image: postgres:16
7
- env_file: docker/.env
8
- volumes:
9
- - db-data:/var/lib/postgresql/data
10
- healthcheck:
11
- test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
12
- interval: 5s
13
- timeout: 5s
14
- retries: 20
15
- networks:
16
- - internal
17
-
18
- cache:
19
- image: redis:7
20
- command: ["redis-server", "--appendonly", "yes"]
21
- healthcheck:
22
- test: ["CMD", "redis-cli", "ping"]
23
- interval: 5s
24
- timeout: 3s
25
- retries: 20
26
- networks:
27
- - internal
28
-
29
- api:
30
- # Pre-built backend image from GitHub Container Registry
31
- # Override version with BACKEND_VERSION in docker/.env (defaults to latest)
32
- image: ghcr.io/weirdfingers/boards-backend:${BACKEND_VERSION:-latest}
33
- command: ["uvicorn", "boards.api.app:app", "--host", "0.0.0.0", "--port", "8800"]
34
- env_file:
35
- - docker/.env
36
- - api/.env
37
- environment:
38
- # Enable loading custom generators and plugins from /app/extensions
39
- # Include /app/src for the boards module (from Docker image)
40
- - PYTHONPATH=/app/src:/app/extensions
41
- # Explicit paths to configuration files
42
- - BOARDS_GENERATORS_CONFIG_PATH=/app/config/generators.yaml
43
- - BOARDS_STORAGE_CONFIG_PATH=/app/config/storage_config.yaml
44
- # Ensure logs are visible in real-time (no buffering)
45
- - PYTHONUNBUFFERED=1
46
- volumes:
47
- # Configuration files (read-only)
48
- - ./config:/app/config:ro
49
- # Generated media persistence (read-write)
50
- - ./data/storage:/app/data/storage
51
- # Custom generators and plugins (read-only)
52
- - ./extensions:/app/extensions:ro
53
- depends_on:
54
- db:
55
- condition: service_healthy
56
- cache:
57
- condition: service_healthy
58
- ports:
59
- - "${API_PORT:-8800}:8800"
60
- healthcheck:
61
- test: ["CMD", "curl", "-f", "http://localhost:8800/health"]
62
- interval: 30s
63
- timeout: 3s
64
- retries: 50
65
- networks:
66
- - internal
67
-
68
- worker:
69
- # Pre-built backend image from GitHub Container Registry
70
- # Override version with BACKEND_VERSION in docker/.env (defaults to latest)
71
- image: ghcr.io/weirdfingers/boards-backend:${BACKEND_VERSION:-latest}
72
- command:
73
- [
74
- "boards-worker",
75
- "--log-level",
76
- "debug",
77
- "--processes",
78
- "1",
79
- "--threads",
80
- "1",
81
- ]
82
- env_file:
83
- - docker/.env
84
- - api/.env
85
- environment:
86
- # Enable loading custom generators and plugins from /app/extensions
87
- # Include /app/src for the boards module (from Docker image)
88
- - PYTHONPATH=/app/src:/app/extensions
89
- # Explicit paths to configuration files
90
- - BOARDS_GENERATORS_CONFIG_PATH=/app/config/generators.yaml
91
- - BOARDS_STORAGE_CONFIG_PATH=/app/config/storage_config.yaml
92
- # Internal API URL for worker communication
93
- - BOARDS_INTERNAL_API_URL=http://api:8800
94
- # Ensure logs are visible in real-time (no buffering)
95
- - PYTHONUNBUFFERED=1
96
- volumes:
97
- # Configuration files (read-only)
98
- - ./config:/app/config:ro
99
- # Generated media persistence (read-write)
100
- - ./data/storage:/app/data/storage
101
- # Custom generators and plugins (read-only)
102
- - ./extensions:/app/extensions:ro
103
- depends_on:
104
- db:
105
- condition: service_healthy
106
- cache:
107
- condition: service_healthy
108
- networks:
109
- - internal
110
-
111
- networks:
112
- internal:
113
- driver: bridge
114
-
115
- volumes:
116
- db-data:
@@ -1,23 +0,0 @@
1
- # Docker Compose Environment Variables
2
- # Generated by CLI - DO NOT EDIT MANUALLY
3
-
4
- # Project configuration
5
- PROJECT_NAME=baseboards
6
-
7
- # Service ports
8
- WEB_PORT=3300
9
- API_PORT=8800
10
-
11
- # PostgreSQL configuration
12
- POSTGRES_USER=baseboards
13
- POSTGRES_PASSWORD=REPLACE_WITH_GENERATED_PASSWORD
14
- POSTGRES_DB=baseboards
15
-
16
- # Database URL (for API container)
17
- BOARDS_DATABASE_URL=postgresql://baseboards:REPLACE_WITH_GENERATED_PASSWORD@db:5432/baseboards
18
-
19
- # Redis URL (for API container)
20
- BOARDS_REDIS_URL=redis://cache:6379/0
21
-
22
- # Image version (matches CLI version)
23
- VERSION=latest
@@ -1,28 +0,0 @@
1
- # Frontend Environment Variables
2
-
3
- # API Configuration
4
- NEXT_PUBLIC_API_URL=http://localhost:8800
5
- NEXT_PUBLIC_GRAPHQL_URL=http://localhost:8800/graphql
6
-
7
- # Internal API URL for Docker
8
- # When running in Docker, this URL is used for server-side requests (like image optimization)
9
- # to access the API via the internal Docker network instead of localhost
10
- INTERNAL_API_URL=http://api:8800
11
-
12
- # Auth Provider
13
- # For local development, 'none' allows unauthenticated access
14
- NEXT_PUBLIC_AUTH_PROVIDER=none
15
-
16
- # Clerk
17
- # NEXT_PUBLIC_AUTH_PROVIDER=clerk
18
- # NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
19
-
20
- # Supabase
21
- # NEXT_PUBLIC_AUTH_PROVIDER=supabase
22
- # NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
23
- # NEXT_PUBLIC_SUPABASE_ANON_KEY=...
24
-
25
- # Auth0
26
- # NEXT_PUBLIC_AUTH_PROVIDER=auth0
27
- # NEXT_PUBLIC_AUTH0_DOMAIN=...
28
- # NEXT_PUBLIC_AUTH0_CLIENT_ID=...
@@ -1,51 +0,0 @@
1
- FROM node:20-alpine AS base
2
-
3
- # Install dependencies only when needed
4
- FROM base AS deps
5
- RUN apk add --no-cache libc6-compat
6
- WORKDIR /app
7
-
8
- # Copy package files
9
- COPY package.json package-lock.json* pnpm-lock.yaml* ./
10
- RUN corepack enable pnpm && pnpm install
11
-
12
- # Rebuild the source code only when needed
13
- FROM base AS builder
14
- WORKDIR /app
15
- COPY --from=deps /app/node_modules ./node_modules
16
- COPY . .
17
-
18
- # Accept build args for Next.js public env vars
19
- ARG NEXT_PUBLIC_API_URL
20
- ARG NEXT_PUBLIC_GRAPHQL_URL
21
- ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
22
- ENV NEXT_PUBLIC_GRAPHQL_URL=${NEXT_PUBLIC_GRAPHQL_URL}
23
-
24
- RUN corepack enable pnpm && pnpm run build
25
-
26
- # Production image, copy all the files and run next
27
- FROM base AS runner
28
- WORKDIR /app
29
-
30
- ENV NODE_ENV=production
31
-
32
- RUN addgroup --system --gid 1001 nodejs
33
- RUN adduser --system --uid 1001 nextjs
34
-
35
- # Enable pnpm for dev mode (must be done as root before USER switch)
36
- RUN corepack enable pnpm
37
-
38
- # Automatically leverage output traces to reduce image size
39
- # https://nextjs.org/docs/advanced-features/output-file-tracing
40
- COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
41
- COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
42
- COPY --from=builder --chown=nextjs:nodejs /app/public ./public
43
-
44
- USER nextjs
45
-
46
- EXPOSE 3000
47
-
48
- ENV PORT=3000
49
- ENV HOSTNAME="0.0.0.0"
50
-
51
- CMD ["node", "server.js"]
@@ -1,22 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "src/app/globals.css",
9
- "baseColor": "neutral",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "iconLibrary": "lucide",
14
- "aliases": {
15
- "components": "@/components",
16
- "utils": "@/lib/utils",
17
- "ui": "@/components/ui",
18
- "lib": "@/lib",
19
- "hooks": "@/hooks"
20
- },
21
- "registries": {}
22
- }