@polymorphism-tech/morph-spec 8.37.1 → 8.40.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 (317) hide show
  1. package/CLAUDE.md +37 -13
  2. package/README.md +2 -2
  3. package/bin/morph-spec.js +75 -49
  4. package/claude-plugin.json +1 -1
  5. package/docs/CHEATSHEET.md +1 -1
  6. package/docs/QUICKSTART.md +1 -1
  7. package/framework/CLAUDE.md +6 -5
  8. package/framework/MORPH.md +25 -22
  9. package/framework/agents.json +96 -36
  10. package/framework/docs/CLI.md +54 -17
  11. package/framework/evals/rubrics/code-quality.md +5 -0
  12. package/framework/evals/rubrics/condensed.md +6 -2
  13. package/framework/evals/rubrics/contracts.md +20 -0
  14. package/framework/evals/rubrics/test-coverage.md +17 -6
  15. package/framework/hooks/README.md +9 -3
  16. package/framework/hooks/claude-code/core/graph-refresh-kick.js +52 -0
  17. package/framework/hooks/claude-code/core/telemetry-log.js +172 -87
  18. package/framework/hooks/claude-code/core/validate-completion.js +16 -90
  19. package/framework/hooks/claude-code/core/worktree-context.js +10 -0
  20. package/framework/hooks/shared/command-tokens.js +96 -0
  21. package/framework/hooks/shared/git-exclude.js +44 -0
  22. package/framework/hooks/shared/git-paths.js +52 -0
  23. package/framework/hooks/shared/graph-freshness.js +380 -0
  24. package/framework/hooks/shared/graph-refresh.js +416 -0
  25. package/framework/hooks/shared/morph-cli.js +17 -5
  26. package/framework/hooks/shared/redact-secrets.js +55 -0
  27. package/framework/hooks/shared/telemetry-logger.js +25 -2
  28. package/framework/hooks/shared/transcript-usage.js +80 -0
  29. package/framework/mcp/registry.json +33 -2
  30. package/framework/rubrics/backend.json +2 -2
  31. package/framework/rubrics/default.json +2 -2
  32. package/framework/rubrics/frontend.json +2 -2
  33. package/framework/rules/csharp-standards.md +1 -0
  34. package/framework/rules/infrastructure-standards.md +0 -1
  35. package/framework/rules/morph-workflow.md +10 -4
  36. package/framework/rules/nextjs-standards.md +1 -0
  37. package/framework/schemas/config.schema.json +41 -1
  38. package/framework/schemas/feature.schema.json +5 -1
  39. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  40. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  41. package/framework/skills/core/morph-apply/SKILL.md +40 -11
  42. package/framework/skills/core/morph-brainstorming/SKILL.md +16 -7
  43. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  44. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  45. package/framework/skills/core/morph-implement/SKILL.md +44 -10
  46. package/framework/skills/core/morph-media/SKILL.md +1 -1
  47. package/framework/skills/core/morph-plan/SKILL.md +73 -15
  48. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  49. package/framework/skills/core/morph-review/SKILL.md +51 -13
  50. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  51. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  52. package/framework/skills/core/morph-uiux/SKILL.md +39 -13
  53. package/framework/standards/STANDARDS.json +189 -14
  54. package/framework/standards/ai-agents/context-providers.md +16 -26
  55. package/framework/standards/ai-agents/durable-workflows-hitl.md +15 -21
  56. package/framework/standards/ai-agents/modalities-image-gen.md +21 -25
  57. package/framework/standards/ai-agents/modalities-speech-to-text.md +4 -15
  58. package/framework/standards/ai-agents/modalities-text-to-speech.md +2 -11
  59. package/framework/standards/ai-agents/modalities-vision.md +1 -18
  60. package/framework/standards/ai-agents/prompt-sources.md +0 -4
  61. package/framework/standards/ai-agents/testing-ai.md +2 -1
  62. package/framework/standards/architecture/code-comments.md +100 -0
  63. package/framework/standards/backend/dotnet/testing.md +22 -0
  64. package/framework/standards/backend/integrations/neon-auth/neon-auth.md +63 -50
  65. package/framework/standards/frontend/admin-app/data-table.md +562 -0
  66. package/framework/standards/frontend/admin-app/feedback.md +236 -0
  67. package/framework/standards/frontend/admin-app/forms.md +232 -0
  68. package/framework/standards/frontend/admin-app/page-structure.md +203 -0
  69. package/framework/standards/frontend/design-system/ai-image-generation.md +5 -5
  70. package/framework/standards/frontend/nextjs/components.md +37 -58
  71. package/framework/standards/frontend/nextjs/data-fetching.md +1 -0
  72. package/framework/standards/frontend/nextjs/forms.md +31 -30
  73. package/framework/standards/frontend/nextjs/state-management.md +2 -1
  74. package/framework/standards/frontend/nextjs/testing.md +18 -0
  75. package/framework/standards/integration/mcp/mcp-tools.md +48 -117
  76. package/framework/templates/code/dotnet/abstractions/result.cs +0 -2
  77. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +26 -39
  78. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +28 -68
  79. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +99 -117
  80. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +2 -44
  81. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +40 -61
  82. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +54 -107
  83. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +53 -58
  84. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +192 -281
  85. package/framework/templates/code/dotnet/database/migration.cs +49 -83
  86. package/framework/templates/code/dotnet/database/vector-entity.cs +2 -46
  87. package/framework/templates/code/dotnet/extensions/result-extensions.cs +0 -2
  88. package/framework/templates/code/dotnet/feature/validator.cs.hbs +11 -15
  89. package/framework/templates/code/dotnet/jobs/agent.cs +3 -51
  90. package/framework/templates/code/dotnet/jobs/job.cs +2 -97
  91. package/framework/templates/code/dotnet/test.cs +2 -87
  92. package/framework/templates/code/typescript/contracts.ts +140 -167
  93. package/framework/templates/context/design-system.md +3 -3
  94. package/framework/templates/docs/proposal.md +11 -0
  95. package/framework/templates/docs/spec.md +15 -0
  96. package/framework/templates/docs/ui-mockups.md +115 -98
  97. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +1 -48
  98. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +3 -79
  99. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +1 -70
  100. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +1 -47
  101. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +2 -99
  102. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +0 -6
  103. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +3 -88
  104. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +1 -41
  105. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +0 -21
  106. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +1 -25
  107. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +2 -63
  108. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +0 -30
  109. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +1 -52
  110. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +3 -78
  111. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +4 -109
  112. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +0 -22
  113. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +1 -36
  114. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +2 -57
  115. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +0 -75
  116. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +2 -59
  117. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +4 -111
  118. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +0 -34
  119. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +1 -57
  120. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +0 -19
  121. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +2 -74
  122. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +2 -33
  123. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +1 -43
  124. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +1 -96
  125. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +0 -13
  126. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +0 -27
  127. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +0 -33
  128. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +0 -31
  129. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +3 -75
  130. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +0 -42
  131. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +0 -39
  132. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +1 -55
  133. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +3 -59
  134. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +0 -46
  135. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +3 -28
  136. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +7 -61
  137. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +2 -37
  138. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +1 -23
  139. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +2 -82
  140. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +1 -68
  141. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +1 -62
  142. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +2 -62
  143. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +1 -25
  144. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +0 -124
  145. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +1 -73
  146. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +1 -66
  147. package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +0 -41
  148. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +2 -112
  149. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +2 -43
  150. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +5 -110
  151. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +7 -103
  152. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +1 -42
  153. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +1 -30
  154. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +1 -19
  155. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +0 -48
  156. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +1 -29
  157. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +2 -38
  158. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +1 -14
  159. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +4 -69
  160. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +1 -10
  161. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +1 -57
  162. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +0 -26
  163. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +1 -19
  164. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +0 -32
  165. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +0 -14
  166. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +0 -24
  167. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +0 -32
  168. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +0 -37
  169. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +0 -24
  170. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +0 -78
  171. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +0 -53
  172. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +0 -44
  173. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +0 -44
  174. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +0 -19
  175. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +0 -24
  176. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +6 -48
  177. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +1 -13
  178. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +2 -71
  179. package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +5 -100
  180. package/framework/templates/feature/decisions.md +124 -122
  181. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +39 -43
  182. package/framework/templates/frontend/nextjs/env.mjs.hbs +29 -32
  183. package/framework/templates/frontend/nextjs/page.tsx.hbs +21 -22
  184. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +42 -54
  185. package/framework/templates/integrations/asaas-client.cs +332 -387
  186. package/framework/templates/integrations/asaas-webhook.cs +290 -351
  187. package/framework/templates/integrations/neon-auth-config.cs +9 -105
  188. package/framework/templates/project/validate.js +97 -120
  189. package/package.json +2 -2
  190. package/src/commands/dashboard/dashboard.js +80 -53
  191. package/src/commands/graph/affected.js +4 -3
  192. package/src/commands/graph/build.js +109 -18
  193. package/src/commands/graph/explain.js +8 -5
  194. package/src/commands/graph/status.js +14 -8
  195. package/src/commands/mcp/mcp-setup.js +37 -9
  196. package/src/commands/observability/cost.js +148 -18
  197. package/src/commands/project/doctor.js +85 -15
  198. package/src/commands/project/init.js +6 -3
  199. package/src/commands/project/install-plugin-cmd.js +1 -1
  200. package/src/commands/project/update.js +30 -0
  201. package/src/commands/project/worktree.js +73 -90
  202. package/src/commands/state/advance.js +18 -0
  203. package/src/commands/state/approve.js +15 -0
  204. package/src/commands/state/archive.js +62 -9
  205. package/src/commands/state/finish.js +62 -14
  206. package/src/commands/state/gate-check.js +8 -1
  207. package/src/commands/state/gate-decision.js +8 -4
  208. package/src/commands/state/report-check.js +90 -9
  209. package/src/commands/state/usecase.js +66 -0
  210. package/src/commands/tasks/dag.js +17 -2
  211. package/src/commands/validation/validate-feature.js +6 -1
  212. package/src/commands/validation/verify.js +20 -1
  213. package/src/dashboard/app/App.jsx +80 -16
  214. package/src/dashboard/app/components/ActivityFeed.jsx +172 -0
  215. package/src/dashboard/app/components/CommandPalette.jsx +155 -0
  216. package/src/dashboard/app/components/DetailPanel.jsx +47 -11
  217. package/src/dashboard/app/components/EntityLink.jsx +55 -0
  218. package/src/dashboard/app/components/ErrorBoundary.jsx +54 -0
  219. package/src/dashboard/app/components/FlowGraph.jsx +19 -17
  220. package/src/dashboard/app/components/KnowledgeMarkdown.jsx +53 -0
  221. package/src/dashboard/app/components/Markdown.jsx +47 -0
  222. package/src/dashboard/app/components/PhaseRail.jsx +111 -0
  223. package/src/dashboard/app/components/SearchFilter.jsx +40 -22
  224. package/src/dashboard/app/components/Sidebar.jsx +146 -37
  225. package/src/dashboard/app/hooks/useMorphQuery.js +54 -0
  226. package/src/dashboard/app/hooks/usePref.js +38 -0
  227. package/src/dashboard/app/lib/format.js +69 -0
  228. package/src/dashboard/app/lib/phases.js +56 -0
  229. package/src/dashboard/app/lib/project.js +50 -0
  230. package/src/dashboard/app/pages/Activity.jsx +24 -0
  231. package/src/dashboard/app/pages/AgentMap.jsx +371 -370
  232. package/src/dashboard/app/pages/FeatureDetail.jsx +604 -0
  233. package/src/dashboard/app/pages/Features.jsx +400 -0
  234. package/src/dashboard/app/pages/Guide.jsx +146 -0
  235. package/src/dashboard/app/pages/HookInspector.jsx +357 -322
  236. package/src/dashboard/app/pages/PhasePipeline.jsx +277 -408
  237. package/src/dashboard/app/pages/Portfolio.jsx +156 -0
  238. package/src/dashboard/app/pages/Rubrics.jsx +101 -0
  239. package/src/dashboard/app/pages/RulesMap.jsx +300 -273
  240. package/src/dashboard/app/pages/SkillsLibrary.jsx +483 -366
  241. package/src/dashboard/app/pages/Standards.jsx +407 -332
  242. package/src/dashboard/app/styles/index.css +187 -47
  243. package/src/dashboard/index.html +14 -12
  244. package/src/dashboard/package.json +32 -24
  245. package/src/dashboard/scanner/activity-scanner.js +351 -0
  246. package/src/dashboard/scanner/agents-scanner.js +63 -1
  247. package/src/dashboard/scanner/docs-scanner.js +59 -0
  248. package/src/dashboard/scanner/feature-status.js +10 -0
  249. package/src/dashboard/scanner/features-scanner.js +360 -0
  250. package/src/dashboard/scanner/hooks-scanner.js +8 -1
  251. package/src/dashboard/scanner/index.js +14 -7
  252. package/src/dashboard/scanner/phases-scanner.js +14 -15
  253. package/src/dashboard/scanner/portfolio.js +153 -0
  254. package/src/dashboard/scanner/project-api.js +195 -0
  255. package/src/dashboard/scanner/rules-scanner.js +42 -37
  256. package/src/dashboard/scanner/skills-scanner.js +105 -43
  257. package/src/dashboard/scanner/standards-scanner.js +4 -1
  258. package/src/dashboard/vite-plugin-morph-data.js +134 -17
  259. package/src/lib/ai/comment-stripper.js +101 -4
  260. package/src/lib/detectors/claude-config-detector.js +2 -7
  261. package/src/lib/detectors/index.js +5 -1
  262. package/src/lib/evaluator-report.js +47 -0
  263. package/src/lib/generators/handoff-generator.js +4 -18
  264. package/src/lib/generators/settings-generator.js +208 -209
  265. package/src/lib/git/default-branch.js +52 -0
  266. package/src/lib/git/tree-fingerprint.js +58 -0
  267. package/src/lib/git/tree-state.js +167 -0
  268. package/src/lib/graph/god-nodes.js +12 -3
  269. package/src/lib/graph/graph-health.js +48 -2
  270. package/src/lib/graph/graph-loader.js +99 -25
  271. package/src/lib/graph/graphifyignore.js +145 -28
  272. package/src/lib/graph/sanitize.js +117 -11
  273. package/src/lib/installers/mcp-installer.js +724 -719
  274. package/src/lib/installers/memory-installer.js +1 -2
  275. package/src/lib/projects/registry.js +154 -0
  276. package/src/lib/risk-detector.js +90 -0
  277. package/src/lib/specs/acervo-format.js +70 -0
  278. package/src/lib/specs/acervo-lifecycle.js +264 -0
  279. package/src/lib/specs/adr-index.js +169 -0
  280. package/src/lib/specs/revocations.js +156 -0
  281. package/src/lib/specs/screen-checklist.js +357 -0
  282. package/src/lib/specs/usecase-check.js +20 -16
  283. package/src/lib/specs/usecase-promoter.js +103 -38
  284. package/src/lib/specs/usecase-registry.js +7 -7
  285. package/src/lib/tasks/tasks-json-parser.js +2 -3
  286. package/src/lib/telemetry/metrics.js +386 -0
  287. package/src/lib/telemetry/telemetry-reader.js +161 -51
  288. package/src/lib/telemetry/verify-event.js +79 -0
  289. package/src/lib/validators/code-budget/code-budget-validator.js +200 -0
  290. package/src/lib/validators/code-budget/comment-scanner.js +75 -0
  291. package/src/lib/validators/code-budget/index.js +9 -0
  292. package/src/lib/validators/reuse/reuse-validator.js +4 -2
  293. package/src/lib/validators/reuse/symbol-scanner.js +27 -22
  294. package/src/lib/validators/validation-runner.js +21 -5
  295. package/src/lib/validators/verify-runner.js +11 -0
  296. package/src/lib/worktree/finish-backup.js +739 -0
  297. package/src/lib/worktree/ignored-triage.js +15 -8
  298. package/src/lib/worktree/worktree-audit.js +5 -0
  299. package/src/scripts/install-plugin.js +1 -1
  300. package/src/scripts/setup-infra.js +31 -22
  301. package/src/utils/agents-installer.js +338 -24
  302. package/src/utils/banner.js +1 -1
  303. package/src/utils/hooks-installer.js +75 -15
  304. package/src/commands/index.js +0 -13
  305. package/src/commands/project/checkpoint.js +0 -209
  306. package/src/core/state/phase-state-machine.js +0 -197
  307. package/src/dashboard/app/hooks/useDetailPanel.js +0 -15
  308. package/src/dashboard/app/pages/LiveState.jsx +0 -206
  309. package/src/dashboard/scanner/squads-scanner.js +0 -13
  310. package/src/dashboard/scanner/state-scanner.js +0 -85
  311. package/src/lib/generators/index.js +0 -10
  312. package/src/lib/hooks/hook-executor.js +0 -167
  313. package/src/lib/validators/checkpoint-persistence.js +0 -39
  314. package/src/lib/validators/shared/emit-validator-dispatch.js +0 -14
  315. package/src/lib/validators/shared/index.js +0 -12
  316. package/src/lib/validators/shared/issue-counter.js +0 -14
  317. package/src/lib/validators/shared/result-formatter.js +0 -124
