Files
AgenticCode/openspec/changes/archive/2026-04-04-migrate-to-semantic-kernel/tasks.md
local 471e9ce935 feat: migrate chat backend to Semantic Kernel with tool calling support
Replace manual HTTP proxy in ChatController with Semantic Kernel's
OpenAI chat completion service pointed at CLIProxyAPI. Add extraction
plugin with validation function for structured field extraction from
natural language, enabling an agentic loop with auto-retry and
human-in-the-loop escalation.

- Add Microsoft.SemanticKernel 1.74.0 with OpenAI connector
- Create ExtractedFields schema and ValidationResult models
- Create ExtractionPlugin with [KernelFunction] validation
- Rewrite ChatController to use IChatCompletionService streaming
- Configure FunctionChoiceBehavior.Auto() for tool calling
- Preserve existing SSE contract (client unchanged)
- Update tests to mock SK services, add plugin and integration tests
- Archive multi-turn-conversations and migrate-to-semantic-kernel changes
- Sync specs for agent-extraction, semantic-kernel-integration, chat-streaming

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 23:59:13 +01:00

41 lines
2.3 KiB
Markdown

## 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