@polymorphism-tech/morph-spec 7.9.4 → 8.0.0

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 (211) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.md +31 -2
  3. package/bin/morph-spec.js +50 -2
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +38 -1
  7. package/docs/QUICKSTART.md +60 -1
  8. package/framework/CLAUDE.md +13 -2
  9. package/framework/MORPH.md +38 -2
  10. package/framework/agents.json +22 -3
  11. package/framework/commands/commit.md +166 -166
  12. package/framework/commands/morph-hotfix.md +39 -0
  13. package/framework/commands/morph-infra.md +215 -215
  14. package/framework/commands/morph-preflight.md +205 -205
  15. package/framework/commands/morph-troubleshoot.md +124 -124
  16. package/framework/hooks/README.md +25 -10
  17. package/framework/hooks/claude-code/core/gate-guard.js +4 -2
  18. package/framework/hooks/claude-code/core/loop-detect.js +2 -1
  19. package/framework/hooks/claude-code/core/post-edit-typecheck.js +14 -5
  20. package/framework/hooks/claude-code/core/tasks-json-guard.js +4 -2
  21. package/framework/hooks/claude-code/core/validate-completion.js +1 -1
  22. package/framework/hooks/claude-code/core/worktree-context.js +160 -0
  23. package/framework/hooks/claude-code/statusline.py +679 -679
  24. package/framework/hooks/claude-code/statusline.sh +11 -11
  25. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  26. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  27. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  28. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  29. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  30. package/framework/hooks/shared/activity-logger.js +160 -160
  31. package/framework/hooks/shared/build-check.js +2 -2
  32. package/framework/hooks/shared/hook-response.js +17 -5
  33. package/framework/hooks/shared/payload-utils.js +42 -0
  34. package/framework/hooks/shared/state-reader.js +22 -2
  35. package/framework/hooks/shared/stdin-reader.js +26 -26
  36. package/framework/rubrics/backend.json +41 -41
  37. package/framework/rules/ai-agents-standards.md +45 -45
  38. package/framework/rules/dotnet-templates.md +86 -86
  39. package/framework/rules/frontend-standards.md +13 -13
  40. package/framework/rules/infrastructure-standards.md +27 -27
  41. package/framework/rules/neon-standards.md +25 -25
  42. package/framework/rules/nextjs-standards.md +20 -20
  43. package/framework/rules/nextjs-templates.md +40 -40
  44. package/framework/schemas/feature.schema.json +95 -1
  45. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  46. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  47. package/framework/skills/core/morph-apply/SKILL.md +39 -8
  48. package/framework/skills/core/morph-brainstorming/SKILL.md +9 -1
  49. package/framework/skills/core/morph-eval/SKILL.md +6 -1
  50. package/framework/skills/core/morph-hotfix/SKILL.md +136 -0
  51. package/framework/skills/core/morph-implement/SKILL.md +8 -4
  52. package/framework/skills/core/morph-plan/SKILL.md +5 -1
  53. package/framework/skills/core/morph-proposal/SKILL.md +24 -1
  54. package/framework/skills/core/morph-review/SKILL.md +3 -2
  55. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  56. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  57. package/framework/standards/ai-agents/agent-session.md +160 -160
  58. package/framework/standards/ai-agents/batching.md +193 -193
  59. package/framework/standards/ai-agents/context-providers.md +188 -188
  60. package/framework/standards/ai-agents/mcp-server.md +250 -250
  61. package/framework/standards/ai-agents/mcp-tools.md +197 -197
  62. package/framework/standards/ai-agents/middleware-patterns.md +207 -207
  63. package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
  64. package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
  65. package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
  66. package/framework/standards/ai-agents/modalities-vision.md +201 -201
  67. package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
  68. package/framework/standards/ai-agents/production.md +275 -275
  69. package/framework/standards/ai-agents/prompts-in-db.md +214 -214
  70. package/framework/standards/ai-agents/providers/model-registry.md +158 -158
  71. package/framework/standards/ai-agents/service-tier-flex.md +135 -135
  72. package/framework/standards/ai-agents/structured-output.md +249 -249
  73. package/framework/standards/ai-agents/sweet-spot.md +109 -109
  74. package/framework/templates/.idea/morph-templates.xml +92 -0
  75. package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  76. package/framework/templates/IDE-SNIPPETS.md +262 -262
  77. package/framework/templates/REGISTRY.json +0 -62
  78. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  79. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  80. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  81. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  82. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  83. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  84. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  85. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  86. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  87. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  88. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  89. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  90. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  91. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  92. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  93. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  94. package/framework/templates/code/typescript/contracts.ts +167 -167
  95. package/framework/templates/docs/clarifications.md +253 -253
  96. package/framework/templates/docs/schema-analysis.md +119 -119
  97. package/framework/templates/docs/ui-components.md +52 -52
  98. package/framework/templates/docs/ui-design-system.md +76 -76
  99. package/framework/templates/docs/ui-flows.md +167 -167
  100. package/framework/templates/docs/ui-mockups.md +98 -98
  101. package/framework/templates/feature/decisions.md +122 -122
  102. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  103. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  104. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  105. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  106. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  107. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  108. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  109. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  110. package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
  111. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  112. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  113. package/framework/templates/infrastructure/github/README.md +56 -56
  114. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  115. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  116. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  117. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  118. package/framework/templates/integrations/asaas-client.cs +387 -387
  119. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  120. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  121. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  122. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  123. package/framework/templates/project/validate.js +120 -120
  124. package/framework/templates/state.template.json +17 -17
  125. package/framework/templates/ui/design-system.css +226 -226
  126. package/package.json +1 -1
  127. package/src/commands/dashboard/dashboard.js +53 -53
  128. package/src/commands/index.js +13 -13
  129. package/src/commands/mcp/mcp-setup.js +519 -519
  130. package/src/commands/project/checkpoint.js +209 -209
  131. package/src/commands/project/doctor.js +4 -2
  132. package/src/commands/project/init.js +46 -2
  133. package/src/commands/project/update.js +5 -3
  134. package/src/commands/project/worktree.js +1005 -46
  135. package/src/commands/state/advance.js +17 -2
  136. package/src/commands/state/approve.js +18 -1
  137. package/src/commands/state/create.js +158 -14
  138. package/src/commands/state/retype.js +126 -0
  139. package/src/commands/state/score.js +4 -0
  140. package/src/commands/tasks/dag.js +32 -0
  141. package/src/commands/validation/index.js +1 -0
  142. package/src/commands/validation/validate-feature.js +33 -5
  143. package/src/commands/validation/verify.js +190 -0
  144. package/src/core/state/phase-state-machine.js +197 -197
  145. package/src/core/state/state-manager.js +35 -10
  146. package/src/core/templates/template-renderer.js +477 -477
  147. package/src/core/work-types.js +79 -0
  148. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  149. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  150. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  151. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  152. package/src/dashboard/app/main.jsx +13 -13
  153. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  154. package/src/dashboard/app/pages/HookInspector.jsx +418 -418
  155. package/src/dashboard/app/pages/LiveState.jsx +11 -1
  156. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  157. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  158. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  159. package/src/dashboard/app/pages/Standards.jsx +332 -332
  160. package/src/dashboard/app/styles/index.css +47 -47
  161. package/src/dashboard/index.html +12 -12
  162. package/src/dashboard/package.json +24 -24
  163. package/src/dashboard/scanner/hooks-scanner.js +41 -41
  164. package/src/dashboard/scanner/phases-scanner.js +15 -15
  165. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  166. package/src/dashboard/scanner/rules-scanner.js +37 -37
  167. package/src/dashboard/scanner/skills-scanner.js +43 -43
  168. package/src/dashboard/scanner/squads-scanner.js +13 -13
  169. package/src/dashboard/scanner/standards-scanner.js +26 -26
  170. package/src/dashboard/scanner/state-scanner.js +42 -0
  171. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  172. package/src/dashboard/vite.config.js +24 -24
  173. package/src/lib/agents/metrics-aggregator.js +56 -56
  174. package/src/lib/agents/metrics-calculator.js +125 -125
  175. package/src/lib/agents/output-collector.js +73 -73
  176. package/src/lib/detectors/claude-config-detector.js +152 -152
  177. package/src/lib/detectors/design-system-detector.js +231 -231
  178. package/src/lib/detectors/index.js +217 -217
  179. package/src/lib/generators/architecture-scanner.js +639 -639
  180. package/src/lib/generators/design-system-generator.js +508 -508
  181. package/src/lib/generators/index.js +13 -13
  182. package/src/lib/generators/settings-generator.js +209 -209
  183. package/src/lib/hooks/hook-executor.js +167 -167
  184. package/src/lib/installers/mcp-installer.js +719 -719
  185. package/src/lib/installers/memory-installer.js +1 -1
  186. package/src/lib/risk-detector.js +16 -0
  187. package/src/lib/tasks/dispatch-planner.js +122 -4
  188. package/src/lib/tasks/mermaid-renderer.js +132 -0
  189. package/src/lib/tasks/task-classifier.js +30 -30
  190. package/src/lib/tasks/task-parser.js +209 -209
  191. package/src/lib/tasks/test-runner.js +27 -6
  192. package/src/lib/validators/architecture/architecture-validator.js +259 -259
  193. package/src/lib/validators/checkpoint-persistence.js +39 -39
  194. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
  195. package/src/lib/validators/css/css-validator.js +340 -340
  196. package/src/lib/validators/packages/package-validator.js +347 -347
  197. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  198. package/src/lib/validators/shared/issue-counter.js +14 -14
  199. package/src/lib/validators/validation-runner.js +349 -349
  200. package/src/lib/validators/verify-runner.js +322 -0
  201. package/src/lib/work-type-detector.js +143 -0
  202. package/src/scripts/setup-infra.js +32 -5
  203. package/src/utils/agent-id-mapper.js +11 -11
  204. package/src/utils/agents-installer.js +10 -6
  205. package/src/utils/claude-settings-manager.js +300 -300
  206. package/src/utils/file-copier.js +43 -0
  207. package/src/utils/hooks-installer.js +41 -11
  208. package/src/utils/skills-installer.js +174 -174
  209. package/framework/templates/meta-prompts/parallel-workers/parallel-coordinator.md +0 -113
  210. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +0 -80
  211. package/src/lib/tasks/wave-resolver.js +0 -353