@@ -1,98 +1,115 @@
1
- # UI Mockups & Wireframes: {{titleCase FEATURE_NAME}}
2
-
3
- | Field | Value |
4
- |-------|-------|
5
- | **Feature** | {{FEATURE_NAME}} |
6
- | **Created** | {{DATE}} |
7
-
8
- ---
9
-
10
- ## Screen Inventory
11
-
12
- | Screen ID | Name | Route | Priority |
13
- |-----------|------|-------|----------|
14
- | **S001** | {Screen Name} | /path | High |
15
- | **S002** | {Screen Name} | /path | Medium |
16
-
17
- ---
18
-
19
- ## S001: {Primary Screen}
20
-
21
- ### Desktop Layout
22
-
23
- ```
24
- ┌─────────────────────────────────────┐
25
- │ Header [User ▼] │
26
- ├─────────────────────────────────────┤
27
- │ │
28
- │ [Title] │
29
- │ │
30
- │ ┌──────────────────────────────┐ │
31
- │ │ Main Content Area │ │
32
- │ │ │ │
33
- │ │ [Card 1] [Card 2] │ │
34
- │ │ │ │
35
- │ │ ┌────────────────────────┐ │ │
36
- │ │ │ Data Table │ │ │
37
- │ │ │ ... │ │ │
38
- │ │ └────────────────────────┘ │ │
39
- │ └──────────────────────────────┘ │
40
- │ │
41
- └─────────────────────────────────────┘
42
- ```
43
-
44
- ### Mobile Layout
45
-
46
- ```
47
- ┌──────────────────────┐
48
- │ ☰ Title [User ▼]│
49
- ├──────────────────────┤
50
- │ │
51
- │ [Card 1] │
52
- │ │
53
- │ [Card 2] │
54
- │ │
55
- │ [View All Items] │
56
- │ │
57
- └──────────────────────┘
58
- ```
59
-
60
- ---
61
-
62
- ## States
63
-
64
- ### Loading
65
- - Show skeleton placeholders
66
- - Spinner for primary content
67
-
68
- ### Empty
69
- - Icon + message
70
- - Clear call-to-action button
71
-
72
- ### Error
73
- - Warning icon
74
- - User-friendly message
75
- - Retry button
76
-
77
- ### Success (After Action)
78
- - Toast notification
79
- - Auto-dismiss after 3s
80
-
81
- ---
82
-
83
- ## Interactions
84
-
85
- - **Hover**: Subtle elevation increase
86
- - **Click**: Scale down (0.98)
87
- - **Transitions**: Fade-in 200ms
88
-
89
- ---
90
-
91
- ## Accessibility
92
- - [ ] 44x44px minimum touch targets
93
- - [ ] Focus indicators visible
94
- - [ ] Proper heading hierarchy (H1 → H2 → H3)
95
-
96
- ---
97
-
98
- *Generated with MORPH Framework*
1
+ # UI Mockups & Wireframes: {{titleCase FEATURE_NAME}}
2
+
3
+ | Field | Value |
4
+ |-------|-------|
5
+ | **Feature** | {{FEATURE_NAME}} |
6
+ | **Created** | {{DATE}} |
7
+
8
+ ---
9
+
10
+ ## Screen Inventory
11
+
12
+ | Screen ID | Name | Route | Priority |
13
+ |-----------|------|-------|----------|
14
+ | **S001** | {Screen Name} | /path | High |
15
+ | **S002** | {Screen Name} | /path | Medium |
16
+
17
+ ---
18
+
19
+ ## Tela: {Primary Screen}
20
+
21
+ ### Desktop Layout
22
+
23
+ ```
24
+ ┌─────────────────────────────────────┐
25
+ │ Header [User ▼] │
26
+ ├─────────────────────────────────────┤
27
+ │ │
28
+ │ [Title] │
29
+ │ │
30
+ │ ┌──────────────────────────────┐ │
31
+ │ │ Main Content Area │ │
32
+ │ │ │ │
33
+ │ │ [Card 1] [Card 2] │ │
34
+ │ │ │ │
35
+ │ │ ┌────────────────────────┐ │ │
36
+ │ │ │ Data Table │ │ │
37
+ │ │ │ ... │ │ │
38
+ │ │ └────────────────────────┘ │ │
39
+ │ └──────────────────────────────┘ │
40
+ │ │
41
+ └─────────────────────────────────────┘
42
+ ```
43
+
44
+ ### Mobile Layout
45
+
46
+ ```
47
+ ┌──────────────────────┐
48
+ │ ☰ Title [User ▼]│
49
+ ├──────────────────────┤
50
+ │ │
51
+ │ [Card 1] │
52
+ │ │
53
+ │ [Card 2] │
54
+ │ │
55
+ │ [View All Items] │
56
+ │ │
57
+ └──────────────────────┘
58
+ ```
59
+
60
+ ### Checklist de tela
61
+
62
+ Troque cada `…` pela decisão — "não se aplica" vale se escrito; `…`, vazio ou "a definir" reprovam o Gate uiux.
63
+
64
+ | Item | Decisão |
65
+ |---|---|
66
+ | Superfície | … |
67
+ | Volume esperado | … |
68
+ | Paginação | … |
69
+ | Ordenação | … |
70
+ | Filtro | … |
71
+ | Estado vazio | … |
72
+ | Estado carregando | … |
73
+ | Estado de erro | … |
74
+ | Mobile | … |
75
+ | Abas | … |
76
+
77
+ ---
78
+
79
+ ## States
80
+
81
+ ### Loading
82
+ - Show skeleton placeholders
83
+ - Spinner for primary content
84
+
85
+ ### Empty
86
+ - Icon + message
87
+ - Clear call-to-action button
88
+
89
+ ### Error
90
+ - Warning icon
91
+ - User-friendly message
92
+ - Retry button
93
+
94
+ ### Success (After Action)
95
+ - Toast notification
96
+ - Auto-dismiss after 3s
97
+
98
+ ---
99
+
100
+ ## Interactions
101
+
102
+ - **Hover**: Subtle elevation increase
103
+ - **Click**: Scale down (0.98)
104
+ - **Transitions**: Fade-in 200ms
105
+
106
+ ---
107
+
108
+ ## Accessibility
109
+ - [ ] 44x44px minimum touch targets
110
+ - [ ] Focus indicators visible
111
+ - [ ] Proper heading hierarchy (H1 → H2 → H3)
112
+
113
+ ---
114
+
115
+ *Generated with MORPH Framework*
@@ -1,65 +1,18 @@
1
1
  namespace Morph.AiKit.Agents;
