@polymorphism-tech/morph-spec 8.0.0 → 8.1.1

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 (168) hide show
  1. package/README.md +2 -2
  2. package/bin/validate.js +379 -379
  3. package/claude-plugin.json +1 -1
  4. package/docs/CHEATSHEET.md +1 -1
  5. package/docs/QUICKSTART.md +1 -1
  6. package/framework/CLAUDE.md +1 -1
  7. package/framework/MORPH.md +5 -5
  8. package/framework/agents.json +1 -1
  9. package/framework/commands/commit.md +166 -166
  10. package/framework/commands/morph-infra.md +215 -215
  11. package/framework/commands/morph-preflight.md +205 -205
  12. package/framework/commands/morph-troubleshoot.md +124 -124
  13. package/framework/hooks/README.md +0 -1
  14. package/framework/hooks/claude-code/statusline.py +679 -679
  15. package/framework/hooks/claude-code/statusline.sh +11 -11
  16. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  17. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  18. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  19. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  20. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  21. package/framework/hooks/shared/activity-logger.js +160 -160
  22. package/framework/hooks/shared/stdin-reader.js +26 -26
  23. package/framework/rubrics/backend.json +41 -41
  24. package/framework/rules/ai-agents-standards.md +45 -45
  25. package/framework/rules/dotnet-templates.md +86 -86
  26. package/framework/rules/frontend-standards.md +13 -13
  27. package/framework/rules/infrastructure-standards.md +27 -27
  28. package/framework/rules/neon-standards.md +25 -25
  29. package/framework/rules/nextjs-standards.md +20 -20
  30. package/framework/rules/nextjs-templates.md +40 -40
  31. package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
  32. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
  33. package/framework/skills/core/morph-apply/SKILL.md +12 -21
  34. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  35. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  36. package/framework/skills/core/morph-hotfix/SKILL.md +2 -4
  37. package/framework/skills/core/morph-implement/SKILL.md +10 -19
  38. package/framework/skills/core/morph-plan/SKILL.md +1 -1
  39. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  40. package/framework/skills/core/morph-review/SKILL.md +11 -15
  41. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  42. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  43. package/framework/standards/ai-agents/agent-session.md +160 -160
  44. package/framework/standards/ai-agents/batching.md +193 -193
  45. package/framework/standards/ai-agents/context-providers.md +188 -188
  46. package/framework/standards/ai-agents/mcp-server.md +250 -250
  47. package/framework/standards/ai-agents/mcp-tools.md +197 -197
  48. package/framework/standards/ai-agents/middleware-patterns.md +207 -207
  49. package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
  50. package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
  51. package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
  52. package/framework/standards/ai-agents/modalities-vision.md +201 -201
  53. package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
  54. package/framework/standards/ai-agents/production.md +275 -275
  55. package/framework/standards/ai-agents/prompts-in-db.md +214 -214
  56. package/framework/standards/ai-agents/providers/model-registry.md +158 -158
  57. package/framework/standards/ai-agents/service-tier-flex.md +135 -135
  58. package/framework/standards/ai-agents/structured-output.md +249 -249
  59. package/framework/standards/ai-agents/sweet-spot.md +109 -109
  60. package/framework/templates/IDE-SNIPPETS.md +262 -262
  61. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  62. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  63. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  64. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  65. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  66. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  67. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  68. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  69. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  70. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  71. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  72. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  73. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  74. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  75. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  76. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  77. package/framework/templates/code/typescript/contracts.ts +167 -167
  78. package/framework/templates/docs/clarifications.md +253 -253
  79. package/framework/templates/docs/schema-analysis.md +119 -119
  80. package/framework/templates/docs/ui-components.md +52 -52
  81. package/framework/templates/docs/ui-design-system.md +76 -76
  82. package/framework/templates/docs/ui-flows.md +167 -167
  83. package/framework/templates/docs/ui-mockups.md +98 -98
  84. package/framework/templates/feature/decisions.md +122 -122
  85. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  86. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  87. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  88. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  89. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  90. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  91. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  92. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  93. package/framework/templates/infrastructure/docker/docker-compose.template.yml +50 -50
  94. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  95. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  96. package/framework/templates/infrastructure/github/README.md +56 -56
  97. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  98. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  99. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  100. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  101. package/framework/templates/integrations/asaas-client.cs +387 -387
  102. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  103. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  104. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  105. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  106. package/framework/templates/project/validate.js +120 -120
  107. package/framework/templates/state.template.json +17 -17
  108. package/framework/templates/ui/design-system.css +226 -226
  109. package/package.json +1 -1
  110. package/src/commands/dashboard/dashboard.js +53 -53
  111. package/src/commands/index.js +13 -13
  112. package/src/commands/mcp/mcp-setup.js +519 -519
  113. package/src/commands/project/checkpoint.js +209 -209
  114. package/src/commands/project/worktree.js +83 -1
  115. package/src/core/state/phase-state-machine.js +197 -197
  116. package/src/core/templates/template-renderer.js +477 -477
  117. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  118. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  119. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  120. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  121. package/src/dashboard/app/main.jsx +13 -13
  122. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  123. package/src/dashboard/app/pages/HookInspector.jsx +418 -418
  124. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  125. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  126. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  127. package/src/dashboard/app/pages/Standards.jsx +332 -332
  128. package/src/dashboard/app/styles/index.css +47 -47
  129. package/src/dashboard/index.html +12 -12
  130. package/src/dashboard/package.json +24 -24
  131. package/src/dashboard/scanner/hooks-scanner.js +41 -41
  132. package/src/dashboard/scanner/phases-scanner.js +15 -15
  133. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  134. package/src/dashboard/scanner/rules-scanner.js +37 -37
  135. package/src/dashboard/scanner/skills-scanner.js +43 -43
  136. package/src/dashboard/scanner/squads-scanner.js +13 -13
  137. package/src/dashboard/scanner/standards-scanner.js +26 -26
  138. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  139. package/src/dashboard/vite.config.js +24 -24
  140. package/src/lib/agents/metrics-aggregator.js +56 -56
  141. package/src/lib/agents/metrics-calculator.js +125 -125
  142. package/src/lib/agents/output-collector.js +73 -73
  143. package/src/lib/detectors/claude-config-detector.js +152 -152
  144. package/src/lib/detectors/design-system-detector.js +231 -231
  145. package/src/lib/detectors/index.js +217 -217
  146. package/src/lib/generators/architecture-scanner.js +639 -639
  147. package/src/lib/generators/design-system-generator.js +508 -508
  148. package/src/lib/generators/index.js +13 -13
  149. package/src/lib/generators/settings-generator.js +209 -209
  150. package/src/lib/hooks/hook-executor.js +167 -167
  151. package/src/lib/installers/mcp-installer.js +719 -719
  152. package/src/lib/tasks/task-classifier.js +30 -30
  153. package/src/lib/tasks/task-parser.js +209 -209
  154. package/src/lib/validators/architecture/architecture-validator.js +259 -259
  155. package/src/lib/validators/checkpoint-persistence.js +39 -39
  156. package/src/lib/validators/contracts/contract-compliance-validator.js +274 -274
  157. package/src/lib/validators/css/css-validator.js +340 -340
  158. package/src/lib/validators/packages/package-validator.js +347 -347
  159. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  160. package/src/lib/validators/shared/issue-counter.js +14 -14
  161. package/src/lib/validators/validation-runner.js +349 -349
  162. package/src/utils/agent-id-mapper.js +11 -11
  163. package/src/utils/claude-settings-manager.js +300 -300
  164. package/src/utils/hooks-installer.js +3 -24
  165. package/src/utils/skills-installer.js +174 -174
  166. package/framework/hooks/claude-code/core/subagent-report-guard.js +0 -95
  167. package/framework/templates/.idea/morph-templates.xml +0 -92
  168. package/framework/templates/.vscode/morph-templates.code-snippets +0 -186
