@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.
Files changed (253) hide show
  1. package/CLAUDE.md +22 -2
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +43 -5
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +5 -4
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +2 -2
  8. package/framework/MORPH.md +20 -22
  9. package/framework/agents.json +198 -44
  10. package/framework/ai-pin.json +22 -0
  11. package/framework/commands/morph-media.md +45 -0
  12. package/framework/docs/CLI.md +238 -10
  13. package/framework/evals/proof-rubrics/README.md +76 -0
  14. package/framework/evals/proof-rubrics/eval-de-modelo.md +64 -0
  15. package/framework/evals/proof-rubrics/fiacao.md +54 -0
  16. package/framework/evals/proof-rubrics/guard-cego.md +52 -0
  17. package/framework/evals/proof-rubrics/media-claims.md +109 -0
  18. package/framework/evals/proof-rubrics/mutation-proof.md +77 -0
  19. package/framework/evals/proof-rubrics/observabilidade-genai.md +119 -0
  20. package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +48 -0
  21. package/framework/evals/rubrics/architecture.md +30 -0
  22. package/framework/evals/rubrics/code-quality.md +26 -0
  23. package/framework/evals/rubrics/test-coverage.md +20 -0
  24. package/framework/hooks/README.md +11 -1
  25. package/framework/hooks/claude-code/core/block-destructive-worktree-removal.js +5 -8
  26. package/framework/hooks/claude-code/core/block-raw-worktree-add.js +79 -0
  27. package/framework/hooks/claude-code/core/chain.js +27 -7
  28. package/framework/hooks/claude-code/core/protect-spec-files.js +41 -4
  29. package/framework/hooks/claude-code/core/worktree-context.js +83 -14
  30. package/framework/hooks/claude-code/core/worktree-create.js +206 -0
  31. package/framework/hooks/claude-code/core/worktree-env-inject.js +87 -0
  32. package/framework/hooks/claude-code/core/worktree-remove.js +81 -0
  33. package/framework/hooks/shared/command-tokens.js +23 -0
  34. package/framework/hooks/shared/e2e-check.js +0 -0
  35. package/framework/hooks/shared/git-paths.js +25 -0
  36. package/framework/hooks/shared/hook-response.js +17 -0
  37. package/framework/hooks/shared/morph-cli.js +134 -0
  38. package/framework/rules/ai-agents-standards.md +14 -2
  39. package/framework/rules/infrastructure-standards.md +3 -1
  40. package/framework/schemas/ai-pin.schema.json +97 -0
  41. package/framework/schemas/config.schema.json +107 -0
  42. package/framework/schemas/feature.schema.json +23 -4
  43. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  44. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  45. package/framework/skills/core/morph-apply/SKILL.md +28 -7
  46. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  47. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  48. package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
  49. package/framework/skills/core/morph-implement/SKILL.md +20 -2
  50. package/framework/skills/core/morph-media/SKILL.md +215 -0
  51. package/framework/skills/core/morph-plan/SKILL.md +38 -4
  52. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  53. package/framework/skills/core/morph-review/SKILL.md +166 -9
  54. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  55. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  56. package/framework/skills/core/morph-uiux/SKILL.md +1 -1
  57. package/framework/standards/PROVENANCE.json +81 -3
  58. package/framework/standards/STANDARDS.json +1504 -830
  59. package/framework/standards/ai-agents/agent-archetypes.md +160 -0
  60. package/framework/standards/ai-agents/agent-session.md +256 -160
  61. package/framework/standards/ai-agents/agent-spec.md +196 -0
  62. package/framework/standards/ai-agents/batching.md +217 -193
  63. package/framework/standards/ai-agents/context-providers.md +261 -188
  64. package/framework/standards/ai-agents/conversational-agent-with-phases.md +239 -0
  65. package/framework/standards/ai-agents/cost-and-budget.md +256 -0
  66. package/framework/standards/ai-agents/durable-workflows-hitl.md +98 -5
  67. package/framework/standards/ai-agents/evals-with-cache.md +289 -0
  68. package/framework/standards/ai-agents/guardrails.md +222 -0
  69. package/framework/standards/ai-agents/llm-runtime-defaults.md +226 -0
  70. package/framework/standards/ai-agents/mcp-server.md +351 -250
  71. package/framework/standards/ai-agents/mcp-tools.md +250 -197
  72. package/framework/standards/ai-agents/media-pipeline.md +352 -0
  73. package/framework/standards/ai-agents/media-video.md +267 -0
  74. package/framework/standards/ai-agents/middleware-patterns.md +241 -207
  75. package/framework/standards/ai-agents/modalities-image-gen.md +422 -173
  76. package/framework/standards/ai-agents/modalities-speech-to-text.md +177 -171
  77. package/framework/standards/ai-agents/modalities-text-to-speech.md +189 -181
  78. package/framework/standards/ai-agents/modalities-vision.md +205 -201
  79. package/framework/standards/ai-agents/multi-agent-patterns.md +211 -155
  80. package/framework/standards/ai-agents/observability-patterns.md +227 -17
  81. package/framework/standards/ai-agents/production.md +260 -231
  82. package/framework/standards/ai-agents/prompt-sources.md +389 -0
  83. package/framework/standards/ai-agents/providers/model-registry.md +293 -158
  84. package/framework/standards/ai-agents/rag-custom-pgvector.md +69 -4
  85. package/framework/standards/ai-agents/service-tier-flex.md +143 -135
  86. package/framework/standards/ai-agents/setup.md +166 -50
  87. package/framework/standards/ai-agents/structured-output.md +280 -249
  88. package/framework/standards/ai-agents/sweet-spot.md +129 -109
  89. package/framework/standards/ai-agents/testing-ai.md +236 -0
  90. package/framework/standards/ai-agents/vector-data-extensions.md +50 -20
  91. package/framework/standards/ai-agents/workflows.md +27 -7
  92. package/framework/standards/frontend/design-system/ai-image-generation.md +12 -0
  93. package/framework/standards/frontend/design-system/ai-video-generation.md +13 -0
  94. package/framework/standards/infrastructure/docker/local-compose-isolation.md +90 -0
  95. package/framework/templates/REGISTRY.json +14 -1
  96. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  97. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  98. package/framework/templates/dotnet/ai-kit/Directory.Build.props +25 -0
  99. package/framework/templates/dotnet/ai-kit/Directory.Packages.props +26 -0
  100. package/framework/templates/dotnet/ai-kit/Morph.AiKit.sln +56 -0
  101. package/framework/templates/dotnet/ai-kit/NuGet.config +12 -0
  102. package/framework/templates/dotnet/ai-kit/README.md +128 -0
  103. package/framework/templates/dotnet/ai-kit/global.json +9 -0
  104. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +65 -0
  105. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +289 -0
  106. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +91 -0
  107. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +91 -0
  108. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +181 -0
  109. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +14 -0
  110. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +174 -0
  111. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +54 -0
  112. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +75 -0
  113. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +71 -0
  114. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +246 -0
  115. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +57 -0
  116. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +78 -0
  117. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +225 -0
  118. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +463 -0
  119. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +32 -0
  120. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +49 -0
  121. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +214 -0
  122. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +168 -0
  123. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +142 -0
  124. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +349 -0
  125. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +42 -0
  126. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +77 -0
  127. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +28 -0
  128. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +107 -0
  129. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +253 -0
  130. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +103 -0
  131. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +259 -0
  132. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +21 -0
  133. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +47 -0
  134. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +102 -0
  135. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +44 -0
  136. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +192 -0
  137. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +94 -0
  138. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +99 -0
  139. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +97 -0
  140. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +133 -0
  141. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +93 -0
  142. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +112 -0
  143. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +288 -0
  144. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +158 -0
  145. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +29 -0
  146. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +208 -0
  147. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +95 -0
  148. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Morph.AiKit.csproj +38 -0
  149. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +119 -0
  150. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +82 -0
  151. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +33 -0
  152. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +267 -0
  153. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +474 -0
  154. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/model-registry.v2.json +87 -0
  155. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +169 -0
  156. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +49 -0
  157. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +495 -0
  158. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +260 -0
  159. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +405 -0
  160. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +379 -0
  161. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +197 -0
  162. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +139 -0
  163. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +157 -0
  164. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +178 -0
  165. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +153 -0
  166. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +194 -0
  167. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +86 -0
  168. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +213 -0
  169. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +95 -0
  170. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +225 -0
  171. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +215 -0
  172. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +33 -0
  173. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +89 -0
  174. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +55 -0
  175. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +60 -0
  176. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +131 -0
  177. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +133 -0
  178. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +127 -0
  179. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +216 -0
  180. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +264 -0
  181. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +148 -0
  182. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +184 -0
  183. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +89 -0
  184. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +98 -0
  185. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +451 -0
  186. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +76 -0
  187. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +33 -0
  188. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +261 -0
  189. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +374 -0
  190. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/.morph-eval-cache.json +12 -0
  191. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/contents.data +13 -0
  192. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/entry.json +7 -0
  193. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/contents.data +13 -0
  194. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/entry.json +7 -0
  195. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/contents.data +13 -0
  196. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/entry.json +7 -0
  197. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/contents.data +13 -0
  198. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/entry.json +7 -0
  199. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/orcamento/acme/a-resposta-estruturada.json +24 -0
  200. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/a-saudacao.json +23 -0
  201. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/b-escalonamento.json +24 -0
  202. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/globex/a-saudacao.json +23 -0
  203. package/framework/templates/infrastructure/docker/docker-compose.template.yml +24 -14
  204. package/package.json +3 -3
  205. package/src/commands/e2e/e2e.js +91 -40
  206. package/src/commands/project/doctor.js +143 -6
  207. package/src/commands/project/env.js +95 -0
  208. package/src/commands/project/update.js +469 -153
  209. package/src/commands/project/worktree.js +274 -53
  210. package/src/commands/state/advance.js +24 -2
  211. package/src/commands/state/approve.js +33 -1
  212. package/src/commands/state/create.js +72 -11
  213. package/src/commands/state/delete.js +8 -0
  214. package/src/commands/state/finish.js +360 -53
  215. package/src/commands/state/gate-check.js +190 -6
  216. package/src/commands/state/score.js +36 -1
  217. package/src/commands/validation/verify.js +134 -25
  218. package/src/core/state/state-manager.js +9 -1
  219. package/src/dashboard/app/pages/HookInspector.jsx +430 -418
  220. package/src/dashboard/scanner/hooks-scanner.js +5 -1
  221. package/src/lib/ai/ai-checks.js +182 -0
  222. package/src/lib/ai/ai-project-scan.js +347 -0
  223. package/src/lib/ai/code-audit.js +181 -0
  224. package/src/lib/ai/comment-stripper.js +184 -0
  225. package/src/lib/ai/pin-drift.js +138 -0
  226. package/src/lib/ai/registry-audit.js +285 -0
  227. package/src/lib/e2e/compose-env.js +55 -14
  228. package/src/lib/e2e/stack-teardown.js +115 -0
  229. package/src/lib/evaluator-report.js +269 -15
  230. package/src/lib/generators/architecture-scanner.js +2 -1
  231. package/src/lib/git/default-branch.js +92 -4
  232. package/src/lib/graph/graphifyignore.js +2 -1
  233. package/src/lib/installers/effects.js +193 -0
  234. package/src/lib/installers/templates-reconcile.js +3 -3
  235. package/src/lib/risk-detector.js +284 -0
  236. package/src/lib/standards/verified-against.js +276 -0
  237. package/src/lib/tasks/eval-node.js +485 -0
  238. package/src/lib/tasks/linux-runner.js +297 -0
  239. package/src/lib/tasks/test-nodes.js +486 -0
  240. package/src/lib/tasks/test-runner.js +431 -37
  241. package/src/lib/validators/verify-runner.js +590 -28
  242. package/src/lib/worktree/dirs.js +32 -0
  243. package/src/lib/worktree/docker-audit.js +287 -0
  244. package/src/lib/worktree/env-allocator.js +69 -11
  245. package/src/lib/worktree/worktree-audit.js +70 -3
  246. package/src/scripts/setup-infra.js +24 -11
  247. package/src/utils/agents-installer.js +18 -8
  248. package/src/utils/claude-md-injector.js +10 -5
  249. package/src/utils/file-copier.js +28 -16
  250. package/src/utils/hooks-installer.js +75 -29
  251. package/src/utils/skills-installer.js +194 -187
  252. package/src/utils/version-checker.js +68 -3
  253. package/framework/standards/ai-agents/prompts-in-db.md +0 -214
