@polymorphism-tech/morph-spec 8.33.0 → 8.34.2

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 (176) hide show
  1. package/CLAUDE.md +3 -0
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +25 -1
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +2 -2
  9. package/framework/MORPH.md +4 -5
  10. package/framework/agents.json +1 -0
  11. package/framework/docs/CLI.md +5 -2
  12. package/framework/hooks/README.md +11 -1
  13. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +5 -8
  14. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +79 -0
  15. package/framework/hooks/claude-code/core/chain.js +27 -7
  16. package/framework/hooks/claude-code/core/worktree-context.js +83 -14
  17. package/framework/hooks/claude-code/core/worktree-create.js +206 -0
  18. package/framework/hooks/claude-code/core/worktree-env-inject.js +87 -0
  19. package/framework/hooks/claude-code/core/worktree-remove.js +81 -0
  20. package/framework/hooks/claude-code/statusline.sh +11 -11
  21. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  22. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  23. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  24. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  25. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  26. package/framework/hooks/shared/command-tokens.js +23 -0
  27. package/framework/hooks/shared/e2e-check.js +0 -0
  28. package/framework/hooks/shared/git-paths.js +25 -0
  29. package/framework/hooks/shared/hook-response.js +17 -0
  30. package/framework/hooks/shared/morph-cli.js +134 -0
  31. package/framework/hooks/shared/stdin-reader.js +26 -26
  32. package/framework/rules/infrastructure-standards.md +3 -1
  33. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  34. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  35. package/framework/skills/core/morph-apply/SKILL.md +3 -3
  36. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  37. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  38. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  39. package/framework/skills/core/morph-implement/SKILL.md +3 -1
  40. package/framework/skills/core/morph-plan/SKILL.md +6 -3
  41. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  42. package/framework/skills/core/morph-review/SKILL.md +1 -1
  43. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  44. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  45. package/framework/skills/core/morph-uiux/SKILL.md +1 -1
  46. package/framework/standards/STANDARDS.json +30 -0
  47. package/framework/standards/ai-agents/agent-session.md +160 -160
  48. package/framework/standards/ai-agents/batching.md +193 -193
  49. package/framework/standards/ai-agents/context-providers.md +188 -188
  50. package/framework/standards/ai-agents/mcp-server.md +250 -250
  51. package/framework/standards/ai-agents/mcp-tools.md +197 -197
  52. package/framework/standards/ai-agents/middleware-patterns.md +207 -207
  53. package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
  54. package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
  55. package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
  56. package/framework/standards/ai-agents/modalities-vision.md +201 -201
  57. package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
  58. package/framework/standards/ai-agents/production.md +231 -231
  59. package/framework/standards/ai-agents/prompts-in-db.md +214 -214
  60. package/framework/standards/ai-agents/providers/model-registry.md +158 -158
  61. package/framework/standards/ai-agents/service-tier-flex.md +135 -135
  62. package/framework/standards/ai-agents/structured-output.md +249 -249
  63. package/framework/standards/ai-agents/sweet-spot.md +109 -109
  64. package/framework/standards/infrastructure/docker/local-compose-isolation.md +88 -0
  65. package/framework/templates/IDE-SNIPPETS.md +262 -262
  66. package/framework/templates/REGISTRY.json +1 -1
  67. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  68. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  69. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  70. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  71. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  72. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  73. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  74. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  75. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  76. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  77. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  78. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  79. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  80. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  81. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  82. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  83. package/framework/templates/code/typescript/contracts.ts +167 -167
  84. package/framework/templates/docs/clarifications.md +253 -253
  85. package/framework/templates/docs/schema-analysis.md +119 -119
  86. package/framework/templates/docs/ui-components.md +52 -52
  87. package/framework/templates/docs/ui-design-system.md +76 -76
  88. package/framework/templates/docs/ui-flows.md +167 -167
  89. package/framework/templates/docs/ui-mockups.md +98 -98
  90. package/framework/templates/feature/decisions.md +122 -122
  91. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  92. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  93. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  94. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  95. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  96. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  97. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  98. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  99. package/framework/templates/infrastructure/docker/docker-compose.template.yml +24 -14
  100. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  101. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  102. package/framework/templates/infrastructure/github/README.md +56 -56
  103. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  104. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  105. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  106. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  107. package/framework/templates/integrations/asaas-client.cs +387 -387
  108. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  109. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  110. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  111. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  112. package/framework/templates/project/validate.js +120 -120
  113. package/framework/templates/state.template.json +17 -17
  114. package/framework/templates/ui/design-system.css +226 -226
  115. package/package.json +1 -1
  116. package/src/commands/dashboard/dashboard.js +53 -53
  117. package/src/commands/e2e/e2e.js +77 -39
  118. package/src/commands/index.js +13 -13
  119. package/src/commands/project/checkpoint.js +209 -209
  120. package/src/commands/project/doctor.js +8 -6
  121. package/src/commands/project/env.js +95 -0
  122. package/src/commands/project/worktree.js +266 -52
  123. package/src/commands/state/delete.js +8 -0
  124. package/src/commands/state/finish.js +29 -34
  125. package/src/core/state/phase-state-machine.js +197 -197
  126. package/src/core/templates/template-renderer.js +477 -477
  127. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  128. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  129. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  130. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  131. package/src/dashboard/app/main.jsx +13 -13
  132. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  133. package/src/dashboard/app/pages/HookInspector.jsx +430 -418
  134. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  135. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  136. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  137. package/src/dashboard/app/pages/Standards.jsx +332 -332
  138. package/src/dashboard/app/styles/index.css +47 -47
  139. package/src/dashboard/index.html +12 -12
  140. package/src/dashboard/package.json +24 -24
  141. package/src/dashboard/scanner/hooks-scanner.js +5 -1
  142. package/src/dashboard/scanner/phases-scanner.js +15 -15
  143. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  144. package/src/dashboard/scanner/rules-scanner.js +37 -37
  145. package/src/dashboard/scanner/skills-scanner.js +43 -43
  146. package/src/dashboard/scanner/squads-scanner.js +13 -13
  147. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  148. package/src/dashboard/vite.config.js +24 -24
  149. package/src/lib/detectors/design-system-detector.js +188 -188
  150. package/src/lib/detectors/index.js +217 -217
  151. package/src/lib/e2e/compose-env.js +6 -11
  152. package/src/lib/e2e/stack-teardown.js +115 -0
  153. package/src/lib/generators/architecture-scanner.js +2 -1
  154. package/src/lib/generators/design-system-generator.js +508 -508
  155. package/src/lib/generators/settings-generator.js +209 -209
  156. package/src/lib/graph/graphifyignore.js +2 -1
  157. package/src/lib/hooks/hook-executor.js +167 -167
  158. package/src/lib/installers/mcp-installer.js +719 -719
  159. package/src/lib/tasks/task-classifier.js +30 -30
  160. package/src/lib/tasks/task-parser.js +209 -209
  161. package/src/lib/tasks/test-runner.js +21 -4
  162. package/src/lib/validators/checkpoint-persistence.js +39 -39
  163. package/src/lib/validators/css/css-validator.js +340 -340
  164. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  165. package/src/lib/validators/shared/issue-counter.js +14 -14
  166. package/src/lib/validators/verify-runner.js +7 -0
  167. package/src/lib/worktree/dirs.js +32 -0
  168. package/src/lib/worktree/env-allocator.js +45 -11
  169. package/src/lib/worktree/worktree-audit.js +40 -2
  170. package/src/utils/agent-id-mapper.js +11 -11
  171. package/src/utils/claude-settings-manager.js +300 -300
  172. package/src/utils/file-copier.js +18 -13
  173. package/src/utils/hooks-installer.js +46 -3
  174. package/src/utils/skills-installer.js +187 -187
  175. package/framework/templates/.idea/morph-templates.xml +0 -92
  176. package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
@@ -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)*