@@ -4,7 +4,7 @@ description: Guia a produção dos três artefatos de planejamento de uma featur
4
4
  version: core
5
5
  when-to-invoke: ao iniciar a fase plan de uma feature, após o Gate 1 (proposal aprovado)
6
6
  user-invokable: true
7
- cliVersion: "8.0.0"
7
+ cliVersion: "8.1.1"
8
8
  ---
9
9
 
10
10
  # morph-plan
@@ -4,7 +4,7 @@ description: Orquestra a fase de proposta+plano de uma feature morph-spec. Encad
4
4
  version: core
5
5
  when-to-invoke: ao receber instrução "use /morph-proposal" do usuário, ou ao iniciar uma nova feature
6
6
  user-invokable: true
7
- cliVersion: "8.0.0"
7
+ cliVersion: "8.1.1"
8
8
  ---
9
9
 
10
10
  # morph-proposal
@@ -4,7 +4,7 @@ description: Conduz a fase de revisão e produz o review-report.md para o Gate 3
4
4
  version: core
5
5
  when-to-invoke: ao iniciar a fase review, após todas as tasks de tasks.json estarem com status `done`
6
6
  user-invokable: true
7
- cliVersion: "8.0.0"
7
+ cliVersion: "8.1.1"
8
8
  ---