2
2
 
3
- /// <summary>
4
- /// Protocolo pelo qual um modelo e alcancado. E o campo <c>api:</c> por alias que a
5
- /// issue #92 exige: a MESMA familia de modelos e atendida por dois protocolos
6
- /// diferentes, e qual deles vale e decisao de configuracao — nunca folclore espalhado
7
- /// por condicional no meio do codigo.
8
- /// </summary>
9
- /// <remarks>
10
- /// <para>
11
- /// <see cref="Responses"/> e <b>0 de proposito</b>: <c>default(AgentApi)</c> e a Responses
12
- /// API porque essa e a decisao da casa (Responses por padrao, Chat Completions como
13
- /// opt-in explicito por alias). Um alias que omite <c>api:</c> no
14
- /// <c>model-registry.v2.json</c> cai em Responses; usar Chat Completions exige escrever
15
- /// <c>"api": "chat"</c> — ou seja, exige alguem assumir a escolha por escrito.
16
- /// </para>
17
- /// <para>
18
- /// O enum descreve a escolha ENTRE OS DOIS PROTOCOLOS DA OpenAI. Provider que expoe um
19
- /// unico protocolo (Google, Ollama) ignora o campo, e por isso declara — ou omite,
20
- /// caindo em — <see cref="Responses"/>: escrever <c>chat</c> ali sugeriria uma escolha
21
- /// que naquele provider nao existe.
22
- /// </para>
23
- /// </remarks>
24
3
  public enum AgentApi