@@ -0,0 +1,267 @@
1
+ using Microsoft.Extensions.AI;
2
+ using Morph.AiKit.Agents;
3
+
4
+ namespace Morph.AiKit.Providers;
5
+
6
+ /// <summary>
7
+ /// Um alias do <c>model-registry.v2.json</c>: o apelido estavel que os agentes citam, com
8
+ /// tudo o que e preciso saber para alcancar o modelo e para contabilizar o que ele custa.
9
+ /// </summary>
10
+ /// <remarks>
11
+ /// <para>
12
+ /// Estende a forma de <c>templates/code/dotnet/ai-agents/ModelRegistry.cs.template</c>
13
+ /// (provider + model + options) com os dois campos que a issue #92 exige e que o template
14
+ /// v1 nao tinha: <see cref="Api"/> — o protocolo, por alias — e a decisao de tarifa
15
+ /// (<see cref="Pricing"/> ou <see cref="PricingWaiver"/>).
16
+ /// </para>
17
+ /// <para>
18
+ /// <b>Invariante do tipo:</b> ou existe <see cref="Pricing"/>, ou existe
19
+ /// <see cref="PricingWaiver"/> — nunca os dois, nunca nenhum. E o que impede
20
+ /// <c>cost_usd</c> de sair nulo la na frente: a ausencia de tarifa passa a ser uma decisao
21
+ /// escrita por alguem, com motivo, e nao um campo que ninguem preencheu.
22
+ /// <see cref="ValidatePricingDecision"/> e o guardiao dessa invariante e e chamado pelo
23
+ /// <see cref="ModelRegistry"/> em toda carga.
24
+ /// </para>
25
+ /// </remarks>
26
+ /// <param name="Provider">Familia de SDK: <c>openai</c>, <c>google</c>, <c>ollama</c>...</param>
27
+ /// <param name="Model">Id do modelo no provider.</param>
28
+ /// <param name="Api">Protocolo deste alias. Ver <see cref="AgentApi"/>.</param>
29
+ /// <param name="Pricing">Tarifa por 1M de tokens, ou nulo se houver <see cref="PricingWaiver"/>.</param>
30
+ /// <param name="Endpoint">Endpoint alternativo (Ollama, gateway). Nulo = o padrao do SDK.</param>
31
+ public sealed record ModelAlias(
32
+ string Provider,
33
+ string Model,
34
+ AgentApi Api,
35
+ ModelPricing? Pricing,
36
+ string? Endpoint)
37
+ {
38
+ /// <summary>A chave do alias no documento — <c>text-default</c>, <c>reasoning</c>...</summary>
39
+ public required string Name { get; init; }
40
+
41
+ /// <summary>
42
+ /// Motivo, por extenso, de este alias nao ter tarifa. Preenchido <b>somente</b> quando
43
+ /// <see cref="Pricing"/> e nulo. Exemplo real: modelo local, onde a conta e a maquina e
44
+ /// nao o token.
45
+ /// </summary>
46
+ public string? PricingWaiver { get; init; }
47
+
48
+ /// <summary>Limites conhecidos deste alias. Ver <see cref="ModelAliasConstraints"/>.</summary>
49
+ public ModelAliasConstraints Constraints { get; init; } = ModelAliasConstraints.None;
50
+
51
+ /// <summary>Se ha tarifa. Quando falso, <see cref="PricingWaiver"/> explica por que.</summary>
52
+ public bool HasPricing => Pricing is not null;
53
+
54
+ /// <summary>
55
+ /// A tarifa, ou uma falha que diz o nome do alias e o motivo declarado da ausencia.
56
+ /// Use quando o custo e obrigatorio; use <see cref="HasPricing"/> quando ausencia de
57
+ /// tarifa e um caminho previsto (e o caso do <c>UsageCostMiddleware</c>, que registra
58
+ /// tokens com custo zero e sinaliza a ausencia — nunca inventa tarifa).
59
+ /// </summary>
60
+ public ModelPricing RequirePricing()
61
+ => Pricing ?? throw ModelRegistryException.MissingPricing(Name, PricingWaiver);
62
+
63
+ /// <summary>
64
+ /// Cobra a invariante "tarifa OU dispensa, nunca ambas, nunca nenhuma".
65
+ /// </summary>
66
+ /// <exception cref="ModelRegistryException">Quando a decisao de tarifa nao foi tomada.</exception>
67
+ public static void ValidatePricingDecision(ModelAlias alias)
68
+ {
69
+ ArgumentNullException.ThrowIfNull(alias);
70
+
71
+ var hasWaiver = !string.IsNullOrWhiteSpace(alias.PricingWaiver);
72
+
73
+ if (alias.Pricing is null && !hasWaiver)
74
+ {
75
+ throw new ModelRegistryException(
76
+ $"alias '{alias.Name}': sem 'pricing' e sem 'pricingWaiver'. O custo em USD nao " +
77
+ "pode ser calculado nem declarado ausente, e um custo nulo silencioso e " +
78
+ "exatamente a dor que este registry existe para acabar. Declare a tarifa em " +
79
+ "'pricing' ou escreva o motivo em 'pricingWaiver'.");
80
+ }
81
+
82
+ if (alias.Pricing is not null && hasWaiver)
83
+ {
84
+ throw new ModelRegistryException(
85
+ $"alias '{alias.Name}': tem 'pricing' E 'pricingWaiver'. As duas coisas juntas " +
86
+ "nao dizem qual vale. Deixe exatamente uma.");
87
+ }
88
+ }
89
+
90
+ /// <summary>
91
+ /// Confronta uma requisicao com os limites declarados deste alias, <b>sem lancar</b> —
92
+ /// a decisao de abortar, avisar ou seguir e de quem chama (a <c>AgentFactory</c>).
93
+ /// </summary>
94
+ /// <param name="effectiveApi">
95
+ /// O protocolo que vai valer de fato: <c>spec.Api ?? alias.Api</c>. Veja
96
+ /// <see cref="AgentSpec.ResolveApi"/> — a precedencia mora la, nao aqui.
97
+ /// </param>
98
+ /// <param name="hasTools">Se a requisicao leva tools.</param>
99
+ /// <param name="reasoningEffort">
100
+ /// O esforco que sera enviado, ou nulo quando nada sera enviado. <b>Nulo nao e
101
+ /// violacao</b>: nesse caso vale o default do provider, e qual e ele o kit nao afirma
102
+ /// saber — modelar o contrario seria trocar um fato por folclore.
103
+ /// </param>
104
+ /// <param name="temperatureIsSet">Se a requisicao envia temperatura.</param>
105
+ public AliasRequestCheck CheckRequest(
106
+ AgentApi effectiveApi,
107
+ bool hasTools,
108
+ ReasoningEffort? reasoningEffort,
109
+ bool temperatureIsSet)
110
+ {
111
+ List<string>? violations = null;
112
+
113
+ if (Constraints.ToolCallingRequiresReasoningEffortNone
114
+ && effectiveApi == AgentApi.Chat
115
+ && hasTools
116
+ && reasoningEffort is { } effort
117
+ && effort != ReasoningEffort.None)
118
+ {
119
+ (violations ??= []).Add(
120
+ $"alias '{Name}': na Chat Completions este modelo nao suporta tool calling com " +
121
+ $"reasoning effort diferente de 'none' (pedido: '{effort}'). Use api 'responses', " +
122
+ $"envie reasoning effort 'none', ou tire as tools. Procedencia: {Constraints.Provenance}");
123
+ }
124
+
125
+ if (Constraints.TemperatureUnsupported && temperatureIsSet)
126
+ {
127
+ (violations ??= []).Add(
128
+ $"alias '{Name}': este modelo foi declarado sem suporte a temperatura. " +
129
+ $"Procedencia: {Constraints.Provenance}");
130
+ }
131
+
132
+ return violations is null
133
+ ? AliasRequestCheck.Satisfied
134
+ : new AliasRequestCheck(false, violations);
135
+ }
136
+ }
137
+
138
+ /// <summary>
139
+ /// Tarifa de um alias, em USD por 1 milhao de tokens. Vive junto do alias porque a conta
140
+ /// so faz sentido com a tarifa daquele modelo — e porque a matematica do custo, escrita
141
+ /// uma vez aqui, nao pode divergir entre o middleware (T11) e um relatorio qualquer.
142
+ /// </summary>
143
+ /// <param name="InputPerMTok">USD por 1M de tokens de entrada.</param>
144
+ /// <param name="OutputPerMTok">USD por 1M de tokens de saida.</param>
145
+ /// <param name="CachedInputPerMTok">
146
+ /// USD por 1M de tokens de entrada servidos do cache do provider. Nulo = <b>nao ha desconto
147
+ /// declarado</b>, e entao token cacheado e cobrado como entrada normal. Nulo NUNCA significa
148
+ /// "de graca": inventar desconto e tao errado quanto inventar tarifa.
149
+ /// </param>
150
+ public sealed record ModelPricing(
151
+ decimal InputPerMTok,
152
+ decimal OutputPerMTok,
153
+ decimal? CachedInputPerMTok)
154
+ {
155
+ /// <summary>Tokens a que a tarifa se refere: 1 milhao.</summary>
156
+ public const decimal TokensPerTariffUnit = 1_000_000m;
157
+
158
+ /// <summary>
159
+ /// Custo em USD de uma volta, a partir das contagens de token da resposta.
160
+ /// </summary>
161
+ /// <remarks>
162
+ /// <paramref name="cachedInputTokens"/> e um <b>subconjunto</b> de
163
+ /// <paramref name="inputTokens"/> — e assim que o provider reporta e assim que
164
+ /// <c>UsageDetails.CachedInputTokenCount</c> espelha. A parte cacheada so e cobrada a
165
+ /// parte quando <see cref="CachedInputPerMTok"/> existe; sem tarifa de cache, toda a
166
+ /// entrada e cobrada pela tarifa de entrada.
167
+ /// </remarks>
168
+ /// <exception cref="ArgumentOutOfRangeException">Contagem negativa.</exception>
169
+ /// <exception cref="ArgumentException">Tokens cacheados maiores que os de entrada.</exception>
170
+ public decimal ComputeCostUsd(long inputTokens, long outputTokens, long? cachedInputTokens = null)
171
+ {
172
+ ArgumentOutOfRangeException.ThrowIfNegative(inputTokens);
173
+ ArgumentOutOfRangeException.ThrowIfNegative(outputTokens);
174
+
175
+ if (cachedInputTokens is { } cached)
176
+ {
177
+ ArgumentOutOfRangeException.ThrowIfNegative(cached);
178
+
179
+ if (cached > inputTokens)
180
+ {
181
+ throw new ArgumentException(
182
+ $"tokens cacheados ({cached}) nao podem exceder os de entrada ({inputTokens}): " +
183
+ "o cacheado e um subconjunto da entrada, nao uma parcela a mais.",
184
+ nameof(cachedInputTokens));
185
+ }
186
+ }
187
+
188
+ var cachedCount = CachedInputPerMTok is null ? 0L : cachedInputTokens ?? 0L;
189
+ var fullPriceInput = inputTokens - cachedCount;
190
+
191
+ var cost = (fullPriceInput * InputPerMTok)
192
+ + (cachedCount * (CachedInputPerMTok ?? InputPerMTok))
193
+ + (outputTokens * OutputPerMTok);
194
+
195
+ return cost / TokensPerTariffUnit;
196
+ }
197
+ }
198
+
199
+ /// <summary>
200
+ /// Limites conhecidos de um alias. <b>Por alias, com procedencia escrita</b> — nunca uma
201
+ /// regra universal chumbada no codigo.
202
+ /// </summary>
203
+ /// <remarks>
204
+ /// A diferenca importa: "modelo de raciocinio rejeita tool" e folclore; o que a
205
+ /// documentacao diz e mais estreito e cabe num campo. Um limite sem
206
+ /// <see cref="Provenance"/> e recusado na carga do registry, justamente para que ninguem
207
+ /// consiga gravar um "todo mundo sabe que" sem dizer de onde tirou.
208
+ /// </remarks>
209
+ public sealed record ModelAliasConstraints
210
+ {
211
+ /// <summary>Nenhum limite declarado.</summary>
212
+ public static readonly ModelAliasConstraints None = new();
213
+
214
+ /// <summary>
215
+ /// Na <b>Chat Completions</b>, este modelo so aceita tool calling com reasoning effort
216
+ /// <c>none</c>. E o limite exato descrito pela documentacao — mais estreito que
217
+ /// "modelo de raciocinio nao aceita tool" — e por isso e verificado com os quatro fatos
218
+ /// juntos em <see cref="ModelAlias.CheckRequest"/>: protocolo Chat, tools presentes,
219
+ /// effort enviado, e effort diferente de <c>none</c>.
220
+ /// </summary>
221
+ public bool ToolCallingRequiresReasoningEffortNone { get; init; }
222
+
223
+ /// <summary>
224
+ /// Este modelo nao aceita <c>temperature</c>.
225
+ /// <b>Existe como flag por alias exatamente porque a afirmacao generica
226
+ /// ("temperatura e obsoleta para modelos de raciocinio") NAO foi confirmada em fonte
227
+ /// primaria.</b> Quem ligar isto assume a afirmacao para um modelo especifico e escreve
228
+ /// de onde tirou em <see cref="Provenance"/>.
229
+ /// </summary>
230
+ public bool TemperatureUnsupported { get; init; }
231
+
232
+ /// <summary>
233
+ /// De onde veio o limite: documento, data, citacao. Obrigatorio quando qualquer flag
234
+ /// esta ligada.
235
+ /// </summary>
236
+ public string? Provenance { get; init; }
237
+
238
+ /// <summary>Se ha qualquer limite declarado.</summary>
239
+ public bool AnyFlagSet => ToolCallingRequiresReasoningEffortNone || TemperatureUnsupported;
240
+
241
+ /// <summary>
242
+ /// Cobra "limite ligado exige procedencia".
243
+ /// </summary>
244
+ /// <exception cref="ModelRegistryException">Flag ligada sem procedencia.</exception>
245
+ public void ValidateProvenance(string aliasName)
246
+ {
247
+ if (AnyFlagSet && string.IsNullOrWhiteSpace(Provenance))
248
+ {
249
+ throw new ModelRegistryException(
250
+ $"alias '{aliasName}': ha limite declarado em 'constraints' sem 'provenance'. " +
251
+ "Um limite sem fonte e folclore com forca de codigo — escreva o documento e a " +
252
+ "data de onde ele saiu.");
253
+ }
254
+ }
255
+ }
256
+
257
+ /// <summary>
258
+ /// Resultado de <see cref="ModelAlias.CheckRequest"/>. Result, nao excecao: um limite
259
+ /// violado e informacao para quem chama decidir, nao fluxo de controle.
260
+ /// </summary>
261
+ /// <param name="IsSatisfied">Se a requisicao respeita todos os limites do alias.</param>
262
+ /// <param name="Violations">Uma frase por limite violado, ja com a procedencia.</param>
263
+ public sealed record AliasRequestCheck(bool IsSatisfied, IReadOnlyList<string> Violations)
264
+ {
265
+ /// <summary>Nenhuma violacao.</summary>
266
+ public static readonly AliasRequestCheck Satisfied = new(true, []);
267
+ }