9
9
 
10
10
  # morph-review
@@ -56,22 +56,18 @@ e o `recap.md` estar atualizado. Normalmente invocada pela skill orquestradora `
56
56
  seguindo as bandas 0-10 de cada uma.
57
57
  NÃO reescreva código. NÃO toque em tasks.json, feature.json nem no board
58
58
  de sessão.
59
- Protocolo obrigatório — ATO FINAL: chame a tool SendMessage com
60
- to:"main" e o relatório completo no content como a ÚLTIMA tool call
61
- do seu turno; sua última mensagem em texto NÃO chega ao orquestrador
62
- — só SendMessage chega. Encerre IMEDIATAMENTE depois: zero texto
63
- adicional, zero nova tool call, zero "aguardando confirmação".
64
- Exemplo literal (última chamada de tool da sua sessão, sem nada depois):
65
- SendMessage({ to: "main", content: "Review de {feature}: arch=9.0
66
- contracts=9.5 quality=9.0 tests=8.5 → composto 9.05. Feedback: ..." })
67
- Terminar idle sem SendMessage, ou continuar agindo depois dele, é
68
- falha de protocolo.
69
- Retorne no content: score 0-10 por dimensão, score composto (arch×0.30 +
70
- contracts×0.25 + quality×0.25 + tests×0.20), e feedback priorizado
71
- (bloqueantes primeiro) para qualquer dimensão < 9.
59
+ Contrato do relatório final — ATO FINAL: o seu relatório é a sua
60
+ ÚLTIMA MENSAGEM DE TEXTO; ela é o valor de retorno desta sessão e
61
+ chega inteira ao orquestrador. NÃO chame SendMessage: ele gera um
62
+ evento a mais além da notificação de término, custando um turno
63
+ inútil ao orquestrador. Escreva o relatório e encerre.
64
+ Seu relatório final deve conter: score 0-10 por dimensão, score
65
+ composto (arch×0.30 + contracts×0.25 + quality×0.25 + tests×0.20), e
66
+ feedback priorizado (bloqueantes primeiro) para qualquer dimensão < 9.
67
+ Relatório oco, ou sem esses itens, é falha de protocolo.
72
68
  ```
73
69
  - **Fallback (tipo não registrado):** se `morph-evaluator` não estiver na sua lista de subagent types, despache `general-purpose` colando o campo `persona` do agente `evaluator` (Read em `.morph/framework/agents.json`) no topo do prompt — e **registre o fallback no review-report** (seção de método).