25
4
  {
26
- /// <summary>Responses API — o padrao da casa. Valor 0, logo <c>default(AgentApi)</c>.</summary>
5
+ // 0 de proposito: default(AgentApi) e alias sem 'api:' caem em Responses; Chat e opt-in escrito.
27
6
  Responses = 0,
28
7
 
29
- /// <summary>
30
- /// Chat Completions — opt-in explicito por alias. Carrega limites que a Responses API
31
- /// nao tem; ver <c>Morph.AiKit.Providers.ModelAliasConstraints</c>.
32
- /// </summary>
33
8
  Chat = 1,
34
9
 
35
- /// <summary>
36
- /// Images — geracao/edicao de imagem. <b>Nao e um protocolo de conversa</b>: um alias
37
- /// com este <c>api</c> e recusado pela <c>AgentFactory</c>, com erro nomeado.
38
- /// </summary>
39
- /// <remarks>
40
- /// Um registry so, um vocabulario so de alias: quem procura "qual modelo este projeto
41
- /// usa" encontra o de imagem no mesmo lugar que o de chat. A alternativa era um
42
- /// <c>media-registry.json</c> separado — duas verdades sobre o mesmo fato.
43
- /// </remarks>
44
10
  Images = 2,
45
11
 
46
- /// <summary>
47
- /// Videos — geracao de video. Mesma regra de <see cref="Images"/>: alias de midia nao
48
- /// vira agente.
49
- /// </summary>
50
12
  Videos = 3,
51
13
  }
