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