@polymorphism-tech/morph-spec 8.33.0 → 8.35.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.
- package/CLAUDE.md +22 -2
- package/README.md +2 -2
- package/bin/morph-spec.js +43 -5
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +5 -4
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +2 -2
- package/framework/MORPH.md +20 -22
- package/framework/agents.json +198 -44
- package/framework/ai-pin.json +22 -0
- package/framework/commands/morph-media.md +45 -0
- package/framework/docs/CLI.md +238 -10
- package/framework/evals/proof-rubrics/README.md +76 -0
- package/framework/evals/proof-rubrics/eval-de-modelo.md +64 -0
- package/framework/evals/proof-rubrics/fiacao.md +54 -0
- package/framework/evals/proof-rubrics/guard-cego.md +52 -0
- package/framework/evals/proof-rubrics/media-claims.md +109 -0
- package/framework/evals/proof-rubrics/mutation-proof.md +77 -0
- package/framework/evals/proof-rubrics/observabilidade-genai.md +119 -0
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +48 -0
- package/framework/evals/rubrics/architecture.md +30 -0
- package/framework/evals/rubrics/code-quality.md +26 -0
- package/framework/evals/rubrics/test-coverage.md +20 -0
- package/framework/hooks/README.md +11 -1
- package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +5 -8
- package/framework/hooks/claude-code/core/block-raw-worktree-add.js +79 -0
- package/framework/hooks/claude-code/core/chain.js +27 -7
- package/framework/hooks/claude-code/core/protect-spec-files.js +41 -4
- package/framework/hooks/claude-code/core/worktree-context.js +83 -14
- package/framework/hooks/claude-code/core/worktree-create.js +206 -0
- package/framework/hooks/claude-code/core/worktree-env-inject.js +87 -0
- package/framework/hooks/claude-code/core/worktree-remove.js +81 -0
- package/framework/hooks/shared/command-tokens.js +23 -0
- package/framework/hooks/shared/e2e-check.js +0 -0
- package/framework/hooks/shared/git-paths.js +25 -0
- package/framework/hooks/shared/hook-response.js +17 -0
- package/framework/hooks/shared/morph-cli.js +134 -0
- package/framework/rules/ai-agents-standards.md +14 -2
- package/framework/rules/infrastructure-standards.md +3 -1
- package/framework/schemas/ai-pin.schema.json +97 -0
- package/framework/schemas/config.schema.json +107 -0
- package/framework/schemas/feature.schema.json +23 -4
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +28 -7
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
- package/framework/skills/core/morph-implement/SKILL.md +20 -2
- package/framework/skills/core/morph-media/SKILL.md +215 -0
- package/framework/skills/core/morph-plan/SKILL.md +38 -4
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +166 -9
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +1 -1
- package/framework/standards/PROVENANCE.json +81 -3
- package/framework/standards/STANDARDS.json +1504 -830
- package/framework/standards/ai-agents/agent-archetypes.md +160 -0
- package/framework/standards/ai-agents/agent-session.md +256 -160
- package/framework/standards/ai-agents/agent-spec.md +196 -0
- package/framework/standards/ai-agents/batching.md +217 -193
- package/framework/standards/ai-agents/context-providers.md +261 -188
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +239 -0
- package/framework/standards/ai-agents/cost-and-budget.md +256 -0
- package/framework/standards/ai-agents/durable-workflows-hitl.md +98 -5
- package/framework/standards/ai-agents/evals-with-cache.md +289 -0
- package/framework/standards/ai-agents/guardrails.md +222 -0
- package/framework/standards/ai-agents/llm-runtime-defaults.md +226 -0
- package/framework/standards/ai-agents/mcp-server.md +351 -250
- package/framework/standards/ai-agents/mcp-tools.md +250 -197
- package/framework/standards/ai-agents/media-pipeline.md +352 -0
- package/framework/standards/ai-agents/media-video.md +267 -0
- package/framework/standards/ai-agents/middleware-patterns.md +241 -207
- package/framework/standards/ai-agents/modalities-image-gen.md +422 -173
- package/framework/standards/ai-agents/modalities-speech-to-text.md +177 -171
- package/framework/standards/ai-agents/modalities-text-to-speech.md +189 -181
- package/framework/standards/ai-agents/modalities-vision.md +205 -201
- package/framework/standards/ai-agents/multi-agent-patterns.md +211 -155
- package/framework/standards/ai-agents/observability-patterns.md +227 -17
- package/framework/standards/ai-agents/production.md +260 -231
- package/framework/standards/ai-agents/prompt-sources.md +389 -0
- package/framework/standards/ai-agents/providers/model-registry.md +293 -158
- package/framework/standards/ai-agents/rag-custom-pgvector.md +69 -4
- package/framework/standards/ai-agents/service-tier-flex.md +143 -135
- package/framework/standards/ai-agents/setup.md +166 -50
- package/framework/standards/ai-agents/structured-output.md +280 -249
- package/framework/standards/ai-agents/sweet-spot.md +129 -109
- package/framework/standards/ai-agents/testing-ai.md +236 -0
- package/framework/standards/ai-agents/vector-data-extensions.md +50 -20
- package/framework/standards/ai-agents/workflows.md +27 -7
- package/framework/standards/frontend/design-system/ai-image-generation.md +12 -0
- package/framework/standards/frontend/design-system/ai-video-generation.md +13 -0
- package/framework/standards/infrastructure/docker/local-compose-isolation.md +90 -0
- package/framework/templates/REGISTRY.json +14 -1
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
- package/framework/templates/dotnet/ai-kit/Directory.Build.props +25 -0
- package/framework/templates/dotnet/ai-kit/Directory.Packages.props +26 -0
- package/framework/templates/dotnet/ai-kit/Morph.AiKit.sln +56 -0
- package/framework/templates/dotnet/ai-kit/NuGet.config +12 -0
- package/framework/templates/dotnet/ai-kit/README.md +128 -0
- package/framework/templates/dotnet/ai-kit/global.json +9 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +65 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +289 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +181 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +14 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +174 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +54 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +75 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +71 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +246 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +57 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +78 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +225 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +463 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +32 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +49 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +214 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +168 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +142 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +349 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +42 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +77 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +28 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +107 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +253 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +103 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +259 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +21 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +47 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +102 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +44 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +192 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +94 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +99 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +97 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +133 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +93 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +112 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +288 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +158 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +29 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +208 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +95 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Morph.AiKit.csproj +38 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +119 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +82 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +33 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +267 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +474 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/model-registry.v2.json +87 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +169 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +49 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +495 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +260 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +405 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +379 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +197 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +139 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +157 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +178 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +153 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +194 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +86 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +213 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +95 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +225 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +215 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +55 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +60 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +131 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +133 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +127 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +216 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +264 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +148 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +184 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +98 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +451 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +76 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +261 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +374 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/.morph-eval-cache.json +12 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/orcamento/acme/a-resposta-estruturada.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/a-saudacao.json +23 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/b-escalonamento.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/globex/a-saudacao.json +23 -0
- package/framework/templates/infrastructure/docker/docker-compose.template.yml +24 -14
- package/package.json +3 -3
- package/src/commands/e2e/e2e.js +91 -40
- package/src/commands/project/doctor.js +143 -6
- package/src/commands/project/env.js +95 -0
- package/src/commands/project/update.js +469 -153
- package/src/commands/project/worktree.js +274 -53
- package/src/commands/state/advance.js +24 -2
- package/src/commands/state/approve.js +33 -1
- package/src/commands/state/create.js +72 -11
- package/src/commands/state/delete.js +8 -0
- package/src/commands/state/finish.js +360 -53
- package/src/commands/state/gate-check.js +190 -6
- package/src/commands/state/score.js +36 -1
- package/src/commands/validation/verify.js +134 -25
- package/src/core/state/state-manager.js +9 -1
- package/src/dashboard/app/pages/HookInspector.jsx +430 -418
- package/src/dashboard/scanner/hooks-scanner.js +5 -1
- package/src/lib/ai/ai-checks.js +182 -0
- package/src/lib/ai/ai-project-scan.js +347 -0
- package/src/lib/ai/code-audit.js +181 -0
- package/src/lib/ai/comment-stripper.js +184 -0
- package/src/lib/ai/pin-drift.js +138 -0
- package/src/lib/ai/registry-audit.js +285 -0
- package/src/lib/e2e/compose-env.js +55 -14
- package/src/lib/e2e/stack-teardown.js +115 -0
- package/src/lib/evaluator-report.js +269 -15
- package/src/lib/generators/architecture-scanner.js +2 -1
- package/src/lib/git/default-branch.js +92 -4
- package/src/lib/graph/graphifyignore.js +2 -1
- package/src/lib/installers/effects.js +193 -0
- package/src/lib/installers/templates-reconcile.js +3 -3
- package/src/lib/risk-detector.js +284 -0
- package/src/lib/standards/verified-against.js +276 -0
- package/src/lib/tasks/eval-node.js +485 -0
- package/src/lib/tasks/linux-runner.js +297 -0
- package/src/lib/tasks/test-nodes.js +486 -0
- package/src/lib/tasks/test-runner.js +431 -37
- package/src/lib/validators/verify-runner.js +590 -28
- package/src/lib/worktree/dirs.js +32 -0
- package/src/lib/worktree/docker-audit.js +287 -0
- package/src/lib/worktree/env-allocator.js +69 -11
- package/src/lib/worktree/worktree-audit.js +70 -3
- package/src/scripts/setup-infra.js +24 -11
- package/src/utils/agents-installer.js +18 -8
- package/src/utils/claude-md-injector.js +10 -5
- package/src/utils/file-copier.js +28 -16
- package/src/utils/hooks-installer.js +75 -29
- package/src/utils/skills-installer.js +194 -187
- package/src/utils/version-checker.js +68 -3
- package/framework/standards/ai-agents/prompts-in-db.md +0 -214
|
@@ -1,173 +1,422 @@
|
|
|
1
|
-
# Modalities — Image Generation (
|
|
2
|
-
|
|
3
|
-
> **Scope:** stacks=["dotnet"]
|
|
4
|
-
> **Layer:** 2 (on-keyword)
|
|
5
|
-
> **Keywords:** image generation, text to image,
|
|
6
|
-
> **Read by Claude in:** implement (quando o projeto precisa gerar
|
|
7
|
-
|
|
8
|
-
**Verified against:**
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
1
|
+
# Modalities — Image Generation (media-generation)
|
|
2
|
+
|
|
3
|
+
> **Scope:** stacks=["dotnet"]
|
|
4
|
+
> **Layer:** 2 (on-keyword)
|
|
5
|
+
> **Keywords:** image generation, text to image, gpt-image, nano banana, image editing, product photo, mockup generation, image synthesis
|
|
6
|
+
> **Read by Claude in:** implement (quando o projeto precisa gerar ou editar imagens em runtime)
|
|
7
|
+
|
|
8
|
+
**Verified against:** OpenAI 2.13.0 + Microsoft.Extensions.AI 10.9.0 + Google.GenAI 1.21.0 (ai-pin 2026-09-08); provado por `templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs` — `IImageGenerator`, `MEAI001`, `ImageGenerationRequest.OriginalImages` e a ausência de propriedade tipada para `quality` COMPILAM ali, e `OPENAI001` em `GeneratedImageQuality` foi medido pelo compilador. `HostedImageGenerationTool` foi medido por reflexão sobre a assembly do pin (existe, não é experimental); preço, data de desligamento e limites de referência são **verificação documental** contra as páginas de §Como re-verificar este standard. Last-verified: 2026-09-08.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Geração de imagem **em runtime, a partir de .NET**. Autoria de asset de landing page por MCP, em
|
|
13
|
+
tempo de design, é outro standard e outro consumidor:
|
|
14
|
+
`frontend/design-system/ai-image-generation.md` — prompt craft de marca, `assets.md`, integração com
|
|
15
|
+
`next/image`. Este aqui é sobre a chamada paga que o seu backend faz, o que ela custa e onde ela
|
|
16
|
+
pode morar.
|
|
17
|
+
|
|
18
|
+
O pipeline que recebe o pedido, revisa e publica está em `ai-agents/media-pipeline.md`. Vídeo está
|
|
19
|
+
em `ai-agents/media-video.md`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quando usar geração de imagem
|
|
24
|
+
|
|
25
|
+
| Caso | Por que a geração ganha do asset estático |
|
|
26
|
+
|---|---|
|
|
27
|
+
| **Catálogo** | Variação de tecido, cor e cena sobre o **mesmo** produto real, a partir de foto de referência |
|
|
28
|
+
| **Marketing** | Peça de campanha por segmento, com texto na imagem, em volume |
|
|
29
|
+
| **Variação de produto** | N combinações que ninguém fotografaria uma a uma |
|
|
30
|
+
|
|
31
|
+
**Não use** quando um asset estático resolve: custo por chamada, latência de vários segundos e
|
|
32
|
+
nenhuma garantia de repetibilidade. Se a imagem não muda por usuário ou por contexto, sirva de CDN.
|
|
33
|
+
|
|
34
|
+
**Não use dentro de um turno de conversa.** Esta é a regra dura da casa, e ela não é estética:
|
|
35
|
+
a documentação da própria OpenAI declara que um prompt complexo pode levar **até 2 minutos**, cada
|
|
36
|
+
chamada custa dinheiro, e dentro do turno **não existe revisão humana possível**. O turno enfileira
|
|
37
|
+
e confirma; a mídia volta depois, revisada. O mecanismo que prende essa regra — e não apenas a
|
|
38
|
+
explica — está em `ai-agents/media-pipeline.md`.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## A API
|
|
43
|
+
|
|
44
|
+
Duas superfícies, e a escolha entre elas é por **necessidade**, não por gosto.
|
|
45
|
+
|
|
46
|
+
### Abstração `IImageGenerator` (Microsoft.Extensions.AI)
|
|
47
|
+
|
|
48
|
+
```csharp
|
|
49
|
+
using Microsoft.Extensions.AI;
|
|
50
|
+
using OpenAI.Images;
|
|
51
|
+
|
|
52
|
+
#pragma warning disable MEAI001 // IImageGenerator e experimental: a superficie pode mudar entre menores
|
|
53
|
+
// AsIImageGenerator() vem de Microsoft.Extensions.AI.OpenAI — um pacote A MAIS.
|
|
54
|
+
// Sem ele, escreva o adaptador (e o kit escreve: ver a nota abaixo).
|
|
55
|
+
IImageGenerator generator = new ImageClient("gpt-image-2", apiKey).AsIImageGenerator();
|
|
56
|
+
|
|
57
|
+
var response = await generator.GenerateAsync(
|
|
58
|
+
new ImageGenerationRequest { Prompt = prompt },
|
|
59
|
+
new ImageGenerationOptions { MediaType = "image/png", Count = 1 },
|
|
60
|
+
ct);
|
|
61
|
+
#pragma warning restore MEAI001
|
|
62
|
+
|
|
63
|
+
var bytes = response.Contents.OfType<DataContent>().First().Data;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> **A ponte é um pacote separado, e isso muda o seu `.csproj`.** `AsIImageGenerator()` é uma extensão
|
|
67
|
+
> de `Microsoft.Extensions.AI.OpenAI`; ter `Microsoft.Extensions.AI` e `OpenAI` **não** basta —
|
|
68
|
+
> medido pelo compilador. Se o pacote da ponte não estiver no seu pin, o caminho é escrever um
|
|
69
|
+
> `IImageGenerator` sobre o `ImageClient`, como o exemplar do kit faz em
|
|
70
|
+
> `templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs`. As duas
|
|
71
|
+
> alternativas são legítimas; o que não é legítimo é descobrir isso em tempo de build depois de ter
|
|
72
|
+
> escrito o pipeline inteiro.
|
|
73
|
+
|
|
74
|
+
Fatos que decidem o desenho, medidos contra `Microsoft.Extensions.AI.Abstractions` 10.9.0:
|
|
75
|
+
|
|
76
|
+
- `IImageGenerator` carrega `[Experimental("MEAI001")]`. Suprimir o diagnóstico é obrigatório, e o
|
|
77
|
+
`#pragma` **leva comentário do risco** — é o que separa "assumimos a instabilidade" de
|
|
78
|
+
"silenciamos um aviso".
|
|
79
|
+
- `ImageGenerationRequest` tem `Prompt` e `OriginalImages` (`IEnumerable<AIContent>`). `OriginalImages`
|
|
80
|
+
é o gancho de **edição com referência** — é por ele que o produto real é preservado.
|
|
81
|
+
- `ImageGenerationOptions` expõe `AdditionalProperties`, `Count`, `ImageSize`, `MediaType`,
|
|
82
|
+
`ModelId`, `RawRepresentationFactory`, `ResponseFormat` e `StreamingCount`. **Não há propriedade
|
|
83
|
+
tipada** para `quality`, `background` ou `input_fidelity`: esses vão por `AdditionalProperties` ou
|
|
84
|
+
por `RawRepresentationFactory`. Escrever `options.Quality` não compila, e procurar por ela é o
|
|
85
|
+
primeiro tropeço de quem chega vindo do `ImageClient` direto.
|
|
86
|
+
- Único adaptador oficial é OpenAI/Azure OpenAI (`OpenAIClientExtensions.AsIImageGenerator`, **no
|
|
87
|
+
pacote `Microsoft.Extensions.AI.OpenAI` — ver a ressalva acima**). Para
|
|
88
|
+
Gemini **não existe** adaptador MEAI oficial: use `Google.GenAI` direto
|
|
89
|
+
(`Client.Models.GenerateContentAsync` com `ResponseModalities = ["IMAGE", "TEXT"]`, lendo
|
|
90
|
+
`Candidates[0].Content.Parts[..].InlineData`), ou escreva um `IImageGenerator` próprio.
|
|
91
|
+
|
|
92
|
+
### Images API direto, quando o produto real precisa ser preservado
|
|
93
|
+
|
|
94
|
+
`POST /v1/images/edits` aceita N imagens de referência (PNG/JPG/WebP, cada uma **abaixo de 50 MB**,
|
|
95
|
+
mesmo formato e tamanho) e uma `mask` PNG com alfa nas mesmas dimensões da primeira imagem. É o
|
|
96
|
+
caminho para catálogo: editar preserva; gerar do zero recria.
|
|
97
|
+
|
|
98
|
+
`GenerateImageVariationAsync` do SDK **não é opção** — a API de variações só existia no modelo
|
|
99
|
+
listado em §Deprecações.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Tool hospedada de imagem
|
|
104
|
+
|
|
105
|
+
`Microsoft.Extensions.AI.HostedImageGenerationTool` existe na 10.9.0, **não** é experimental e é um
|
|
106
|
+
*marker*: ela não gera nada, apenas informa ao serviço que o modelo pode gerar
|
|
107
|
+
(`Name => "image_generation"`). O adaptador da OpenAI mapeia `ModelId → Model`,
|
|
108
|
+
`MediaType → OutputFileFormat`, `StreamingCount → PartialImageCount` e `ImageSize → Size`;
|
|
109
|
+
**`quality`, `background`, `moderation` e `input_fidelity` não são mapeados**. O resultado volta
|
|
110
|
+
como `ImageGenerationToolResultContent { Outputs = [DataContent] }` dentro de
|
|
111
|
+
`ChatResponse.Messages[..].Contents` — nunca como `FunctionResultContent`.
|
|
112
|
+
|
|
113
|
+
> **Procedência, separada em dois níveis.** Que o tipo **existe** e **não** é experimental na 10.9.0
|
|
114
|
+
> foi medido por reflexão sobre a assembly do pin. Já a **tabela de mapeamento** acima vem da leitura
|
|
115
|
+
> de `OpenAIResponsesChatClient.cs` em
|
|
116
|
+
> `https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.AI.OpenAI/`,
|
|
117
|
+
> consultado em 2026-09-07 — é
|
|
118
|
+
> código **interno** da ponte, fora da superfície pública, e portanto não confirmável por reflexão.
|
|
119
|
+
> Confirme contra o provedor configurado antes de contar com um desses parâmetros pela tool.
|
|
120
|
+
|
|
121
|
+
**E é exatamente por isso que ela não entra no agente de WhatsApp.** A tool é o caminho natural de
|
|
122
|
+
"me mostra esse sofá em verde", e a documentação a descreve para chat/atendimento. Este standard
|
|
123
|
+
**contradiz** essa leitura para o atendimento, com o motivo escrito:
|
|
124
|
+
|
|
125
|
+
| Fato | Consequência no turno |
|
|
126
|
+
|---|---|
|
|
127
|
+
| Latência documentada de até 2 min | O turno estoura; o cliente vê silêncio |
|
|
128
|
+
| Custo por chamada, sem teto natural | Um usuário curioso vira uma fatura |
|
|
129
|
+
| `quality`/`moderation` não mapeados pelo adaptador | Você não controla nem o custo nem o filtro |
|
|
130
|
+
| Nenhuma revisão possível dentro do turno | Claim visual errado sai direto para o cliente |
|
|
131
|
+
|
|
132
|
+
O que o turno faz é **enfileirar e confirmar**. A tool hospedada é legítima em ferramenta interna,
|
|
133
|
+
com humano na frente da tela e orçamento controlado — nunca no canal do cliente.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Provedor por alias
|
|
138
|
+
|
|
139
|
+
O alias mora no `model-registry.v2.json` do kit, com `api` declarando o protocolo. Alias de imagem
|
|
140
|
+
usa `api: images`; alias de vídeo, `api: videos` (ver `ai-agents/media-video.md`). O `AgentFactory`
|
|
141
|
+
**recusa com erro nomeado** um alias de mídia passado como agente de chat: um alias de imagem
|
|
142
|
+
resolvido como conversa apontaria para um modelo que não fala chat, e a falha apareceria tarde e
|
|
143
|
+
confusa.
|
|
144
|
+
|
|
145
|
+
| Papel | Alias | Por quê |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| Imagem, default | `gpt-image-2` | Default do próprio provedor; resolução arbitrária (múltiplos de 16 px, lado ≤ 3840 px, razão ≤ 3:1); até 8 imagens coerentes por prompt; `input_fidelity` deixou de existir porque a fidelidade já é alta |
|
|
148
|
+
| Imagem, referência de produto | `gemini-3.1-flash-image` | 10 objetos + 4 personagens + 3 estilos de referência — o caso "muitas fotos do mesmo móvel" |
|
|
149
|
+
| Imagem, lote barato | `gemini-3.1-flash-lite-image` | O piso de preço da família, com 14 objetos de referência |
|
|
150
|
+
| Vídeo | ver `ai-agents/media-video.md` | Fora do escopo deste standard |
|
|
151
|
+
|
|
152
|
+
**Nenhum alias fora desta lista sem passar pela tabela de §Deprecações primeiro.** Um alias
|
|
153
|
+
proibido não é preferência de estilo: é dinheiro gasto num endpoint que vai devolver erro.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Prompt como spec versionada
|
|
158
|
+
|
|
159
|
+
Um prompt de produção é **template versionado**, nunca string concatenada no handler. O que o
|
|
160
|
+
template fixa:
|
|
161
|
+
|
|
162
|
+
1. **Estrutura, sempre na mesma ordem:** cena/fundo → sujeito → detalhes-chave → restrições.
|
|
163
|
+
Segmentos rotulados; frases descritivas, não lista de keywords.
|
|
164
|
+
2. **Fotorrealismo declarado** quando é o caso ("photorealistic", "professional product
|
|
165
|
+
photography"); termos de câmera servem à composição, não à física.
|
|
166
|
+
3. **Texto na imagem entre aspas literais**, marcas soletradas.
|
|
167
|
+
4. **"Preserve list" repetida em CADA iteração de edição** — "change only X, keep everything else".
|
|
168
|
+
Iterações pequenas e sequenciais; ao driftar, reinicie a conversa com a descrição completa em vez
|
|
169
|
+
de empilhar correções.
|
|
170
|
+
5. **Fundo transparente vem do parâmetro, não do prompt** (`background=transparent` + PNG/WebP):
|
|
171
|
+
descrever o fundo no texto faz o prompt vencer o parâmetro.
|
|
172
|
+
|
|
173
|
+
O prompt final vai para a proveniência do job junto com o `revised_prompt` que o provedor devolve —
|
|
174
|
+
ver `ai-agents/media-pipeline.md`. Prompt que não foi gravado não pode ser reproduzido nem auditado.
|
|
175
|
+
|
|
176
|
+
Para prompt craft de marca (paleta, tom, herói aprovado como referência das derivadas), o standard
|
|
177
|
+
é `frontend/design-system/ai-image-generation.md`; este não o repete.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Referências de produto
|
|
182
|
+
|
|
183
|
+
| Modelo | Limite de referência |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `gemini-3.1-flash-lite-image` | 14 objetos |
|
|
186
|
+
| `gemini-3.1-flash-image` | 10 objetos + 4 personagens + 3 estilos |
|
|
187
|
+
| `gemini-3-pro-image` | 6 objetos + 5 personagens |
|
|
188
|
+
| OpenAI `/v1/images/edits` | N imagens, cada uma abaixo de 50 MB, mesmo formato e tamanho |
|
|
189
|
+
|
|
190
|
+
**Indexe cada referência no prompt** ("image 1 = o sofá; image 2 = o tecido") e diga como elas
|
|
191
|
+
interagem. Referência não nomeada é referência que o modelo escolhe sozinho como usar.
|
|
192
|
+
|
|
193
|
+
O hash sha256 de cada referência entra na chave de idempotência do pedido (`media-pipeline.md`):
|
|
194
|
+
trocar a foto de referência **é** outro pedido, mesmo com o prompt idêntico.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Exemplo C# completo
|
|
199
|
+
|
|
200
|
+
```csharp
|
|
201
|
+
// SEM `using OpenAI.Images;`. Ele nao e necessario aqui — o gerador chega injetado e nenhum
|
|
202
|
+
// tipo do SDK da OpenAI aparece neste arquivo — e deixa-lo torna `ImageGenerationOptions`
|
|
203
|
+
// AMBIGUO (CS0104) entre Microsoft.Extensions.AI e OpenAI.Images. Onde os dois convivem de
|
|
204
|
+
// verdade, como no adaptador do kit, o tipo vai QUALIFICADO.
|
|
205
|
+
using Microsoft.Extensions.AI;
|
|
206
|
+
|
|
207
|
+
// O pragma abre ACIMA da classe, e nao dentro do metodo: o parametro do construtor primario
|
|
208
|
+
// tambem nomeia IImageGenerator, e MEAI001 e ERRO por padrao — nao aviso. Pragma dentro do
|
|
209
|
+
// corpo deixa a assinatura de fora e o arquivo nao compila.
|
|
210
|
+
#pragma warning disable MEAI001 // IImageGenerator/ImageGenerationRequest sao experimentais: a superficie pode mudar entre menores.
|
|
211
|
+
|
|
212
|
+
/// <summary>
|
|
213
|
+
/// Adaptador de PROVIDER. Note o que ele NAO e: um servico publico que um handler
|
|
214
|
+
/// possa chamar. Quem produz bytes vive atras do enfileiramento descrito em
|
|
215
|
+
/// ai-agents/media-pipeline.md, e no kit esse tipo e `internal` de proposito.
|
|
216
|
+
/// </summary>
|
|
217
|
+
/// <remarks>
|
|
218
|
+
/// O IImageGenerator chega INJETADO, e nao construido aqui. As duas formas de obte-lo
|
|
219
|
+
/// sao legitimas e a escolha e do seu pin (ver a ressalva da secao "A API"):
|
|
220
|
+
/// - com Microsoft.Extensions.AI.OpenAI no pin: imageClient.AsIImageGenerator()
|
|
221
|
+
/// - sem ele: um IImageGenerator escrito a mao sobre o ImageClient, como em
|
|
222
|
+
/// templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs
|
|
223
|
+
/// Injetar em vez de construir e o que faz ESTE exemplo compilar nos dois casos.
|
|
224
|
+
/// </remarks>
|
|
225
|
+
internal sealed class OpenAiImageAdapter(IImageGenerator generator)
|
|
226
|
+
{
|
|
227
|
+
// ReadOnlyMemory<byte> dos dois lados porque e o tipo REAL de DataContent.Data.
|
|
228
|
+
// Declarar BinaryData aqui nao converte (CS0029) — e o compilador que decide isso.
|
|
229
|
+
public async Task<ReadOnlyMemory<byte>> ProduceAsync(
|
|
230
|
+
string prompt,
|
|
231
|
+
IReadOnlyList<ReadOnlyMemory<byte>> references,
|
|
232
|
+
CancellationToken ct)
|
|
233
|
+
{
|
|
234
|
+
var request = new ImageGenerationRequest { Prompt = prompt };
|
|
235
|
+
if (references.Count > 0)
|
|
236
|
+
{
|
|
237
|
+
// OriginalImages e o gancho de EDICAO: preserva o produto real em vez de recria-lo.
|
|
238
|
+
request.OriginalImages = [.. references.Select(r => new DataContent(r, "image/png"))];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
var options = new ImageGenerationOptions
|
|
242
|
+
{
|
|
243
|
+
MediaType = "image/png",
|
|
244
|
+
Count = 1,
|
|
245
|
+
// Nao ha propriedade tipada para quality/background/input_fidelity na 10.9.0.
|
|
246
|
+
AdditionalProperties = new() { ["quality"] = "low" },
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
var response = await generator.GenerateAsync(request, options, ct);
|
|
250
|
+
|
|
251
|
+
return response.Contents.OfType<DataContent>().First().Data;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#pragma warning restore MEAI001
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Escada de qualidade, e ela é obrigatória:** gere N candidatas em `low`, escolha com humano, e só
|
|
259
|
+
então regenere a vencedora em `high`. A conta de gerar tudo em `high` está em §Custo por chamada.
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Parâmetros
|
|
264
|
+
|
|
265
|
+
> Superfície de `ImageGenerationOptions` medida contra `Microsoft.Extensions.AI.Abstractions`
|
|
266
|
+
> 10.9.0; parâmetros de wire medidos contra a Images API da OpenAI.
|
|
267
|
+
|
|
268
|
+
| Parâmetro | Onde vive | Nota |
|
|
269
|
+
|---|---|---|
|
|
270
|
+
| `ModelId` | tipado | Vem do alias, nunca do handler |
|
|
271
|
+
| `Count` | tipado | N candidatas numa chamada; cobra por imagem |
|
|
272
|
+
| `ImageSize` | tipado (`System.Drawing.Size`) | `gpt-image-2` aceita múltiplos de 16 px até 3840 px de lado |
|
|
273
|
+
| `MediaType` | tipado | `image/png`, `image/jpeg`, `image/webp` |
|
|
274
|
+
| `ResponseFormat` | tipado | Prefira bytes. URL de provedor expira — ver §Deprecações e `media-pipeline.md` |
|
|
275
|
+
| `StreamingCount` | tipado | Imagens parciais (0-3) para feedback de UI interna |
|
|
276
|
+
| `quality` | `AdditionalProperties` | `low`/`medium`/`high`/`auto`. **Não é tipado na 10.9.0** |
|
|
277
|
+
| `background` | `AdditionalProperties` | `transparent`/`opaque`/`auto`; exige PNG ou WebP |
|
|
278
|
+
| `moderation` | `AdditionalProperties` | `auto`/`low`. Bloqueio é `rejected_by_policy`, não erro técnico |
|
|
279
|
+
| `output_compression` | `AdditionalProperties` | 0-100, só JPEG/WebP |
|
|
280
|
+
| `mask` | só Images API direto | PNG com alfa, mesmas dimensões da primeira referência |
|
|
281
|
+
|
|
282
|
+
Nada em `AdditionalProperties` é validado em compilação. Um erro de digitação ali é um parâmetro que
|
|
283
|
+
o provedor ignora em silêncio — cubra com teste de contrato o mapa nome→valor que o seu adaptador
|
|
284
|
+
monta.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Custo por chamada
|
|
289
|
+
|
|
290
|
+
> **Toda a aritmética de dinheiro deste standard mora nesta seção, e em lugar nenhum mais.**
|
|
291
|
+
> Re-verificar preço é reabrir esta seção e §Deprecações — não reler o standard inteiro.
|
|
292
|
+
|
|
293
|
+
Preço de **lista pública**, em USD, sem desconto de contrato. Consultadas em **2026-09-07**:
|
|
294
|
+
`https://developers.openai.com/api/docs/pricing` e `https://ai.google.dev/gemini-api/docs/pricing`.
|
|
295
|
+
|
|
296
|
+
| Item | Preço | Origem |
|
|
297
|
+
|---|---|---|
|
|
298
|
+
| `gpt-image-2` — token de imagem de saída | $30,00 / 1M | OpenAI pricing (lista) |
|
|
299
|
+
| `gpt-image-2` — 1024², low / medium / high | ≈ $0,006 / $0,053 / $0,211 | **Estimativa de terceiro**, derivada da calculadora (`https://wavespeed.ai/blog/posts/gpt-image-2-pricing-2026/`). **Não é preço de lista** — a OpenAI publica por token |
|
|
300
|
+
| `gemini-3.1-flash-lite-image` | $0,0336 (Batch = Standard) | Gemini pricing |
|
|
301
|
+
| `gemini-3.1-flash-image` — 1K | $0,067 (Batch $0,034) | Gemini pricing |
|
|
302
|
+
| `gemini-3-pro-image` — 1K/2K | $0,134 (Batch $0,067) | Gemini pricing |
|
|
303
|
+
| Batch API (OpenAI e Google) | −50 % | páginas de pricing acima |
|
|
304
|
+
|
|
305
|
+
**A ressalva da segunda linha é parte do standard, não rodapé.** O preço por imagem do `gpt-image-2`
|
|
306
|
+
não tem fonte primária: a única tarifa oficial é por token. Um número derivado por terceiro serve
|
|
307
|
+
para dimensionar teto de orçamento, nunca para faturar cliente.
|
|
308
|
+
|
|
309
|
+
Três consequências de desenho, não de opinião:
|
|
310
|
+
|
|
311
|
+
1. **Escada de qualidade.** A diferença entre `low` e `high` na estimativa acima é de mais de 30×.
|
|
312
|
+
Candidatas em `low`; `high` só na aprovada.
|
|
313
|
+
2. **Batch para catálogo.** Metade do preço em lote é a maior alavanca isolada disponível. A decisão
|
|
314
|
+
Batch × Flex × síncrono já está escrita: `ai-agents/batching.md` e `ai-agents/service-tier-flex.md`.
|
|
315
|
+
3. **Custo estimado gravado ANTES da chamada**, e teto por tenant/dia em unidades (imagens ×
|
|
316
|
+
qualidade). O mecanismo está em `ai-agents/media-pipeline.md`; a tarifa está aqui.
|
|
317
|
+
|
|
318
|
+
Token de imagem de **entrada** (edição com referência) também é cobrado, e `input_fidelity: high`
|
|
319
|
+
nos modelos legados aumenta a fatura. Edição não é mais barata que geração por definição.
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Deprecações
|
|
324
|
+
|
|
325
|
+
> **Toda data de desligamento deste standard mora nesta seção, e em lugar nenhum mais.**
|
|
326
|
+
|
|
327
|
+
Fontes, consultadas em **2026-09-07**: `https://developers.openai.com/api/docs/deprecations` e
|
|
328
|
+
`https://ai.google.dev/gemini-api/docs/imagen` (mais o changelog em
|
|
329
|
+
`https://ai.google.dev/gemini-api/docs/changelog`).
|
|
330
|
+
|
|
331
|
+
| Alias | Situação | Data |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `gpt-image-1`, `gpt-image-1-mini`, `gpt-image-1.5`, `chatgpt-image-latest` | **desligam** (anunciado 2026-06-02) | 2026-12-01 |
|
|
334
|
+
| `dall-e-2`, `dall-e-3` | **desligados** | 2026-05-12 |
|
|
335
|
+
| `imagen-4.0-generate-001` e irmãos | **desligado** (anunciado 2026-06-15) | 2026-08-17 |
|
|
336
|
+
| `gemini-2.5-flash-image` | legado, migrar — sem data anunciada | — |
|
|
337
|
+
| `sora-2`, `sora-2-pro` (vídeo) | **desligam, sem substituto** | 2026-09-24 — ver `ai-agents/media-video.md` |
|
|
338
|
+
|
|
339
|
+
**Próximo desligamento conhecido: 2026-09-24.** Se esta data já passou quando você está lendo, este
|
|
340
|
+
standard não está apenas velho — ele está **errado**, e a §Como re-verificar diz em qual página
|
|
341
|
+
conferir. Uma data no passado nesta linha é falsificação em segundos, sem pesquisa.
|
|
342
|
+
|
|
343
|
+
O alias `dall-e` continua na busca do `STANDARDS.json` de propósito: quem procurar pelo modelo morto
|
|
344
|
+
tem de cair **aqui**, no lugar que diz que ele morreu.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Anti-patterns
|
|
349
|
+
|
|
350
|
+
| Anti-pattern | Por quê é errado | Jeito certo |
|
|
351
|
+
|---|---|---|
|
|
352
|
+
| Gerar imagem quando asset estático resolve | Custo e latência sem ganho | Sirva de CDN |
|
|
353
|
+
| **Gerar dentro do turno de conversa** | Latência de até 2 min, custo por mensagem, zero revisão | Enfileire e confirme (`media-pipeline.md`) |
|
|
354
|
+
| **Usar alias em lista de desligamento** | Dinheiro gasto num endpoint com data de morte | Confira §Deprecações antes de pinar |
|
|
355
|
+
| **Gravar a URL do provedor em vez dos bytes** | URL de provedor expira; o link quebra depois | Baixe, grave no blob próprio, guarde caminho + sha256 |
|
|
356
|
+
| **Gerar do zero quando o produto real existe** | Inventa material, medida ou cor que o produto não tem — claim visual falso | Edição com `OriginalImages` / `/v1/images/edits` |
|
|
357
|
+
| Não moderar o prompt antes de enviar | Erro 400 sem log útil e conteúdo impróprio | Valide antes; ver `ai-agents/middleware-patterns.md` |
|
|
358
|
+
| Criar `AIAgent` para geração de imagem | `IImageGenerator` não é `IChatClient` | Serviço enfileirado, não agente |
|
|
359
|
+
| Suprimir `MEAI001` sem comentário | Silencia o aviso e esconde o risco de breaking change | `#pragma` com o motivo escrito na linha |
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Checklist (verifiable by morph-eval)
|
|
364
|
+
|
|
365
|
+
- [ ] O alias escolhido **não** está na tabela de §Deprecações
|
|
366
|
+
- [ ] A chamada passa por `IImageGenerator` (ou adaptador próprio), sem acoplar o handler ao SDK
|
|
367
|
+
- [ ] `MEAI001` suprimido explicitamente, com comentário do risco na mesma linha
|
|
368
|
+
- [ ] Edição com referência usa `OriginalImages` / `/v1/images/edits` quando o produto real existe
|
|
369
|
+
- [ ] Prompt montado por template versionado, com a estrutura fixa e a "preserve list" repetida
|
|
370
|
+
- [ ] `quality` mínimo por finalidade — candidatas em `low`, `high` só na aprovada
|
|
371
|
+
- [ ] Custo estimado gravado **antes** da chamada, com a tarifa de §Custo por chamada
|
|
372
|
+
- [ ] Bytes gravados em blob próprio; nenhuma URL de provedor persistida como se fosse permanente
|
|
373
|
+
- [ ] Nenhuma geração dentro de um turno de conversa — o handler devolve id de job
|
|
374
|
+
- [ ] Nenhum teste toca API paga
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Como re-verificar este standard
|
|
379
|
+
|
|
380
|
+
Cinco páginas, cinco perguntas. Cabe numa sessão; é o custo que torna o corte de 90 dias cumprível
|
|
381
|
+
em vez de desativado por allowlist.
|
|
382
|
+
|
|
383
|
+
| Página | O que conferir |
|
|
384
|
+
|---|---|
|
|
385
|
+
| `https://developers.openai.com/api/docs/deprecations` | A tabela de §Deprecações inteira, e a linha "próximo desligamento conhecido" |
|
|
386
|
+
| `https://developers.openai.com/api/docs/pricing` | O preço por token de saída de imagem, e se apareceu preço por imagem oficial (hoje não há) |
|
|
387
|
+
| `https://ai.google.dev/gemini-api/docs/pricing` | As três linhas Gemini de §Custo por chamada |
|
|
388
|
+
| `https://ai.google.dev/gemini-api/docs/image-generation` | Limites de referência da §Referências de produto |
|
|
389
|
+
| `https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.ai.imagegenerationoptions` + `https://www.nuget.org/packages/Microsoft.Extensions.AI` | Se `quality`/`background` ganharam propriedade tipada, e se `MEAI001` saiu do experimental |
|
|
390
|
+
|
|
391
|
+
**E o exemplo, que é uma afirmação verificável, se re-verifica compilando — não lendo:**
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
node scripts/extract-doc-csharp.mjs \
|
|
395
|
+
framework/standards/ai-agents/modalities-image-gen.md \
|
|
396
|
+
"## Exemplo C# completo" /tmp/probe/Exemplo.cs
|
|
397
|
+
cd /tmp/probe && dotnet build # csproj com o pin + TreatWarningsAsErrors
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
O `TreatWarningsAsErrors` é obrigatório na sonda: sem ele `MEAI001` vira aviso e o build fica verde
|
|
401
|
+
sobre um exemplo que o consumidor **não** consegue compilar. Este bloco foi medido nos dois
|
|
402
|
+
cenários do pin — com e sem `Microsoft.Extensions.AI.OpenAI` — e sai `0 Aviso(s), 0 Erro(s)` nos
|
|
403
|
+
dois. Antes disso ele carregava três erros independentes, nenhum ligado ao pacote-ponte.
|
|
404
|
+
|
|
405
|
+
Ao terminar, atualize `Last-verified` **e** o `ai-pin` citado no header — re-datar sem re-verificar é
|
|
406
|
+
o defeito que `scripts/check-freshness.js` existe para impedir.
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## References
|
|
411
|
+
|
|
412
|
+
- `ai-agents/media-pipeline.md` — o job, a revisão humana, a marcação e a regra dura
|
|
413
|
+
- `ai-agents/media-video.md` — vídeo em runtime, e o desligamento da Sora
|
|
414
|
+
- `frontend/design-system/ai-image-generation.md` — autoria de asset de LP via MCP: prompt craft de
|
|
415
|
+
marca, `assets.md`, `next/image`. Consumidor diferente, tempo diferente
|
|
416
|
+
- `ai-agents/batching.md` · `ai-agents/service-tier-flex.md` — a decisão Batch × Flex × síncrono
|
|
417
|
+
- `ai-agents/providers/model-registry.md` — o alias por provedor
|
|
418
|
+
- `ai-agents/setup.md` — pacotes e DI
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
*MORPH-SPEC by Polymorphism Tech — ai-agents/modalities-image-gen.md v2.0*
|