52
14
 
53
- /// <summary>Predicados sobre <see cref="AgentApi"/>.</summary>
54
15
  public static class AgentApiExtensions
55
16
  {
56
- /// <summary>
57
- /// Se o protocolo e de MIDIA (imagem ou video) e portanto nao fala conversa.
58
- /// </summary>
59
- /// <remarks>
60
- /// Escrito uma vez, aqui, porque duas copias deste predicado sao como a
61
- /// <c>AgentFactory</c> e o <c>ModelRegistry</c> passariam a discordar sobre o mesmo
62
- /// alias.
63
- /// </remarks>
64
17
  public static bool IsMedia(this AgentApi api) => api is AgentApi.Images or AgentApi.Videos;
65
18
  }
@@ -5,48 +5,11 @@ using Morph.AiKit.Providers;
5
5
 
6
6
  namespace Morph.AiKit.Agents;
7
7
 
8
- /// <summary>
9
- /// Transforma uma <see cref="AgentSpec"/> (o agente como dado) num
10
- /// <see cref="AIAgent"/> pronto para rodar. E o unico lugar do kit que conhece a ORDEM do
11
- /// pipeline.
12
- /// </summary>
13
- /// <remarks>
14
- /// <para><b>A ordem, de fora para dentro, e o contrato desta classe:</b></para>
15
- /// <code>
16
- /// OpenTelemetryAgent span invoke_agent — cobre a invocacao inteira (T12)
17
- /// +- ChatClientAgent UseProvidedChatClientAsIs = true: o pipeline abaixo e nosso
18
- /// +- timeout TimeoutSeconds vira CancellationToken
19
- /// +- usage-cost ve UMA resposta com o uso ja somado das voltas (T11)
20
- /// +- FunctionInvoking MaxToolIterations / AllowConcurrentToolInvocation
21
- /// +- telemetria de chat span chat, ABAIXO do FICC (T12)
22
- /// +- cliente do provider memoizado pelo ModelRegistry
23
- /// </code>
24
- /// <para>
25
- /// Cada posicao foi <b>medida</b> contra o pin, nao herdada de folclore. Acima do FICC o
26
- /// middleware de custo recebe o uso agregado (10/4 + 30/6 chegam como 40/10); abaixo dele
27
- /// receberia uma resposta por volta, e ainda leria um <c>UsageDetails</c> que o FICC muta
28
- /// para acumular. A telemetria de chat fica abaixo do FICC porque o MAF 1.20.0 escreve, na
29
- /// documentacao do proprio slot que ele reserva, que so assim o span de chat fecha antes
30
- /// das tools e o <c>invoke_agent</c> vira raiz.
31
- /// </para>
32
- /// <para>
33
- /// <b>Por que <c>UseProvidedChatClientAsIs = true</c>:</b> com o default, o
34
- /// <c>ChatClientAgent</c> monta ele mesmo o FICC — e nao ha onde ajustar
35
- /// <c>MaximumIterationsPerRequest</c> nem onde encaixar o custo entre o FICC e o cliente.
36
- /// O preco medido dessa escolha e que o slot de telemetria que o MAF reservaria deixa de
37
- /// existir: sem a T12 ligada, um agente desta fabrica emite <c>invoke_agent</c> e
38
- /// <b>nenhum</b> span de chat. E por isso que a telemetria de chat e um encaixe nomeado, e
39
- /// nao um detalhe opcional.
40
- /// </para>
41
- /// </remarks>
42
8
  public sealed class AgentFactory
