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