## 1. Add Semantic Kernel Dependencies - [x] 1.1 Add `Microsoft.SemanticKernel` and `Microsoft.SemanticKernel.Connectors.OpenAI` NuGet packages to `ChatAgent.Api` - [x] 1.2 Remove the `OpenAI` SDK package if no longer needed after migration ## 2. Define Extraction Schema - [x] 2.1 Create `ExtractedFields` class in `ChatAgent.Shared/Models/` with the predefined set of key-value fields (placeholder fields until real schema is provided) - [x] 2.2 Create `ValidationResult` class in `ChatAgent.Shared/Models/` with `IsValid`, `Errors` properties ## 3. Create Extraction Plugin - [x] 3.1 Create `ExtractionPlugin` class in `ChatAgent.Api/Plugins/` with a `[KernelFunction]` validation method that checks `ExtractedFields` for required fields and type correctness - [x] 3.2 Add inline tutorial comments explaining SK plugin concepts (`[KernelFunction]`, `[Description]`, auto-invocation) ## 4. Wire Semantic Kernel in Program.cs - [x] 4.1 Register `OpenAIChatCompletionService` in DI using `ResponsesApi:BaseUrl` and `ResponsesApi:Model` from config - [x] 4.2 Register `Kernel` with `AddKernel()` and import `ExtractionPlugin` - [x] 4.3 Add inline tutorial comments explaining kernel setup, connectors, and plugin registration ## 5. Rewrite ChatController - [x] 5.1 Replace `IHttpClientFactory` and `IConfiguration` injection with `Kernel` injection - [x] 5.2 Replace manual HTTP proxy logic with `IChatCompletionService.GetStreamingChatMessageContentsAsync()` using the conversation history from the request - [x] 5.3 Configure `OpenAIPromptExecutionSettings` with `FunctionChoiceBehavior.Auto()` and `autoInvokeMaxCallCount = 3` - [x] 5.4 Re-emit streaming content as the existing SSE format (`data: {"text":"..."}\n\n` and `data: [DONE]\n\n`) - [x] 5.5 Add inline tutorial comments explaining streaming chat completion, execution settings, and tool call behavior ## 6. Update Tests - [x] 6.1 Update `ChatControllerTests` to mock `IChatCompletionService` instead of upstream HTTP calls - [x] 6.2 Add tests for the validation plugin (`ExtractionPlugin` returns correct pass/fail results) - [x] 6.3 Add a test verifying the agent escalates to the user after max retries ## 7. Verify - [x] 7.1 Run `dotnet build` to confirm no errors - [x] 7.2 Run `dotnet test` to confirm all tests pass - [ ] 7.3 Manual smoke test: send a chat message and verify streaming still works end-to-end through SK