74
- - Os scores por dimensão e o composto do review-report vêm **desse retorno**, não da sua auto-avaliação. O hook `subagent-report-guard` bloqueia uma vez o encerramento do avaliador sem SendMessage; se mesmo assim ele ficar idle sem reportar, cobre via SendMessage antes de prosseguir (fallback). **Assim que o relatório chegar, libere a sessão do avaliador** — `TaskStop(task_id: <id/nome retornado pelo dispatch>)` — para não deixá-lo pendurado até o idle-detector do harness disparar um `idle_notification` de volta a esta sessão.
70
+ - Os scores por dimensão e o composto do review-report vêm **desse retorno**, não da sua auto-avaliação. Se o relatório vier oco ou sem os scores por dimensão, registre a falha de protocolo na seção de método do review-report e re-despache.
75
71
 
76
72
  5. Produza `review-report.md` em `.morph/features/{feature}/4-review/` com:
77
73
  - Scores por dimensão (arquitetura, contratos, qualidade, cobertura)
@@ -4,7 +4,7 @@ description: Varre o codebase existente, detecta stack atual, compara com o stac
4
4
  version: core
5
5
  when-to-invoke: ao iniciar uma feature em projeto brownfield (codebase já existente)
6
6
  user-invokable: true
7
- cliVersion: "8.0.0"
7
+ cliVersion: "8.1.1"
8
8
  ---
9
9
 
10
10
  # morph-stack-scan
@@ -4,7 +4,7 @@ description: Localiza e carrega um standard específico do STANDARDS.json sob de
4
4
  version: core
5
5
  when-to-invoke: quando precisar consultar um standard específico durante a implementação
6
6
  user-invokable: true
7
- cliVersion: "8.0.0"
7
+ cliVersion: "8.1.1"
8
8
  ---
9
9
 
10
10
  # morph-standards
