@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.
Files changed (237) hide show
  1. package/dist/index.js +560 -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,253 +0,0 @@
1
- """Configuration-driven generator loader.
2
-
3
- Loads and registers generators based on configuration file.
4
- File path is specified via settings.generators_config_path.
5
-
6
- Supports three declaration forms: import, class, entrypoint.
7
- Strict mode is enabled by default and will fail startup on errors.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- from collections.abc import Iterable
13
- from dataclasses import dataclass
14
- from importlib import import_module
15
- from importlib import metadata as importlib_metadata
16
- from pathlib import Path
17
- from typing import Any
18
-
19
- import yaml
20
-
21
- from boards.config import settings
22
- from boards.logging import get_logger
23
-
24
- from .base import BaseGenerator
25
- from .registry import registry
26
-
27
- logger = get_logger(__name__)
28
-
29
-
30
- ENTRYPOINT_GROUP = "boards.generators"
31
-
32
- VALID_ARTIFACT_TYPES: set[str] = {"image", "video", "audio", "text", "lora"}
33
-
34
-
35
- @dataclass
36
- class LoaderConfig:
37
- strict_mode: bool = True
38
- allow_unlisted: bool = False
39
- declarations: list[dict[str, Any]] | None = None
40
-
41
-
42
- def _load_file_config(path: str) -> LoaderConfig | None:
43
- try:
44
- with open(path, encoding="utf-8") as f:
45
- data: dict[str, Any] = yaml.safe_load(f) or {}
46
- except FileNotFoundError:
47
- return None
48
-
49
- strict_mode = bool(data.get("strict_mode", True))
50
- allow_unlisted = bool(data.get("allow_unlisted", False))
51
- declarations = list(data.get("generators", []) or [])
52
-
53
- return LoaderConfig(
54
- strict_mode=strict_mode,
55
- allow_unlisted=allow_unlisted,
56
- declarations=declarations,
57
- )
58
-
59
-
60
- def _discover_config() -> LoaderConfig | None:
61
- """Discover config from settings.generators_config_path."""
62
- if not settings.generators_config_path:
63
- return None
64
-
65
- path = Path(settings.generators_config_path)
66
- if not path.exists():
67
- logger.warning("Generators config path set but not found", path=str(path))
68
- return None
69
-
70
- cfg = _load_file_config(str(path))
71
- if cfg:
72
- logger.info("Loaded generators config from settings", path=str(path))
73
- return cfg
74
-
75
-
76
- def _resolve_class(qualified_name: str) -> type[BaseGenerator]:
77
- if ":" in qualified_name:
78
- module_name, class_name = qualified_name.split(":", 1)
79
- else:
80
- # Split on last dot for module path
81
- module_name, class_name = qualified_name.rsplit(".", 1)
82
-
83
- module = import_module(module_name)
84
- cls = getattr(module, class_name)
85
- if not isinstance(cls, type) or not issubclass(cls, BaseGenerator):
86
- raise TypeError(f"Resolved object is not a BaseGenerator subclass: {qualified_name}")
87
- return cls
88
-
89
-
90
- def _resolve_entrypoint(name: str) -> type[BaseGenerator]:
91
- try:
92
- eps = importlib_metadata.entry_points()
93
- # Python 3.12 returns a Selection object with .select
94
- group_filtered: Iterable[Any]
95
- if hasattr(eps, "select"):
96
- group_filtered = eps.select(group=ENTRYPOINT_GROUP)
97
- else:
98
- group_filtered = eps.get(ENTRYPOINT_GROUP, []) # type: ignore[attr-defined]
99
- except Exception as e: # pragma: no cover - edge cases
100
- raise RuntimeError(f"Failed to read entry points: {e}") from e
101
-
102
- for ep in group_filtered:
103
- if getattr(ep, "name", None) == name:
104
- obj = ep.load()
105
- if not isinstance(obj, type) or not issubclass(obj, BaseGenerator):
106
- raise TypeError(f"Entry point '{name}' is not a BaseGenerator class")
107
- return obj
108
-
109
- raise LookupError(f"Entry point not found: {name}")
110
-
111
-
112
- def _validate_artifact_type(instance: BaseGenerator) -> None:
113
- artifact_type = getattr(instance, "artifact_type", None)
114
- if not artifact_type or artifact_type not in VALID_ARTIFACT_TYPES:
115
- raise ValueError(f"Invalid artifact_type: {artifact_type}")
116
-
117
-
118
- def _register_instance(instance: BaseGenerator, name_override: str | None) -> None:
119
- if name_override:
120
- # Override instance name if provided
121
- try:
122
- instance.name = name_override
123
- except Exception as e:
124
- raise ValueError(f"Failed to set generator name override: {e}") from e
125
-
126
- _validate_artifact_type(instance)
127
- registry.register(instance)
128
-
129
-
130
- def _enforce_unlisted_policy(
131
- allowed_names: set[str], strict_mode: bool, allow_unlisted: bool
132
- ) -> None:
133
- registered = set(registry.list_names())
134
- extras = registered - allowed_names
135
- if not extras:
136
- return
137
-
138
- msg = f"Found unlisted generator registrations: {sorted(extras)}"
139
- if allow_unlisted:
140
- logger.warning(msg)
141
- return
142
-
143
- # Not allowed. Attempt to unregister extras then decide based on strict_mode.
144
- for name in extras:
145
- try:
146
- registry.unregister(name)
147
- except Exception: # pragma: no cover - defensive
148
- pass
149
-
150
- if strict_mode:
151
- raise RuntimeError(msg)
152
- else:
153
- logger.error(msg)
154
-
155
-
156
- def load_generators_from_config(config_path: str | None = None) -> None:
157
- """Load and register generators according to configuration.
158
-
159
- Raises on errors when strict mode is enabled (default).
160
- """
161
-
162
- # Discover configuration
163
- cfg: LoaderConfig | None
164
- if config_path:
165
- cfg = _load_file_config(config_path)
166
- if cfg:
167
- logger.info("Loaded generators config from explicit path", path=config_path)
168
- else:
169
- cfg = _discover_config()
170
-
171
- # If nothing configured, do nothing (no implicit imports)
172
- if not cfg or not cfg.declarations:
173
- logger.info("No generators configuration found; skipping generator loading")
174
- return
175
-
176
- strict_mode = cfg.strict_mode
177
- allow_unlisted = cfg.allow_unlisted
178
-
179
- requested_names: set[str] = set()
180
-
181
- # Process declarations in order
182
- for decl in cfg.declarations:
183
- if not isinstance(decl, dict):
184
- msg = f"Invalid generator declaration type: {type(decl)}"
185
- if strict_mode:
186
- raise ValueError(msg)
187
- logger.error(msg)
188
- continue
189
-
190
- if decl.get("enabled") is False:
191
- continue
192
-
193
- name_override = decl.get("name")
194
-
195
- try:
196
- if "import" in decl:
197
- import_path = decl["import"]
198
- import_module(import_path)
199
- # Back-compat path relies on module side-effect registration.
200
- # We cannot infer the name here reliably; collect after loop.
201
- logger.info("Imported generator module", import_path=import_path)
202
- elif "class" in decl:
203
- qualified = decl["class"]
204
- options = decl.get("options", {}) or {}
205
- cls = _resolve_class(qualified)
206
- instance = cls(**options) if options else cls()
207
- _register_instance(instance, name_override)
208
- requested_names.add(instance.name)
209
- logger.info(
210
- "Registered generator via class",
211
- class_path=qualified,
212
- name=instance.name,
213
- )
214
- elif "entrypoint" in decl:
215
- ep_name = decl["entrypoint"]
216
- options = decl.get("options", {}) or {}
217
- cls = _resolve_entrypoint(ep_name)
218
- instance = cls(**options) if options else cls()
219
- _register_instance(instance, name_override)
220
- requested_names.add(instance.name)
221
- logger.info(
222
- "Registered generator via entrypoint",
223
- entrypoint=ep_name,
224
- name=instance.name,
225
- )
226
- else:
227
- raise ValueError(
228
- "Generator declaration must include one of: import, class, entrypoint"
229
- )
230
-
231
- except Exception as e:
232
- msg = f"Failed to load generator declaration: {e}"
233
- if strict_mode:
234
- raise RuntimeError(msg) from e
235
- logger.error(msg)
236
- continue
237
-
238
- # After imports, collect names to enforce allow_unlisted policy
239
- # requested_names may be incomplete for `import` declarations; fill with registry state
240
- for name in registry.list_names():
241
- requested_names.add(name)
242
-
243
- _enforce_unlisted_policy(requested_names, strict_mode, allow_unlisted)
244
-
245
- # Final summary
246
- logger.info(
247
- "Generators loading complete",
248
- requested=len(cfg.declarations or []),
249
- registered=len(registry),
250
- names=registry.list_names(),
251
- strict_mode=strict_mode,
252
- allow_unlisted=allow_unlisted,
253
- )
@@ -1,114 +0,0 @@
1
- """
2
- Generator registry system for discovering and managing generators.
3
- """
4
-
5
- from boards.logging import get_logger
6
-
7
- from .base import BaseGenerator
8
-
9
- logger = get_logger(__name__)
10
-
11
-
12
- class GeneratorRegistry:
13
- """
14
- Central registry for generator discovery and management.
15
-
16
- Provides methods to register generators, look them up by name,
17
- and list available generators by various criteria.
18
- """
19
-
20
- def __init__(self):
21
- self._generators: dict[str, BaseGenerator] = {}
22
-
23
- def register(self, generator: BaseGenerator) -> None:
24
- """
25
- Register a generator instance with the registry.
26
-
27
- Args:
28
- generator: Generator instance to register
29
-
30
- Raises:
31
- ValueError: If a generator with the same name is already registered
32
- """
33
- logger.info("Registering generator", name=generator.name)
34
- if generator.name in self._generators:
35
- raise ValueError(f"Generator '{generator.name}' is already registered")
36
-
37
- self._generators[generator.name] = generator
38
-
39
- def get(self, name: str) -> BaseGenerator | None:
40
- """
41
- Get a generator by name.
42
-
43
- Args:
44
- name: Name of the generator to retrieve
45
-
46
- Returns:
47
- BaseGenerator instance or None if not found
48
- """
49
- return self._generators.get(name)
50
-
51
- def list_all(self) -> list[BaseGenerator]:
52
- """
53
- List all registered generators.
54
-
55
- Returns:
56
- List of all generator instances
57
- """
58
- return list(self._generators.values())
59
-
60
- def list_by_artifact_type(self, artifact_type: str) -> list[BaseGenerator]:
61
- """
62
- List generators that produce a specific artifact type.
63
-
64
- Args:
65
- artifact_type: Type of artifact (image, video, audio, text, lora)
66
-
67
- Returns:
68
- List of generators that produce the specified artifact type
69
- """
70
- return [
71
- generator
72
- for generator in self._generators.values()
73
- if generator.artifact_type == artifact_type
74
- ]
75
-
76
- def list_names(self) -> list[str]:
77
- """
78
- List all registered generator names.
79
-
80
- Returns:
81
- List of generator names
82
- """
83
- return list(self._generators.keys())
84
-
85
- def unregister(self, name: str) -> bool:
86
- """
87
- Unregister a generator by name.
88
-
89
- Args:
90
- name: Name of the generator to unregister
91
-
92
- Returns:
93
- True if the generator was found and removed, False otherwise
94
- """
95
- if name in self._generators:
96
- del self._generators[name]
97
- return True
98
- return False
99
-
100
- def clear(self) -> None:
101
- """Clear all registered generators."""
102
- self._generators.clear()
103
-
104
- def __len__(self) -> int:
105
- """Return the number of registered generators."""
106
- return len(self._generators)
107
-
108
- def __contains__(self, name: str) -> bool:
109
- """Check if a generator with the given name is registered."""
110
- return name in self._generators
111
-
112
-
113
- # Global registry instance
114
- registry = GeneratorRegistry()