@polymorphism-tech/morph-spec 1.0.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +1381 -0
- package/LICENSE +72 -0
- package/README.md +89 -6
- package/bin/detect-agents.js +225 -0
- package/bin/morph-spec.js +120 -0
- package/bin/render-template.js +302 -0
- package/bin/semantic-detect-agents.js +246 -0
- package/bin/validate-agents-skills.js +239 -0
- package/bin/validate-agents.js +69 -0
- package/bin/validate-phase.js +263 -0
- package/content/.azure/README.md +293 -0
- package/content/.azure/docs/azure-devops-setup.md +454 -0
- package/content/.azure/docs/branch-strategy.md +398 -0
- package/content/.azure/docs/local-development.md +515 -0
- package/content/.azure/pipelines/pipeline-variables.yml +34 -0
- package/content/.azure/pipelines/prod-pipeline.yml +319 -0
- package/content/.azure/pipelines/staging-pipeline.yml +234 -0
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -0
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -0
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -0
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -0
- package/content/.claude/commands/morph-apply.md +118 -26
- package/content/.claude/commands/morph-archive.md +9 -9
- package/content/.claude/commands/morph-clarify.md +184 -0
- package/content/.claude/commands/morph-design.md +275 -0
- package/content/.claude/commands/morph-proposal.md +56 -15
- package/content/.claude/commands/morph-setup.md +100 -0
- package/content/.claude/commands/morph-status.md +47 -32
- package/content/.claude/commands/morph-tasks.md +319 -0
- package/content/.claude/commands/morph-uiux.md +211 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +604 -0
- package/content/.claude/skills/specialists/ms-agent-expert.md +143 -89
- package/content/.claude/skills/specialists/ui-ux-designer.md +744 -9
- package/content/.claude/skills/stacks/dotnet-blazor.md +244 -8
- package/content/.claude/skills/stacks/dotnet-nextjs.md +2 -2
- package/content/.morph/.morphversion +5 -0
- package/content/.morph/config/agents.json +101 -8
- package/content/.morph/config/azure-pricing.json +70 -0
- package/content/.morph/config/azure-pricing.schema.json +50 -0
- package/content/.morph/config/config.template.json +15 -3
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -0
- package/content/.morph/hooks/README.md +239 -0
- package/content/.morph/hooks/pre-commit-agents.sh +24 -0
- package/content/.morph/hooks/pre-commit-all.sh +48 -0
- package/content/.morph/hooks/pre-commit-costs.sh +91 -0
- package/content/.morph/hooks/pre-commit-specs.sh +49 -0
- package/content/.morph/hooks/pre-commit-tests.sh +60 -0
- package/content/.morph/project.md +5 -4
- package/content/.morph/schemas/agent.schema.json +296 -0
- package/content/.morph/standards/agent-framework-setup.md +453 -0
- package/content/.morph/standards/architecture.md +142 -7
- package/content/.morph/standards/azure.md +218 -23
- package/content/.morph/standards/coding.md +47 -12
- package/content/.morph/standards/dotnet10-migration.md +494 -0
- package/content/.morph/standards/fluent-ui-setup.md +590 -0
- package/content/.morph/standards/migration-guide.md +514 -0
- package/content/.morph/standards/passkeys-auth.md +423 -0
- package/content/.morph/standards/vector-search-rag.md +536 -0
- package/content/.morph/state.json +18 -0
- package/content/.morph/templates/FluentDesignTheme.cs +149 -0
- package/content/.morph/templates/MudTheme.cs +281 -0
- package/content/.morph/templates/contracts.cs +55 -55
- package/content/.morph/templates/decisions.md +4 -4
- package/content/.morph/templates/design-system.css +226 -0
- package/content/.morph/templates/infra/.dockerignore.example +89 -0
- package/content/.morph/templates/infra/Dockerfile.example +82 -0
- package/content/.morph/templates/infra/README.md +286 -0
- package/content/.morph/templates/infra/app-service.bicep +164 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -0
- package/content/.morph/templates/infra/deploy.sh +208 -0
- package/content/.morph/templates/infra/main.bicep +41 -7
- package/content/.morph/templates/infra/parameters.dev.json +6 -0
- package/content/.morph/templates/infra/parameters.prod.json +6 -0
- package/content/.morph/templates/infra/parameters.staging.json +29 -0
- package/content/.morph/templates/proposal.md +3 -3
- package/content/.morph/templates/recap.md +3 -3
- package/content/.morph/templates/spec.md +9 -8
- package/content/.morph/templates/sprint-status.yaml +68 -0
- package/content/.morph/templates/state.template.json +222 -0
- package/content/.morph/templates/story.md +143 -0
- package/content/.morph/templates/tasks.md +1 -1
- package/content/.morph/templates/ui-components.md +276 -0
- package/content/.morph/templates/ui-design-system.md +286 -0
- package/content/.morph/templates/ui-flows.md +336 -0
- package/content/.morph/templates/ui-mockups.md +133 -0
- package/content/.morph/test-infra/example.bicep +59 -0
- package/content/CLAUDE.md +124 -0
- package/content/README.md +79 -0
- package/detectors/config-detector.js +223 -0
- package/detectors/conversation-analyzer.js +163 -0
- package/detectors/index.js +84 -0
- package/detectors/standards-generator.js +275 -0
- package/detectors/structure-detector.js +221 -0
- package/docs/README.md +149 -0
- package/docs/api/cost-calculator.js.html +513 -0
- package/docs/api/design-system-generator.js.html +382 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/api/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/api/global.html +5263 -0
- package/docs/api/index.html +96 -0
- package/docs/api/scripts/collapse.js +39 -0
- package/docs/api/scripts/commonNav.js +28 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/nav.js +12 -0
- package/docs/api/scripts/polyfill.js +4 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/scripts/search.js +99 -0
- package/docs/api/state-manager.js.html +423 -0
- package/docs/api/styles/jsdoc.css +776 -0
- package/docs/api/styles/prettify.css +80 -0
- package/docs/examples.md +328 -0
- package/docs/getting-started.md +302 -0
- package/docs/installation.md +361 -0
- package/docs/templates.md +418 -0
- package/docs/validation-checklist.md +266 -0
- package/package.json +39 -12
- package/src/commands/cost.js +181 -0
- package/src/commands/create-story.js +283 -0
- package/src/commands/detect.js +104 -0
- package/src/commands/doctor.js +67 -0
- package/src/commands/generate.js +149 -0
- package/src/commands/init.js +69 -45
- package/src/commands/shard-spec.js +224 -0
- package/src/commands/sprint-status.js +250 -0
- package/src/commands/state.js +333 -0
- package/src/commands/sync.js +167 -0
- package/src/commands/update-pricing.js +206 -0
- package/src/commands/update.js +88 -13
- package/src/lib/complexity-analyzer.js +292 -0
- package/src/lib/cost-calculator.js +429 -0
- package/src/lib/design-system-generator.js +298 -0
- package/src/lib/state-manager.js +340 -0
- package/src/utils/file-copier.js +59 -0
- package/src/utils/version-checker.js +175 -0
|
@@ -1,147 +1,198 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent Framework Expert
|
|
2
2
|
|
|
3
|
-
Especialista em Microsoft Agent Framework
|
|
3
|
+
Especialista em Microsoft Agent Framework e integração de IA em aplicações .NET.
|
|
4
|
+
|
|
5
|
+
> **IMPORTANTE:** O MORPH-SPEC usa **exclusivamente** Microsoft Agent Framework.
|
|
6
|
+
> Semantic Kernel foi descontinuado.
|
|
4
7
|
|
|
5
8
|
## Responsabilidades
|
|
6
9
|
|
|
7
|
-
1. **Integrar Microsoft Agent Framework** em projetos
|
|
8
|
-
2. **
|
|
10
|
+
1. **Integrar Microsoft Agent Framework** em projetos .NET 10
|
|
11
|
+
2. **Criar agentes** com instruções e tools
|
|
9
12
|
3. **Otimizar prompts** e gerenciar tokens
|
|
10
|
-
4. **
|
|
13
|
+
4. **Implementar RAG** com vector search
|
|
11
14
|
|
|
12
15
|
## Triggers
|
|
13
16
|
|
|
14
|
-
Keywords: `agent`, `ai`, `
|
|
17
|
+
Keywords: `agent`, `ai`, `llm`, `openai`, `chat`, `prompt`, `tool`, `function calling`, `rag`, `embedding`
|
|
15
18
|
|
|
16
|
-
## Microsoft Agent Framework
|
|
19
|
+
## Microsoft Agent Framework (.NET 10)
|
|
17
20
|
|
|
18
|
-
>
|
|
21
|
+
> Framework oficial da Microsoft para criar agentes de IA.
|
|
22
|
+
> Substitui Semantic Kernel com foco exclusivo em agentes.
|
|
19
23
|
|
|
20
24
|
### Estrutura Básica
|
|
21
25
|
|
|
22
26
|
```csharp
|
|
23
|
-
// Agent com
|
|
24
|
-
using Microsoft.
|
|
25
|
-
using Microsoft.
|
|
27
|
+
// Agent com Microsoft Agent Framework
|
|
28
|
+
using Microsoft.Agents.AI;
|
|
29
|
+
using Microsoft.Extensions.AI;
|
|
26
30
|
|
|
27
31
|
public class OrderAnalysisAgent
|
|
28
32
|
{
|
|
29
|
-
private readonly
|
|
33
|
+
private readonly IChatClient _chatClient;
|
|
34
|
+
private readonly ILogger<OrderAnalysisAgent> _logger;
|
|
30
35
|
|
|
31
|
-
public OrderAnalysisAgent(
|
|
36
|
+
public OrderAnalysisAgent(
|
|
37
|
+
IChatClient chatClient,
|
|
38
|
+
ILogger<OrderAnalysisAgent> logger)
|
|
32
39
|
{
|
|
33
|
-
|
|
40
|
+
_chatClient = chatClient;
|
|
41
|
+
_logger = logger;
|
|
34
42
|
}
|
|
35
43
|
|
|
36
|
-
public async Task<string> AnalyzeOrderAsync(Order order)
|
|
44
|
+
public async Task<string> AnalyzeOrderAsync(Order order, CancellationToken ct = default)
|
|
37
45
|
{
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
var agent = _chatClient.CreateAgent(
|
|
47
|
+
instructions: """
|
|
48
|
+
Você é um especialista em análise de pedidos.
|
|
49
|
+
|
|
50
|
+
Analise o pedido fornecido e retorne:
|
|
51
|
+
1. Resumo do pedido
|
|
52
|
+
2. Sugestões de upsell baseadas nos itens
|
|
53
|
+
3. Risco de cancelamento (baixo/médio/alto) com justificativa
|
|
54
|
+
|
|
55
|
+
Seja conciso e objetivo.
|
|
56
|
+
""",
|
|
57
|
+
name: "OrderAnalyzer"
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
var prompt = $"""
|
|
61
|
+
Pedido: {order.OrderNumber}
|
|
62
|
+
Total: {order.Total:C}
|
|
63
|
+
Itens: {order.Items.Count}
|
|
64
|
+
Cliente: {order.Customer.Name}
|
|
65
|
+
Histórico: {order.Customer.TotalOrders} pedidos anteriores
|
|
66
|
+
|
|
67
|
+
Analise este pedido.
|
|
50
68
|
""";
|
|
51
69
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
var result = await _kernel.InvokeAsync(function, new()
|
|
55
|
-
{
|
|
56
|
-
["orderNumber"] = order.OrderNumber,
|
|
57
|
-
["total"] = order.Total.ToString("C"),
|
|
58
|
-
["itemCount"] = order.Items.Count,
|
|
59
|
-
["customerName"] = order.Customer.Name
|
|
60
|
-
});
|
|
70
|
+
_logger.LogInformation("Analisando pedido {OrderNumber}", order.OrderNumber);
|
|
61
71
|
|
|
62
|
-
|
|
72
|
+
var response = await agent.RunAsync(prompt, cancellationToken: ct);
|
|
73
|
+
return response.Content;
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
```
|
|
66
77
|
|
|
67
|
-
### Configuração do
|
|
78
|
+
### Configuração do ChatClient
|
|
68
79
|
|
|
69
80
|
```csharp
|
|
70
81
|
// Program.cs
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
using Microsoft.Extensions.AI;
|
|
83
|
+
|
|
84
|
+
// Azure OpenAI
|
|
85
|
+
builder.Services.AddSingleton<IChatClient>(sp =>
|
|
86
|
+
{
|
|
87
|
+
var config = sp.GetRequiredService<IConfiguration>();
|
|
88
|
+
|
|
89
|
+
return new ChatClient(
|
|
90
|
+
model: "gpt-4o-mini",
|
|
91
|
+
credential: new ApiKeyCredential(config["AzureOpenAI:ApiKey"]!),
|
|
92
|
+
endpoint: new Uri(config["AzureOpenAI:Endpoint"]!)
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Registrar agent como service
|
|
97
|
+
builder.Services.AddScoped<IOrderAnalysisAgent, OrderAnalysisAgent>();
|
|
82
98
|
```
|
|
83
99
|
|
|
84
|
-
###
|
|
100
|
+
### Tools (Function Calling)
|
|
85
101
|
|
|
86
102
|
```csharp
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
using Microsoft.Agents.AI;
|
|
104
|
+
|
|
105
|
+
public class OrderAgent
|
|
89
106
|
{
|
|
107
|
+
private readonly IChatClient _chatClient;
|
|
90
108
|
private readonly IOrderService _orderService;
|
|
91
109
|
|
|
92
|
-
public
|
|
110
|
+
public OrderAgent(IChatClient chatClient, IOrderService orderService)
|
|
93
111
|
{
|
|
112
|
+
_chatClient = chatClient;
|
|
94
113
|
_orderService = orderService;
|
|
95
114
|
}
|
|
96
115
|
|
|
97
|
-
[
|
|
116
|
+
[AgentTool("get_order")]
|
|
98
117
|
[Description("Busca um pedido pelo número")]
|
|
99
118
|
public async Task<Order?> GetOrderAsync(
|
|
100
|
-
[Description("Número do pedido")] string orderNumber
|
|
119
|
+
[Description("Número do pedido")] string orderNumber,
|
|
120
|
+
CancellationToken ct = default)
|
|
101
121
|
{
|
|
102
|
-
return await _orderService.GetByNumberAsync(orderNumber);
|
|
122
|
+
return await _orderService.GetByNumberAsync(orderNumber, ct);
|
|
103
123
|
}
|
|
104
124
|
|
|
105
|
-
[
|
|
125
|
+
[AgentTool("calculate_discount")]
|
|
106
126
|
[Description("Calcula desconto baseado no histórico do cliente")]
|
|
107
127
|
public decimal CalculateDiscount(
|
|
108
128
|
[Description("ID do cliente")] int customerId,
|
|
109
129
|
[Description("Valor do pedido")] decimal orderTotal)
|
|
110
130
|
{
|
|
111
|
-
// Lógica de desconto
|
|
131
|
+
// Lógica de desconto baseada em histórico
|
|
112
132
|
return orderTotal * 0.1m;
|
|
113
133
|
}
|
|
114
|
-
}
|
|
115
134
|
|
|
116
|
-
|
|
117
|
-
|
|
135
|
+
public async Task<string> ChatAsync(string userMessage, CancellationToken ct = default)
|
|
136
|
+
{
|
|
137
|
+
var agent = _chatClient.CreateAgent(
|
|
138
|
+
instructions: """
|
|
139
|
+
Você é um assistente de pedidos.
|
|
140
|
+
Use as tools disponíveis para ajudar os usuários.
|
|
141
|
+
Seja conciso e profissional.
|
|
142
|
+
""",
|
|
143
|
+
name: "OrderAssistant",
|
|
144
|
+
tools: new[]
|
|
145
|
+
{
|
|
146
|
+
AgentTool.FromMethod(nameof(GetOrderAsync), this),
|
|
147
|
+
AgentTool.FromMethod(nameof(CalculateDiscount), this)
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
var response = await agent.RunAsync(userMessage, cancellationToken: ct);
|
|
152
|
+
return response.Content;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
118
155
|
```
|
|
119
156
|
|
|
120
|
-
###
|
|
157
|
+
### Threads (Conversação Persistente)
|
|
121
158
|
|
|
122
159
|
```csharp
|
|
123
|
-
|
|
124
|
-
var agent = new ChatCompletionAgent
|
|
125
|
-
{
|
|
126
|
-
Name = "OrderAssistant",
|
|
127
|
-
Instructions = """
|
|
128
|
-
Você é um assistente de pedidos. Ajude os usuários a:
|
|
129
|
-
- Consultar status de pedidos
|
|
130
|
-
- Calcular descontos
|
|
131
|
-
- Sugerir produtos relacionados
|
|
132
|
-
|
|
133
|
-
Seja conciso e profissional.
|
|
134
|
-
""",
|
|
135
|
-
Kernel = kernel
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// Conversa
|
|
139
|
-
var history = new ChatHistory();
|
|
140
|
-
history.AddUserMessage("Qual o status do pedido #12345?");
|
|
141
|
-
|
|
142
|
-
await foreach (var message in agent.InvokeAsync(history))
|
|
160
|
+
public class ChatService
|
|
143
161
|
{
|
|
144
|
-
|
|
162
|
+
private readonly IChatClient _chatClient;
|
|
163
|
+
private readonly Dictionary<string, AgentThread> _threads = new();
|
|
164
|
+
|
|
165
|
+
public async Task<string> CreateConversationAsync(string userId)
|
|
166
|
+
{
|
|
167
|
+
var agent = _chatClient.CreateAgent(
|
|
168
|
+
instructions: "Você é um assistente útil e amigável.",
|
|
169
|
+
name: "ChatAssistant"
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
var thread = await agent.CreateThreadAsync();
|
|
173
|
+
_threads[userId] = thread;
|
|
174
|
+
|
|
175
|
+
return thread.Id;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
public async Task<string> SendMessageAsync(
|
|
179
|
+
string userId,
|
|
180
|
+
string message,
|
|
181
|
+
CancellationToken ct = default)
|
|
182
|
+
{
|
|
183
|
+
if (!_threads.TryGetValue(userId, out var thread))
|
|
184
|
+
throw new InvalidOperationException("Thread não encontrada");
|
|
185
|
+
|
|
186
|
+
var agent = _chatClient.CreateAgent(
|
|
187
|
+
instructions: "Você é um assistente útil e amigável.",
|
|
188
|
+
name: "ChatAssistant"
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
await thread.AddMessageAsync(message, ct);
|
|
192
|
+
var response = await agent.RunAsync(thread, cancellationToken: ct);
|
|
193
|
+
|
|
194
|
+
return response.Content;
|
|
195
|
+
}
|
|
145
196
|
}
|
|
146
197
|
```
|
|
147
198
|
|
|
@@ -187,22 +238,25 @@ var systemPrompt = """
|
|
|
187
238
|
|
|
188
239
|
## Documentação de Referência
|
|
189
240
|
|
|
190
|
-
- [Microsoft Agent Framework](https://learn.microsoft.com/
|
|
241
|
+
- [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/)
|
|
191
242
|
- [Agent Framework GitHub](https://github.com/microsoft/agent-framework)
|
|
192
|
-
- [
|
|
193
|
-
- [
|
|
194
|
-
- [
|
|
243
|
+
- [Microsoft.Extensions.AI](https://learn.microsoft.com/dotnet/ai/ai-extensions)
|
|
244
|
+
- [Azure OpenAI Service](https://learn.microsoft.com/azure/ai-services/openai/)
|
|
245
|
+
- **[Guia Completo: Agent Framework Setup](../../.morph/standards/agent-framework-setup.md)**
|
|
195
246
|
|
|
196
247
|
## Checklist de Integração AI
|
|
197
248
|
|
|
198
|
-
- [ ]
|
|
249
|
+
- [ ] Package `Microsoft.Agents.AI` instalado
|
|
250
|
+
- [ ] `IChatClient` configurado com DI
|
|
199
251
|
- [ ] Modelo gpt-4o-mini como padrão
|
|
200
252
|
- [ ] API keys no Key Vault (não hardcoded)
|
|
201
|
-
- [ ]
|
|
253
|
+
- [ ] Agents registrados como services
|
|
254
|
+
- [ ] Tools registradas manualmente
|
|
202
255
|
- [ ] System prompt estruturado
|
|
203
256
|
- [ ] Error handling para rate limits
|
|
204
257
|
- [ ] Logging de prompts/responses (dev only)
|
|
205
258
|
- [ ] Custos estimados por operação
|
|
259
|
+
- [ ] **NÃO usar Semantic Kernel**
|
|
206
260
|
|
|
207
261
|
---
|
|
208
262
|
|