43
9
  {
44
10
  private readonly ModelRegistry _registry;
45
11
  private readonly AgentFactoryOptions _options;
46
12
 
47
- /// <summary>Cria a fabrica sobre um registry ja carregado.</summary>
48
- /// <param name="registry">Fonte unica de alias, protocolo e tarifa.</param>
49
- /// <param name="options">Infraestrutura e encaixes. Nulo = nenhum encaixe preenchido.</param>
50
13
  public AgentFactory(ModelRegistry registry, AgentFactoryOptions? options = null)
51
14
  {
52
15
  ArgumentNullException.ThrowIfNull(registry);
@@ -55,15 +18,6 @@ public sealed class AgentFactory
55
18
  _options = options ?? new AgentFactoryOptions();
56
19
  }
57
20
 
58
- /// <summary>
59
- /// Materializa a spec. Alias desconhecido, limite de alias violado ou troca de
60
- /// protocolo sem seletor sao recusas <b>na construcao</b> — nunca um agente meio certo.
61
- /// </summary>
62
- /// <remarks>
63
- /// Recusar aqui e falha de composicao, nao excecao como fluxo de controle: acontece uma
64
- /// vez, na montagem, e seguir adiante seria seguir sem regua. Quem quiser inspecionar
65
- /// antes chama <c>registry.Resolve(alias).CheckRequest(...)</c>, que e Result.
66
- /// </remarks>
67
21
  public AIAgent Create(AgentSpec spec)
68
22
  {
69
23
  ArgumentNullException.ThrowIfNull(spec);
@@ -71,11 +25,6 @@ public sealed class AgentFactory
71
25
  var alias = _registry.Resolve(spec.Alias);
72
26
  var api = spec.ResolveApi(alias.Api);
73
27
 
74
- // Alias de MIDIA nao vira agente, e a recusa e aqui, na construcao. Sem ela, um
75
- // alias de imagem passado por engano viraria um agente de chat apontando para um
76
- // modelo que nao fala chat: a falha apareceria tarde, no primeiro turno, com uma
77
- // mensagem do provider que nao diz o que aconteceu. E a companheira obrigatoria de
78
- // AgentApi.Images/Videos existirem — enum novo sem recusa e uma armadilha nova.
79
28
  if (alias.Api.IsMedia() || api.IsMedia())
80
29
  {
81
30
  throw AgentFactoryException.MediaAliasIsNotAnAgent(spec.Alias, alias.Api.IsMedia() ? alias.Api : api);
@@ -98,6 +47,7 @@ public sealed class AgentFactory
98
47
  Name = spec.Name,
99
48
  Description = spec.Description,
100
49
  ChatOptions = BuildChatOptions(spec, alias),
50
+ // Com o default o ChatClientAgent monta o proprio FICC, sem MaximumIterationsPerRequest nem slot para o custo.
101
51
  UseProvidedChatClientAsIs = true,
102
52
  };
103
53
 
@@ -112,12 +62,6 @@ public sealed class AgentFactory
112
62
  : agent;
113
63
  }
114
64
 
115
- /// <summary>
116
- /// As opcoes de requisicao do agente. <c>ModelId</c> vem do alias — a spec nunca cita
117
- /// modelo. <c>Tools</c> e <c>ResponseFormat</c> entram antes de
118
- /// <see cref="AgentSpecOptions.ApplyTo"/>, que por contrato nao sobrescreve o que ja
119
- /// foi definido.
120
- /// </summary>
121
65
  private static ChatOptions BuildChatOptions(AgentSpec spec, ModelAlias alias)
122
66
  {
123
67
  var options = new ChatOptions
@@ -151,6 +95,8 @@ public sealed class AgentFactory
151
95
  : throw AgentFactoryException.ProtocolWithoutSelector(alias.Name, alias.Api, api);
152
96
  }
153
97
 
98
+ // A ordem e o contrato: o custo fica ACIMA do FICC para ver o uso ja somado das voltas, e a
99
+ // telemetria de chat ABAIXO dele porque so assim o span de chat fecha antes das tools (MAF 1.20.0).
154
100
  private IChatClient BuildChatPipeline(IChatClient leaf, AgentSpec spec, ModelAlias alias)
155
101
  {
156
102
  var builder = leaf.AsBuilder();
@@ -186,11 +132,6 @@ public sealed class AgentFactory
186
132
  return builder.Build(_options.ServiceProvider);
187
133
  }
188
134
 
189
- /// <summary>
190
- /// Realiza <see cref="AgentSpecOptions.TimeoutSeconds"/>. Vive aqui, privado, porque e
191
- /// a traducao de UMA opcao para o <see cref="CancellationToken"/> que o pipeline ja
192
- /// carrega — e nao um conceito que alguem deva compor por fora.
193
- /// </summary>
194
135
  private sealed class TimeoutChatClient(IChatClient inner, TimeSpan timeout) : DelegatingChatClient(inner)
195
136
  {
196
137
  public override async Task<ChatResponse> GetResponseAsync(
@@ -222,43 +163,31 @@ public sealed class AgentFactory
222
163
  }
223
164
  }
224
165
 
225
- /// <summary>Motivo de uma recusa da <see cref="AgentFactory"/>.</summary>
226
166
  public enum AgentFactoryError
227
167
  {
228
- /// <summary>A requisicao viola um limite declarado no alias, com procedencia.</summary>
229
168
  ConstraintViolated = 0,
230
169
 
231
- /// <summary>A spec pede um protocolo diferente do alias e nao ha seletor de cliente.</summary>
232
170
  ProtocolWithoutSelector = 1,
233
171
 
234
- /// <summary>O seletor de cliente devolveu nulo.</summary>
235
172
  NoChatClient = 2,
236
173
 
237
- /// <summary>O alias e de midia (<c>api: images</c> ou <c>api: videos</c>) e nao fala conversa.</summary>
238
174
  MediaAliasIsNotAnAgent = 3,
239
175
  }
240
176
 
241
- /// <summary>
242
- /// Recusa de composicao da <see cref="AgentFactory"/>. <c>sealed</c> e discriminada por
243
- /// <see cref="Reason"/>: quem trata precisa do motivo, nao de herdar do tipo.
244
- /// </summary>
245
177
  public sealed class AgentFactoryException : InvalidOperationException
246
178
  {
247
179
  private AgentFactoryException(AgentFactoryError reason, string message)
248
180
  : base(message)
249
181
  => Reason = reason;
250
182
 
251
- /// <summary>Por que a fabrica recusou.</summary>
252
183
  public AgentFactoryError Reason { get; }
253
184
 
254
- /// <summary>A requisicao viola limites do alias. A mensagem traz cada violacao com sua procedencia.</summary>
255
185
  public static AgentFactoryException ConstraintViolated(string alias, IReadOnlyList<string> violations)
256
186
  => new(
257
187
  AgentFactoryError.ConstraintViolated,
258
188
  $"alias '{alias}': a spec viola limite(s) declarado(s) do alias e o agente NAO foi criado. " +
259
189
  string.Join(" | ", violations));
260
190
 
261
- /// <summary>Divergencia de protocolo sem seletor que saiba construir o outro cliente.</summary>
262
191
  public static AgentFactoryException ProtocolWithoutSelector(string alias, AgentApi aliasApi, AgentApi specApi)
263
192
  => new(
264
193
  AgentFactoryError.ProtocolWithoutSelector,
@@ -268,10 +197,6 @@ public sealed class AgentFactoryException : InvalidOperationException
268
197
  "alias com o api pedido no model-registry.v2.json, ou preencha " +
269
198
  $"{nameof(AgentFactoryOptions)}.{nameof(AgentFactoryOptions.ChatClientSelector)}.");
270
199
 
271
- /// <summary>
272
- /// O alias e de midia. Recusa nomeada, na construcao — nunca um agente que aponta para
273
- /// um modelo que nao fala chat.
274
- /// </summary>
275
200
  public static AgentFactoryException MediaAliasIsNotAnAgent(string alias, AgentApi api)
276
201
  => new(
277
202
  AgentFactoryError.MediaAliasIsNotAnAgent,
@@ -280,7 +205,6 @@ public sealed class AgentFactoryException : InvalidOperationException
280
205
  $"{nameof(Morph.AiKit.Media.IMediaGenerator)}.{nameof(Morph.AiKit.Media.IMediaGenerator.EnqueueAsync)}, " +
281
206
  "que devolve um id de job e nunca bytes. Ver ai-agents/media-pipeline.md.");
282
207
 
283
- /// <summary>O seletor devolveu nulo — nao ha cliente para o par alias/protocolo.</summary>
284
208
  public static AgentFactoryException NoChatClient(string alias, AgentApi api)
285
209
  => new(
286
210
  AgentFactoryError.NoChatClient,
@@ -5,87 +5,18 @@ using Morph.AiKit.Providers;
5
5
 
6
6
  namespace Morph.AiKit.Agents;
7
7
 
8
- /// <summary>
9
- /// O que a <see cref="AgentFactory"/> precisa saber que NAO esta na
10
- /// <see cref="AgentSpec"/>: infraestrutura do processo (log, DI) e os tres encaixes do
11
- /// pipeline que outras tasks preenchem.
12
- /// </summary>
13
- /// <remarks>
14
- /// <para>
15
- /// <b>Por que encaixes e nao dependencias diretas:</b> a ORDEM do pipeline e do kit — ela
16
- /// esta escrita, medida e testada dentro da <see cref="AgentFactory"/>. O CONTEUDO de cada
17
- /// posicao e de quem tem o tipo: o middleware de custo mora na T11 e a telemetria na T12.
18
- /// Se a fabrica referenciasse os dois diretamente, ou ela nasceria depois deles, ou eles
19
- /// nasceriam dentro dela. Com encaixe nomeado, a fabrica continua dona do lugar e cada
20
- /// task continua dona do que ocupa o lugar.
21
- /// </para>
22
- /// <para>
23
- /// Encaixe nulo = posicao vazia. Um agente sem custo e sem telemetria e um agente valido,
24
- /// nao um agente pela metade.
25
- /// </para>
26
- /// </remarks>
27
8
  public sealed record AgentFactoryOptions
28
9
  {
29
- /// <summary>
30
- /// Fabrica de log repassada ao <c>FunctionInvokingChatClient</c> e ao
31
- /// <c>ChatClientAgent</c>. Nula = sem log, que e o default do MAF.
32
- /// </summary>
33
10
  public ILoggerFactory? LoggerFactory { get; init; }
34
11
 
35
- /// <summary>
36
- /// Container usado para resolver servicos ao montar os pipelines. Nulo = os builders
37
- /// do <c>Microsoft.Extensions.AI</c> usam o provider vazio deles.
38
- /// </summary>
39
12
  public IServiceProvider? ServiceProvider { get; init; }
40
13
 
41
- /// <summary>
42
- /// De onde sai o <see cref="IChatClient"/> quando o protocolo efetivo NAO e o do alias.
43
- /// </summary>
44
- /// <remarks>
45
- /// <para>
46
- /// O <c>ModelRegistry</c> memoiza <b>um</b> cliente por alias, construido pela
47
- /// <c>IProviderClientFactory</c> a partir do <c>api:</c> daquele alias. Logo, uma spec
48
- /// que pede Chat Completions num alias declarado <c>responses</c> nao pode ser servida
49
- /// pelo cliente memoizado — ele fala o outro protocolo. Sem este seletor a fabrica
50
- /// <b>recusa</b> a combinacao, nomeando os dois protocolos, em vez de devolver um agente
51
- /// que diz falar um protocolo e fala outro.
52
- /// </para>
53
- /// <para>
54
- /// Nulo (o normal) = todo agente usa o cliente memoizado do alias, e
55
- /// <see cref="AgentSpec.Api"/> divergente vira recusa. Preenchido, recebe o alias e o
56
- /// protocolo <b>efetivo</b> (ja resolvido por <see cref="AgentSpec.ResolveApi"/>) e
57
- /// devolve o cliente correspondente.
58
- /// </para>
59
- /// </remarks>
60
14
  public Func<ModelAlias, AgentApi, IChatClient>? ChatClientSelector { get; init; }
61
15
 
62
- /// <summary>
63
- /// Encaixe do middleware de custo (T11), <b>acima</b> do <c>FunctionInvokingChatClient</c>.
64
- /// Preencha com <c>(b, _, alias) =&gt; b.UseUsageCost(alias, sink)</c>.
65
- /// </summary>
66
- /// <remarks>
67
- /// A posicao e medida, nao opinada: acima do FICC o middleware ve <b>uma</b> resposta
68
- /// com o uso ja somado de todas as voltas de tool (medido: 40/10 num roteiro de duas
69
- /// voltas de 10/4 e 30/6); abaixo do FICC ele ve uma resposta por volta. Pior, o FICC
70
- /// <b>acumula no proprio objeto</b> <c>UsageDetails</c> da primeira volta — um sink que
71
- /// guardasse a referencia abaixo do FICC leria valores que mudaram depois.
72
- /// </remarks>
16
+ // Abaixo do FICC um sink veria uma resposta por volta, e o FICC muta o UsageDetails da primeira volta para acumular.
73
17
  public Func<ChatClientBuilder, AgentSpec, ModelAlias, ChatClientBuilder>? ConfigureUsageCost { get; init; }
74
18
 
75
- /// <summary>
76
- /// Encaixe da telemetria de chat (T12), <b>abaixo</b> do <c>FunctionInvokingChatClient</c>
77
- /// e imediatamente acima do cliente do provider.
78
- /// </summary>
79
- /// <remarks>
80
- /// A posicao e exigencia escrita do proprio MAF 1.20.0: com a instrumentacao abaixo do
81
- /// FICC o span de chat fecha <b>antes</b> de as tools rodarem, o que deixa o
82
- /// <c>invoke_agent</c> como span raiz e permite ao FICC emitir <c>execute_tool</c>.
83
- /// </remarks>
84
19
  public Func<ChatClientBuilder, AgentSpec, ModelAlias, ChatClientBuilder>? ConfigureChatTelemetry { get; init; }
85
20
 
86
- /// <summary>
87
- /// Encaixe da telemetria de agente (T12) — o span mais externo, que cobre a invocacao
88
- /// inteira. Preencha com <c>(b, _, _) =&gt; b.UseMorphTelemetry(telemetryOptions)</c>.
89
- /// </summary>
90
21
  public Func<AIAgentBuilder, AgentSpec, ModelAlias, AIAgentBuilder>? ConfigureAgentTelemetry { get; init; }
91
22
  }
@@ -3,30 +3,11 @@ using Microsoft.Extensions.AI;
3
3
 
4
4
  namespace Morph.AiKit.Agents;
5
5
 
6
- /// <summary>
7
- /// O agente <b>como dado</b>: tudo o que a <c>AgentFactory</c> (T10) precisa para
8
- /// materializar um <c>AIAgent</c>, e nada mais. Nao tem comportamento de execucao, nao
9
- /// abre conexao, nao le configuracao — o que permite descrever um agente em teste, em
10
- /// JSON ou em banco sem arrastar infraestrutura junto.
11
- /// </summary>
12
- /// <remarks>
13
- /// <para>
14
- /// <b>O modelo nao aparece aqui.</b> So o <see cref="Alias"/>, que e resolvido pelo
15
- /// <c>ModelRegistry</c>. E a regra do standard <c>ai-agents-providers-model-registry</c>:
16
- /// agentes referenciam alias, nunca id de modelo — trocar de provider e mudanca de um
17
- /// arquivo so.
18
- /// </para>
19
- /// </remarks>
20
6
  public sealed record AgentSpec
21
7
  {
22
8
  private readonly string _alias = string.Empty;
23
9
  private readonly string _instructions = string.Empty;
24
10
 
25
- /// <summary>
26
- /// Chave no <c>ModelRegistry</c>. Nunca um id de modelo.
27
- /// Vazio ou so espaco e rejeitado na construcao: um alias em branco viraria uma falha
28
- /// de resolucao ilegivel varias camadas adiante.
29
- /// </summary>
30
11
  public required string Alias
31
12
  {
32
13
  get => _alias;
@@ -37,7 +18,6 @@ public sealed record AgentSpec
37
18
  }
38
19
  }
39
20
 
40
- /// <summary>Prompt de sistema do agente. Vazio ou so espaco e rejeitado na construcao.</summary>
41
21
  public required string Instructions
42
22
  {
43
23
  get => _instructions;
@@ -48,44 +28,18 @@ public sealed record AgentSpec
48
28
  }
49
29
  }
50
30
 
51
- /// <summary>
52
- /// Protocolo desta spec. <b>Nulo = usa o <c>api:</c> do alias</b> — o caso normal.
53
- /// Preenchido, vence o alias (ver <see cref="ResolveApi"/>).
54
- /// </summary>
55
31
  public AgentApi? Api { get; init; }
56
32
 
57
- /// <summary>Tools do agente. Vazio por padrao — nunca nulo.</summary>
58
33
  public IReadOnlyList<AITool> Tools { get; init; } = [];
59
34
 
60
- /// <summary>
61
- /// Schema JSON da saida estruturada. Nulo = saida livre.
62
- /// <para>
63
- /// <b>Armadilha de tempo de vida:</b> um <see cref="JsonElement"/> so e valido enquanto
64
- /// o <see cref="JsonDocument"/> que o originou estiver vivo. Guarde aqui um
65
- /// <see cref="JsonElement.Clone"/> quando o documento for descartado — senao o schema
66
- /// morre silenciosamente entre a montagem da spec e o uso dela.
67
- /// </para>
68
- /// </summary>
35
+ // Guarde um JsonElement.Clone(): o elemento morre junto com o JsonDocument que o originou.
69
36
  public JsonElement? OutputSchema { get; init; }
70
37
 
71
- /// <summary>Bag unico de opcoes. Nunca nulo; o default nao envia opcao nenhuma.</summary>
72
38
  public AgentSpecOptions Options { get; init; } = new();
73
39
 
74
- /// <summary>Nome legivel do agente (telemetria, logs). Nulo = sem nome.</summary>
75
40
  public string? Name { get; init; }
76
41
 
77
- /// <summary>Descricao legivel do agente. Nulo = sem descricao.</summary>
78
42
  public string? Description { get; init; }
79
43
 
80
- /// <summary>
81
- /// Precedencia entre o <c>api:</c> da spec e o <c>api:</c> do alias, num lugar so.
82
- /// <b>A spec vence quando presente; o alias vence quando a spec e nula.</b>
83
- /// </summary>
84
- /// <remarks>
85
- /// A regra mora aqui, e nao dentro da <c>AgentFactory</c>, porque divergencia silenciosa
86
- /// entre spec e registry e exatamente o bug que o <c>api:</c> por alias existe para
87
- /// eliminar — e uma regra copiada em dois lugares e uma regra que ja divergiu.
88
- /// </remarks>
89
- /// <param name="aliasApi">O <c>api:</c> declarado no alias resolvido.</param>
90
44
  public AgentApi ResolveApi(AgentApi aliasApi) => Api ?? aliasApi;
91
45
  }