@@ -1,160 +1,160 @@
1
- # Agent Session — Conversation state and chat reducers
2
-
3
- > **Scope:** stacks=["dotnet"]
4
- > **Layer:** 2 (on-keyword)
5
- > **Keywords:** agent session, chat history, conversation state, chat reducer, history truncation, AgentThread
6
- > **Read by Claude in:** implement
7
-
8
- **Verified against:** MAF 1.0 GA. Last-verified: 2026-05-19.
9
-
10
- ---
11
-
12
- ## Quando usar AgentSession
13
-
14
- Use `AgentSession` quando o agente é **conversacional** — há uma UI de chat que mantém histórico entre turnos do usuário.
15
-
16
- **Use AgentSession quando:**
17
- - Existe uma interface de chat (web, mobile, CLI interativo)
18
- - O agente precisa lembrar o que foi dito nos turnos anteriores da mesma conversa
19
- - Há perguntas de follow-up ("e agora?", "altere o segundo ponto", "lembra do que disse sobre X?")
20
-
21
- **NÃO use AgentSession quando:**
22
- - O agente é one-shot (gerador, executor, classificador) — recebe uma entrada, devolve uma saída, fim
23
- - Agentes stateless em pipeline multi-agent — cada chamada é independente
24
- - Jobs de batch/background — não há conversa; histórico não faz sentido
25
-
26
- > "Add Memory/Session because agents need state" é um anti-pattern de `sweet-spot.md`.
27
- > Só adicione quando uma UI de chat real existe.
28
-
29
- ---
30
-
31
- ## A API
32
-
33
- **Pacote:** `Microsoft.Agents.AI` (base; já requerido por `ai-agents-setup`).
34
-
35
- **Tipos confirmados via context7:**
36
- - `AgentSession` — container leve de estado de conversa; obtido via `agent.CreateSessionAsync()`
37
- - `AgentThread` — equivalente para agentes persistentes (PersistentAgentsClient); use `agent.GetNewThread()`
38
- - `ChatClientAgentOptions` — aceita `ChatHistoryProvider` e `AIContextProviders`
39
- - `InMemoryChatHistoryProvider` — implementação embutida de histórico em memória
40
- - `AgentResponse` — tipo retornado por `AIAgent.RunAsync` (non-generic); acesse o texto via `.Text`
41
-
42
- ```csharp
43
- // Construção do agente com histórico em memória
44
- AIAgent agent = _modelRegistry.GetChatClient("text-default")
45
- .AsAIAgent(new ChatClientAgentOptions
46
- {
47
- ChatOptions = new() { Instructions = "You are a helpful assistant." },
48
- ChatHistoryProvider = new InMemoryChatHistoryProvider(),
49
- });
50
- ```
51
-
52
- ---
53
-
54
- ## Exemplo C# — agente conversacional com session persistente entre turnos
55
-
56
- ```csharp
57
- using Microsoft.Agents.AI;
58
- using Microsoft.Extensions.AI;
59
-
60
- // ── 1. Registrar o agente conversacional no DI ──
61
- // Program.cs
62
- builder.Services.AddSingleton<AIAgent>(sp =>
63
- {
64
- var registry = sp.GetRequiredService<ModelRegistry>();
65
- return registry.GetChatClient("text-default")
66
- .AsAIAgent(new ChatClientAgentOptions
67
- {
68
- ChatOptions = new() { Instructions = "You are a helpful customer support assistant." },
69
- // InMemoryChatHistoryProvider: histórico vive em memória, por session.
70
- // Seguro registrar como parte do singleton AIAgent: cada AgentSession criada via
71
- // agent.CreateSessionAsync() isola o histórico de sua conversa — conversas distintas
72
- // não compartilham estado. O provider em si é stateless; o estado fica na session.
73
- // Para persistência entre restarts, substitua por um provider customizado (ex: DB).
74
- ChatHistoryProvider = new InMemoryChatHistoryProvider(),
75
- });
76
- });
77
-
78
- // ── 2. Criar uma session por conversa (ex: por conexão SignalR / por request de "start chat") ──
79
- // ChatController.cs ou ChatHub.cs
80
- public class ChatService(AIAgent _agent)
81
- {
82
- // Uma session por conversa ativa — armazene no escopo do usuário (cache, memória da conexão)
83
- public async Task<AgentSession> StartConversationAsync()
84
- => await _agent.CreateSessionAsync();
85
-
86
- // Cada mensagem do usuário passa a mesma session
87
- public async Task<string> SendMessageAsync(AgentSession session, string userMessage)
88
- {
89
- AgentResponse response = await _agent.RunAsync(userMessage, session);
90
- return response.Text;
91
- }
92
- }
93
-
94
- // ── 3. Uso no controller/hub ──
95
- // Primeiro turno
96
- AgentSession session = await chatService.StartConversationAsync();
97
- string reply1 = await chatService.SendMessageAsync(session, "Meu pedido #1234 está atrasado.");
98
- // reply1: "Vou verificar o pedido #1234 para você..."
99
-
100
- // Segundo turno — o agente lembra do contexto anterior
101
- string reply2 = await chatService.SendMessageAsync(session, "E quando foi despachado?");
102
- // reply2: "O pedido #1234 foi despachado em..." ← contexto mantido pela session
103
- ```
104
-
105
- ---
106
-
107
- ## History management
108
-
109
- O histórico cresce a cada turno. Quando estoura o context window do modelo, as chamadas falham ou truncam silenciosamente.
110
-
111
- ### Estratégias
112
-
113
- | Estratégia | Quando usar | Como implementar |
114
- |------------|-------------|------------------|
115
- | **Sliding window** | Conversas longas com contexto recente suficiente | Limitar `InMemoryChatHistoryProvider` a N mensagens mais recentes |
116
- | **Token budget** | Modelos com context window pequeno | Contar tokens acumulados; truncar quando ultrapassa threshold |
117
- | **Summarization** | Histórico precisa de contexto antigo comprimido | Agente periódico que resume N turnos anteriores em uma mensagem única |
118
-
119
- > **Custom history management:** Para o caso comum, `InMemoryChatHistoryProvider` cobre a
120
- > necessidade de histórico em memória por sessão. Se o projeto exigir truncation customizada
121
- > (ex: sliding window limitando a N mensagens mais recentes ou por token budget), o mecanismo
122
- > de extensão correto — seja subclasse de `ChatHistoryProvider`, um `IChatReducer`, ou outro
123
- > ponto de override — deve ser verificado contra a versão instalada de `Microsoft.Agents.AI`.
124
- > Consulte a documentação MAF atual antes de implementar um provider customizado, pois a API
125
- > exata de extensão não foi confirmada na versão GA e pode variar entre releases.
126
-
127
- ---
128
-
129
- ## Anti-patterns
130
-
131
- | Anti-pattern | Problema |
132
- |-------------|----------|
133
- | Adicionar session em agente one-shot (gerador, executor) | Complexidade desnecessária; estado nunca é usado |
134
- | Histórico ilimitado sem truncation | Context window estoura; custo aumenta linearmente com a conversa |
135
- | Compartilhar uma `AgentSession` entre múltiplos usuários | Histórico de um usuário vaza para outro |
136
- | Usar `InMemoryChatHistoryProvider` sem criar uma `AgentSession` por conversa | Sem `AgentSession` por conversa, o histórico é compartilhado entre todos os usuários; a isolation depende de `AgentSession` — sempre crie uma session por conversa via `agent.CreateSessionAsync()` |
137
- | Usar `AgentThread` (PersistentAgentsClient) sem necessidade | `AgentThread` requer hosted agent service; prefira `AgentSession` com direct model |
138
-
139
- ---
140
-
141
- ## Checklist (verifiable by morph-eval)
142
-
143
- - [ ] `AgentSession` usada somente em agentes conversacionais com UI de chat real
144
- - [ ] `InMemoryChatHistoryProvider` (ou equivalente) registrado em `ChatClientAgentOptions`
145
- - [ ] Uma `AgentSession` por conversa/usuário — nunca compartilhada
146
- - [ ] Estratégia de truncation definida (sliding window, token budget ou summarization)
147
- - [ ] Agentes one-shot (gerador, executor, classificador) **não** recebem session
148
-
149
- ---
150
-
151
- ## References
152
-
153
- - `ai-agents-setup` — packages e DI base
154
- - `ai-agents-sweet-spot` — decisão de quando adicionar estado ao agente
155
- - `ai-agents-middleware-patterns` (Onda 2) — pipeline de contexto e middleware
156
- - MAF Conversations docs: https://learn.microsoft.com/en-us/agent-framework/agents/conversations/
157
-
158
- ---
159
-
160
- *MORPH-SPEC by Polymorphism Tech — ai-agents/agent-session.md v1.0 (2026-05-19)*
1
+ # Agent Session — Conversation state and chat reducers
2
+
3
+ > **Scope:** stacks=["dotnet"]
4
+ > **Layer:** 2 (on-keyword)
5
+ > **Keywords:** agent session, chat history, conversation state, chat reducer, history truncation, AgentThread
6
+ > **Read by Claude in:** implement
7
+
8
+ **Verified against:** MAF 1.0 GA. Last-verified: 2026-05-19.
9
+
10
+ ---
11
+
12
+ ## Quando usar AgentSession
13
+
14
+ Use `AgentSession` quando o agente é **conversacional** — há uma UI de chat que mantém histórico entre turnos do usuário.
15
+
16
+ **Use AgentSession quando:**
17
+ - Existe uma interface de chat (web, mobile, CLI interativo)
18
+ - O agente precisa lembrar o que foi dito nos turnos anteriores da mesma conversa
19
+ - Há perguntas de follow-up ("e agora?", "altere o segundo ponto", "lembra do que disse sobre X?")
20
+
21
+ **NÃO use AgentSession quando:**
22
+ - O agente é one-shot (gerador, executor, classificador) — recebe uma entrada, devolve uma saída, fim
23
+ - Agentes stateless em pipeline multi-agent — cada chamada é independente
24
+ - Jobs de batch/background — não há conversa; histórico não faz sentido
25
+
26
+ > "Add Memory/Session because agents need state" é um anti-pattern de `sweet-spot.md`.
27
+ > Só adicione quando uma UI de chat real existe.
28
+
29
+ ---
30
+
31
+ ## A API
32
+
33
+ **Pacote:** `Microsoft.Agents.AI` (base; já requerido por `ai-agents-setup`).
34
+
35
+ **Tipos confirmados via context7:**
36
+ - `AgentSession` — container leve de estado de conversa; obtido via `agent.CreateSessionAsync()`
37
+ - `AgentThread` — equivalente para agentes persistentes (PersistentAgentsClient); use `agent.GetNewThread()`
38
+ - `ChatClientAgentOptions` — aceita `ChatHistoryProvider` e `AIContextProviders`
39
+ - `InMemoryChatHistoryProvider` — implementação embutida de histórico em memória
40
+ - `AgentResponse` — tipo retornado por `AIAgent.RunAsync` (non-generic); acesse o texto via `.Text`
41
+
42
+ ```csharp
43
+ // Construção do agente com histórico em memória
44
+ AIAgent agent = _modelRegistry.GetChatClient("text-default")
45
+ .AsAIAgent(new ChatClientAgentOptions
46
+ {
47
+ ChatOptions = new() { Instructions = "You are a helpful assistant." },
48
+ ChatHistoryProvider = new InMemoryChatHistoryProvider(),
49
+ });
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Exemplo C# — agente conversacional com session persistente entre turnos
55
+
56
+ ```csharp
57
+ using Microsoft.Agents.AI;
58
+ using Microsoft.Extensions.AI;
59
+
60
+ // ── 1. Registrar o agente conversacional no DI ──
61
+ // Program.cs
62
+ builder.Services.AddSingleton<AIAgent>(sp =>
63
+ {
64
+ var registry = sp.GetRequiredService<ModelRegistry>();
65
+ return registry.GetChatClient("text-default")
66
+ .AsAIAgent(new ChatClientAgentOptions
67
+ {
68
+ ChatOptions = new() { Instructions = "You are a helpful customer support assistant." },
69
+ // InMemoryChatHistoryProvider: histórico vive em memória, por session.
70
+ // Seguro registrar como parte do singleton AIAgent: cada AgentSession criada via
71
+ // agent.CreateSessionAsync() isola o histórico de sua conversa — conversas distintas
72
+ // não compartilham estado. O provider em si é stateless; o estado fica na session.
73
+ // Para persistência entre restarts, substitua por um provider customizado (ex: DB).
74
+ ChatHistoryProvider = new InMemoryChatHistoryProvider(),
75
+ });
76
+ });
77
+
78
+ // ── 2. Criar uma session por conversa (ex: por conexão SignalR / por request de "start chat") ──
79
+ // ChatController.cs ou ChatHub.cs
80
+ public class ChatService(AIAgent _agent)
81
+ {
82
+ // Uma session por conversa ativa — armazene no escopo do usuário (cache, memória da conexão)
83
+ public async Task<AgentSession> StartConversationAsync()
84
+ => await _agent.CreateSessionAsync();
85
+
86
+ // Cada mensagem do usuário passa a mesma session
87
+ public async Task<string> SendMessageAsync(AgentSession session, string userMessage)
88
+ {
89
+ AgentResponse response = await _agent.RunAsync(userMessage, session);
90
+ return response.Text;
91
+ }
92
+ }
93
+
94
+ // ── 3. Uso no controller/hub ──
95
+ // Primeiro turno
96
+ AgentSession session = await chatService.StartConversationAsync();
97
+ string reply1 = await chatService.SendMessageAsync(session, "Meu pedido #1234 está atrasado.");
98
+ // reply1: "Vou verificar o pedido #1234 para você..."
99
+
100
+ // Segundo turno — o agente lembra do contexto anterior
101
+ string reply2 = await chatService.SendMessageAsync(session, "E quando foi despachado?");
102
+ // reply2: "O pedido #1234 foi despachado em..." ← contexto mantido pela session
103
+ ```
104
+
105
+ ---
106
+
107
+ ## History management
108
+
109
+ O histórico cresce a cada turno. Quando estoura o context window do modelo, as chamadas falham ou truncam silenciosamente.
110
+
111
+ ### Estratégias
112
+
113
+ | Estratégia | Quando usar | Como implementar |
114
+ |------------|-------------|------------------|
115
+ | **Sliding window** | Conversas longas com contexto recente suficiente | Limitar `InMemoryChatHistoryProvider` a N mensagens mais recentes |
116
+ | **Token budget** | Modelos com context window pequeno | Contar tokens acumulados; truncar quando ultrapassa threshold |
117
+ | **Summarization** | Histórico precisa de contexto antigo comprimido | Agente periódico que resume N turnos anteriores em uma mensagem única |
118
+
119
+ > **Custom history management:** Para o caso comum, `InMemoryChatHistoryProvider` cobre a
120
+ > necessidade de histórico em memória por sessão. Se o projeto exigir truncation customizada
121
+ > (ex: sliding window limitando a N mensagens mais recentes ou por token budget), o mecanismo
122
+ > de extensão correto — seja subclasse de `ChatHistoryProvider`, um `IChatReducer`, ou outro
123
+ > ponto de override — deve ser verificado contra a versão instalada de `Microsoft.Agents.AI`.
124
+ > Consulte a documentação MAF atual antes de implementar um provider customizado, pois a API
125
+ > exata de extensão não foi confirmada na versão GA e pode variar entre releases.
126
+
127
+ ---
128
+
129
+ ## Anti-patterns
130
+
131
+ | Anti-pattern | Problema |
132
+ |-------------|----------|
133
+ | Adicionar session em agente one-shot (gerador, executor) | Complexidade desnecessária; estado nunca é usado |
134
+ | Histórico ilimitado sem truncation | Context window estoura; custo aumenta linearmente com a conversa |
135
+ | Compartilhar uma `AgentSession` entre múltiplos usuários | Histórico de um usuário vaza para outro |
136
+ | Usar `InMemoryChatHistoryProvider` sem criar uma `AgentSession` por conversa | Sem `AgentSession` por conversa, o histórico é compartilhado entre todos os usuários; a isolation depende de `AgentSession` — sempre crie uma session por conversa via `agent.CreateSessionAsync()` |
137
+ | Usar `AgentThread` (PersistentAgentsClient) sem necessidade | `AgentThread` requer hosted agent service; prefira `AgentSession` com direct model |
138
+
139
+ ---
140
+
141
+ ## Checklist (verifiable by morph-eval)
142
+
143
+ - [ ] `AgentSession` usada somente em agentes conversacionais com UI de chat real
144
+ - [ ] `InMemoryChatHistoryProvider` (ou equivalente) registrado em `ChatClientAgentOptions`
145
+ - [ ] Uma `AgentSession` por conversa/usuário — nunca compartilhada
146
+ - [ ] Estratégia de truncation definida (sliding window, token budget ou summarization)
147
+ - [ ] Agentes one-shot (gerador, executor, classificador) **não** recebem session
148
+
149
+ ---
150
+
151
+ ## References
152
+
153
+ - `ai-agents-setup` — packages e DI base
154
+ - `ai-agents-sweet-spot` — decisão de quando adicionar estado ao agente
155
+ - `ai-agents-middleware-patterns` (Onda 2) — pipeline de contexto e middleware
156
+ - MAF Conversations docs: https://learn.microsoft.com/en-us/agent-framework/agents/conversations/
157
+
158
+ ---
159
+
160
+ *MORPH-SPEC by Polymorphism Tech — ai-agents/agent-session.md v1.0 (2026-05-19)*