@@ -1,173 +1,173 @@
1
- # Modalities — Image Generation (Text to Image)
2
-
3
- > **Scope:** stacks=["dotnet"]
4
- > **Layer:** 2 (on-keyword)
5
- > **Keywords:** image generation, text to image, dall-e, gpt-image, mockup generation, image synthesis
6
- > **Read by Claude in:** implement (quando o projeto precisa gerar imagens a partir de texto)
7
-
8
- **Verified against:** MAF 1.0 GA + OpenAI .NET SDK 2.x. Last-verified: 2026-05-19.
9
-
10
- ---
11
-
12
- ## Quando usar geração de imagem
13
-
14
- Use quando o produto precisa criar imagens em runtime a partir de um prompt textual:
15
-
16
- - **Mockups e protótipos visuais:** gerar capa de produto, banner de campanha, layout de tela
17
- - **Conteúdo para social media:** imagens para posts geradas a partir de briefing do usuário
18
- - **Visualizações:** diagramas, ilustrações ou thumbnails dinâmicos
19
-
20
- **Nota importante:** geração de imagem é uma **chamada de serviço ao provider**, não um agente conversacional. Não crie um `AIAgent` para isso — use `ImageClient` diretamente via DI.
21
-
22
- **Não use** quando um asset estático resolve o problema. Geração de imagem tem custo por chamada e latência de vários segundos. Se a imagem não muda por usuário/contexto, sirva de CDN.
23
-
24
- ---
25
-
26
- ## A API
27
-
28
- O projeto resolve o `ImageClient` para o provider configurado. No OpenAI SDK (.NET 2.x), o caminho é:
29
-
30
- ```csharp
31
- using OpenAI.Images;
32
-
33
- ImageClient client = new("dall-e-3", apiKey);
34
- GeneratedImage image = await client.GenerateImageAsync(prompt, options);
35
- ```
36
-
37
- O projeto injeta `ImageClient` via DI (ver §Exemplo). A resolução pode ser feita via factory ou diretamente por configuração — não há um `GetImageClient("alias")` no `ModelRegistry` padrão; registre o `ImageClient` como serviço nomeado ou use uma factory simples que lê `model-registry.json`.
38
-
39
- ---
40
-
41
- ## Exemplo C# completo
42
-
43
- ```csharp
44
- using OpenAI.Images;
45
- using Microsoft.Extensions.Configuration;
46
-
47
- public sealed class ImageGenerationService
48
- {
49
- private readonly ImageClient _client;
50
-
51
- public ImageGenerationService(IConfiguration config)
52
- {
53
- // O projeto configura o modelo e a chave via config/model-registry.json ou appsettings
54
- var model = config["ImageGen:Model"] ?? "dall-e-3";
55
- var apiKey = config["OpenAI:ApiKey"]!;
56
- _client = new ImageClient(model, apiKey);
57
- }
58
-
59
- /// <summary>
60
- /// Gera uma imagem a partir de um prompt e retorna os bytes PNG.
61
- /// Prefira armazenar os bytes; URLs retornadas pelo provider são efêmeras (expiram em ~1h).
62
- /// </summary>
63
- public async Task<BinaryData> GenerateImageBytesAsync(
64
- string prompt,
65
- GeneratedImageSize? size = null,
66
- GeneratedImageQuality? quality = null,
67
- CancellationToken ct = default)
68
- {
69
- var resolvedSize = size ?? GeneratedImageSize.W1024xH1024;
70
- var resolvedQuality = quality ?? GeneratedImageQuality.Standard;
71
-
72
- var options = new ImageGenerationOptions
73
- {
74
- Size = resolvedSize,
75
- Quality = resolvedQuality,
76
- ResponseFormat = GeneratedImageFormat.Bytes
77
- };
78
-
79
- GeneratedImage image = await _client.GenerateImageAsync(prompt, options, ct);
80
- return image.ImageBytes;
81
- }
82
-
83
- /// <summary>
84
- /// Gera uma imagem e retorna a URI. Use apenas quando precisar da URL diretamente
85
- /// e souber que o downstream vai consumir a URL antes de ela expirar (~1h no OpenAI).
86
- /// </summary>
87
- public async Task<Uri> GenerateImageUriAsync(string prompt, CancellationToken ct = default)
88
- {
89
- var options = new ImageGenerationOptions
90
- {
91
- Size = GeneratedImageSize.W1024xH1024,
92
- Quality = GeneratedImageQuality.Standard,
93
- ResponseFormat = GeneratedImageFormat.Uri
94
- };
95
-
96
- GeneratedImage image = await _client.GenerateImageAsync(prompt, options, ct);
97
- return image.ImageUri!;
98
- }
99
- }
100
- ```
101
-
102
- **Registro DI:**
103
-
104
- ```csharp
105
- // Program.cs
106
- builder.Services.AddSingleton<ImageGenerationService>();
107
- ```
108
-
109
- **Consumo:**
110
-
111
- ```csharp
112
- public class CampaignController(ImageGenerationService imageGen, IBlobStorage storage) : ControllerBase
113
- {
114
- [HttpPost("generate-banner")]
115
- public async Task<IActionResult> GenerateBanner([FromBody] BannerRequest req)
116
- {
117
- BinaryData bytes = await imageGen.GenerateImageBytesAsync(
118
- prompt: req.Briefing,
119
- size: GeneratedImageSize.W1792xH1024,
120
- quality: GeneratedImageQuality.High);
121
-
122
- // Persista no storage do projeto antes de retornar
123
- string storedUrl = await storage.UploadAsync(bytes, "image/png");
124
- return Ok(new { url = storedUrl });
125
- }
126
- }
127
- ```
128
-
129
- ---
130
-
131
- ## Parâmetros
132
-
133
- > Valores verificados contra OpenAI .NET SDK 2.x / DALL-E 3 (2026-05-19). Outros providers podem variar.
134
-
135
- | Parâmetro | Tipo | Opções | Nota |
136
- |-----------|------|--------|------|
137
- | `Size` | `GeneratedImageSize` | `W1024xH1024`, `W1792xH1024`, `W1024xH1792` | DALL-E 3 suporta os três; DALL-E 2 tem conjunto diferente |
138
- | `Quality` | `GeneratedImageQuality` | `Standard`, `High` | `High` = mais detalhe, mais custo e latência |
139
- | `Style` | `GeneratedImageStyle` | `Natural`, `Vivid` | `Vivid` = mais saturado/dramático; `Natural` = realista |
140
- | `ResponseFormat` | `GeneratedImageFormat` | `Bytes`, `Uri` | Prefira `Bytes` — URLs expiram em ~1h |
141
-
142
- ---
143
-
144
- ## Anti-patterns
145
-
146
- | Anti-pattern | Por quê é errado | Jeito certo |
147
- |--------------|-----------------|-------------|
148
- | Gerar imagem quando asset estático resolve | Custo por chamada + latência sem ganho | Sirva de CDN; só gere quando o conteúdo é dinâmico por usuário/contexto |
149
- | Não moderar o prompt antes de enviar | Prompts maliciosos podem gerar conteúdo impróprio; o provider rejeitará e você terá erro 400 sem log útil | Aplique validação/moderação de prompt antes de chamar `GenerateImageAsync`; veja `ai-agents-middleware-patterns` |
150
- | Armazenar a URI retornada sem baixar | URLs do provider são efêmeras (~1h no OpenAI); links quebram depois | Use `ResponseFormat = Bytes`, persista no storage do projeto e sirva sua própria URL |
151
- | Criar `AIAgent` para geração de imagem | `ImageClient` não é `IChatClient`; não há sentido em wrappear como agente | Injete `ImageGenerationService` diretamente — é um serviço, não um agente |
152
-
153
- ---
154
-
155
- ## Checklist (verifiable by morph-eval)
156
-
157
- - [ ] `ImageClient` injetado via DI — não instanciado inline nos controllers
158
- - [ ] `ResponseFormat = GeneratedImageFormat.Bytes` na maioria dos casos; URLs armazenadas no storage do projeto
159
- - [ ] Prompt passa por validação/moderação antes de ir ao provider
160
- - [ ] Não usa `AIAgent`/`AsAIAgent` para geração de imagem — é um `ImageGenerationService`
161
- - [ ] Model e API key vêm de config, não hardcoded
162
-
163
- ---
164
-
165
- ## References
166
-
167
- - `ai-agents-setup` — packages, DI, e providers disponíveis
168
- - `ai-agents-providers-model-registry` — padrão de alias; adapte para resolver `ImageClient` por provider
169
- - OpenAI .NET SDK — `ImageClient`: https://github.com/openai/openai-dotnet
170
-
171
- ---
172
-
173
- *MORPH-SPEC by Polymorphism Tech — ai-agents/modalities-image-gen.md v1.0 (2026-05-19)*
1
+ # Modalities — Image Generation (Text to Image)
2
+
3
+ > **Scope:** stacks=["dotnet"]
4
+ > **Layer:** 2 (on-keyword)
5
+ > **Keywords:** image generation, text to image, dall-e, gpt-image, mockup generation, image synthesis
6
+ > **Read by Claude in:** implement (quando o projeto precisa gerar imagens a partir de texto)
7
+
8
+ **Verified against:** MAF 1.0 GA + OpenAI .NET SDK 2.x. Last-verified: 2026-05-19.
9
+
10
+ ---
11
+
12
+ ## Quando usar geração de imagem
13
+
14
+ Use quando o produto precisa criar imagens em runtime a partir de um prompt textual:
15
+
16
+ - **Mockups e protótipos visuais:** gerar capa de produto, banner de campanha, layout de tela
17
+ - **Conteúdo para social media:** imagens para posts geradas a partir de briefing do usuário
18
+ - **Visualizações:** diagramas, ilustrações ou thumbnails dinâmicos
19
+
20
+ **Nota importante:** geração de imagem é uma **chamada de serviço ao provider**, não um agente conversacional. Não crie um `AIAgent` para isso — use `ImageClient` diretamente via DI.
21
+
22
+ **Não use** quando um asset estático resolve o problema. Geração de imagem tem custo por chamada e latência de vários segundos. Se a imagem não muda por usuário/contexto, sirva de CDN.
23
+
24
+ ---
25
+
26
+ ## A API
27
+
28
+ O projeto resolve o `ImageClient` para o provider configurado. No OpenAI SDK (.NET 2.x), o caminho é:
29
+
30
+ ```csharp
31
+ using OpenAI.Images;
32
+
33
+ ImageClient client = new("dall-e-3", apiKey);
34
+ GeneratedImage image = await client.GenerateImageAsync(prompt, options);
35
+ ```
36
+
37
+ O projeto injeta `ImageClient` via DI (ver §Exemplo). A resolução pode ser feita via factory ou diretamente por configuração — não há um `GetImageClient("alias")` no `ModelRegistry` padrão; registre o `ImageClient` como serviço nomeado ou use uma factory simples que lê `model-registry.json`.
38
+
39
+ ---
40
+
41
+ ## Exemplo C# completo
42
+
43
+ ```csharp
44
+ using OpenAI.Images;
45
+ using Microsoft.Extensions.Configuration;
46
+
47
+ public sealed class ImageGenerationService
48
+ {
49
+ private readonly ImageClient _client;
50
+
51
+ public ImageGenerationService(IConfiguration config)
52
+ {
53
+ // O projeto configura o modelo e a chave via config/model-registry.json ou appsettings
54
+ var model = config["ImageGen:Model"] ?? "dall-e-3";
55
+ var apiKey = config["OpenAI:ApiKey"]!;
56
+ _client = new ImageClient(model, apiKey);
57
+ }
58
+
59
+ /// <summary>
60
+ /// Gera uma imagem a partir de um prompt e retorna os bytes PNG.
61
+ /// Prefira armazenar os bytes; URLs retornadas pelo provider são efêmeras (expiram em ~1h).
62
+ /// </summary>
63
+ public async Task<BinaryData> GenerateImageBytesAsync(
64
+ string prompt,
65
+ GeneratedImageSize? size = null,
66
+ GeneratedImageQuality? quality = null,
67
+ CancellationToken ct = default)
68
+ {
69
+ var resolvedSize = size ?? GeneratedImageSize.W1024xH1024;
70
+ var resolvedQuality = quality ?? GeneratedImageQuality.Standard;
71
+
72
+ var options = new ImageGenerationOptions
73
+ {
74
+ Size = resolvedSize,
75
+ Quality = resolvedQuality,
76
+ ResponseFormat = GeneratedImageFormat.Bytes
77
+ };
78
+
79
+ GeneratedImage image = await _client.GenerateImageAsync(prompt, options, ct);
80
+ return image.ImageBytes;
81
+ }
82
+
83
+ /// <summary>
84
+ /// Gera uma imagem e retorna a URI. Use apenas quando precisar da URL diretamente
85
+ /// e souber que o downstream vai consumir a URL antes de ela expirar (~1h no OpenAI).
86
+ /// </summary>
87
+ public async Task<Uri> GenerateImageUriAsync(string prompt, CancellationToken ct = default)
88
+ {
89
+ var options = new ImageGenerationOptions
90
+ {
91
+ Size = GeneratedImageSize.W1024xH1024,
92
+ Quality = GeneratedImageQuality.Standard,
93
+ ResponseFormat = GeneratedImageFormat.Uri
94
+ };
95
+
96
+ GeneratedImage image = await _client.GenerateImageAsync(prompt, options, ct);
97
+ return image.ImageUri!;
98
+ }
99
+ }
100
+ ```
101
+
102
+ **Registro DI:**
103
+
104
+ ```csharp
105
+ // Program.cs
106
+ builder.Services.AddSingleton<ImageGenerationService>();
107
+ ```
108
+
109
+ **Consumo:**
110
+
111
+ ```csharp
112
+ public class CampaignController(ImageGenerationService imageGen, IBlobStorage storage) : ControllerBase
113
+ {
114
+ [HttpPost("generate-banner")]
115
+ public async Task<IActionResult> GenerateBanner([FromBody] BannerRequest req)
116
+ {
117
+ BinaryData bytes = await imageGen.GenerateImageBytesAsync(
118
+ prompt: req.Briefing,
119
+ size: GeneratedImageSize.W1792xH1024,
120
+ quality: GeneratedImageQuality.High);
121
+
122
+ // Persista no storage do projeto antes de retornar
123
+ string storedUrl = await storage.UploadAsync(bytes, "image/png");
124
+ return Ok(new { url = storedUrl });
125
+ }
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Parâmetros
132
+
133
+ > Valores verificados contra OpenAI .NET SDK 2.x / DALL-E 3 (2026-05-19). Outros providers podem variar.
134
+
135
+ | Parâmetro | Tipo | Opções | Nota |
136
+ |-----------|------|--------|------|
137
+ | `Size` | `GeneratedImageSize` | `W1024xH1024`, `W1792xH1024`, `W1024xH1792` | DALL-E 3 suporta os três; DALL-E 2 tem conjunto diferente |
138
+ | `Quality` | `GeneratedImageQuality` | `Standard`, `High` | `High` = mais detalhe, mais custo e latência |
139
+ | `Style` | `GeneratedImageStyle` | `Natural`, `Vivid` | `Vivid` = mais saturado/dramático; `Natural` = realista |
140
+ | `ResponseFormat` | `GeneratedImageFormat` | `Bytes`, `Uri` | Prefira `Bytes` — URLs expiram em ~1h |
141
+
142
+ ---
143
+
144
+ ## Anti-patterns
145
+
146
+ | Anti-pattern | Por quê é errado | Jeito certo |
147
+ |--------------|-----------------|-------------|
148
+ | Gerar imagem quando asset estático resolve | Custo por chamada + latência sem ganho | Sirva de CDN; só gere quando o conteúdo é dinâmico por usuário/contexto |
149
+ | Não moderar o prompt antes de enviar | Prompts maliciosos podem gerar conteúdo impróprio; o provider rejeitará e você terá erro 400 sem log útil | Aplique validação/moderação de prompt antes de chamar `GenerateImageAsync`; veja `ai-agents-middleware-patterns` |
150
+ | Armazenar a URI retornada sem baixar | URLs do provider são efêmeras (~1h no OpenAI); links quebram depois | Use `ResponseFormat = Bytes`, persista no storage do projeto e sirva sua própria URL |
151
+ | Criar `AIAgent` para geração de imagem | `ImageClient` não é `IChatClient`; não há sentido em wrappear como agente | Injete `ImageGenerationService` diretamente — é um serviço, não um agente |
152
+
153
+ ---
154
+
155
+ ## Checklist (verifiable by morph-eval)
156
+
157
+ - [ ] `ImageClient` injetado via DI — não instanciado inline nos controllers
158
+ - [ ] `ResponseFormat = GeneratedImageFormat.Bytes` na maioria dos casos; URLs armazenadas no storage do projeto
159
+ - [ ] Prompt passa por validação/moderação antes de ir ao provider
160
+ - [ ] Não usa `AIAgent`/`AsAIAgent` para geração de imagem — é um `ImageGenerationService`
161
+ - [ ] Model e API key vêm de config, não hardcoded
162
+
163
+ ---
164
+
165
+ ## References
166
+
167
+ - `ai-agents-setup` — packages, DI, e providers disponíveis
168
+ - `ai-agents-providers-model-registry` — padrão de alias; adapte para resolver `ImageClient` por provider
169
+ - OpenAI .NET SDK — `ImageClient`: https://github.com/openai/openai-dotnet
170
+
171
+ ---
172
+
173
+ *MORPH-SPEC by Polymorphism Tech — ai-agents/modalities-image-gen.md v1.0 (2026-05-19)*