Skip to content

[agents] refactor to use IChatClient Abstractions#1110

Draft
cleftheris wants to merge 17 commits into
developfrom
fix/agents-sources
Draft

[agents] refactor to use IChatClient Abstractions#1110
cleftheris wants to merge 17 commits into
developfrom
fix/agents-sources

Conversation

@cleftheris

Copy link
Copy Markdown
Contributor

No description provided.

cleftheris and others added 7 commits July 14, 2026 16:15
SourcesHandlers now sets utf-8 charset for text content types when returning files. SourceLinkGenerator injects IConfiguration and generates fully qualified URLs for local sources by prepending the host from configuration.
Refactored chat and document models to support richer, multi-part message content and improved metadata. Updated Angular frontend, EF Core mappings, and service layer for new structures. Added preferred categories to profiles. Updated OpenAPI schema and TypeScript client. Introduced session API skeleton. Removed legacy models and cleaned up references.
Refactor ChatMessageContent mapping to use a custom ValueComparer with explicit JSON serialization/deserialization, improving value comparison and change tracking. Add [JsonPropertyName] attributes to ChatMessageContent and ChatMessagePart. Update PreferredCategories mapping to a primitive collection without explicit column type. Add necessary using directives and clarify code with comments and TODOs.
Renamed DbSet from SessionMessages to Messages for consistency. Updated SessionsStore to use the new DbSet name. Replaced custom JSON serialization and ValueComparer in DbMessageMap with EF Core's ComplexProperty and ToJson() for Content. Simplified mapping by leveraging EF Core's improved support for complex types and JSON serialization.
A new block renders citations for each message in the chat thread. If citations exist, a container with citation spans (tracked by chunkId) is shown after the message content. This enhances message context and traceability.
* Migrate to Microsoft.Extensions.AI abstractions

Refactored codebase to replace custom chat models and Azure.AI.OpenAI usage with Microsoft.Extensions.AI types and OpenAI client integration. Updated service registration, workflow steps, and persistence logic to use new abstractions. Removed obsolete files and updated dependencies to Microsoft.Extensions.AI 10.8.0. Streamlined message and event models for improved compatibility and maintainability.

* Switch to AzureOpenAIClient and update dependencies

Replaced OpenAIClient with AzureOpenAIClient for chat and embedding services. Updated all related service registrations. Added Azure.AI.OpenAI 2.9.0-beta.1 NuGet package.

* Preserve type for "failed" and remove unused using

Changed "failed" in AdditionalProperties to retain its original type in ChatsService.cs. Removed an unused using directive from OutOfScopeResponder.cs for cleaner code.

* Refactor pipeline to use record-based state and chat client

Refactored codebase to remove custom pipeline envelope and state types in favor of ConversationState, IntentState, and direct payload records. Replaced IDexRunner/DexRunner with IDexChatClient/DexChatClient, aligning with Microsoft.Extensions.AI chat abstractions. Updated all pipeline step executors and workflow context to use new state and payload handling. Revised service registration and ChatsService to use new chat client and response types. Improved maintainability and reduced boilerplate by adopting the new chat pipeline model.

* Refactor chat event citation/source handling

Citations and sources are now extracted from `final?.AdditionalProperties` in `ChatsService.cs` instead of defaulting to empty arrays. In `DexChatClient.cs`, the final chat response's `RawRepresentation` is simplified, and citations/sources are added to `AdditionalProperties`. All event class definitions are removed from `DexStreamEvent.cs`, reflecting a shift to a new event handling mechanism.
Comment thread src/Indice.Features.Agents.Core/Services/ChatsService.cs Fixed
Comment on lines +58 to +60
var persistedAssistant = await _store.AppendTurnAsync(session.Id, userMessage, result.Messages.First(),
promptTokens: result.Usage?.InputTokenCount ?? 0, completionTokens: result.Usage?.OutputTokenCount ?? 0,
modelUsed: result.ModelUsed ?? _deployments.Reasoning, cancellationToken);

return new ChatResponse {
SessionId = session.Id,
MessageId = persistedAssistant.Id,
Answer = assistantText,
Citations = result.Citations ?? [],
Sources = result.Sources ?? [],
Failed = result.Failed,
FailureReason = result.FailureReason,
QuestionsUsed = _sessionOptions.GetQuestionsUsed(session.MessageCount + 2),
QuestionsTotal = _sessionOptions.GetQuestionsTotal(),
modelUsed: result.ModelId ?? _deployments.Reasoning, cancellationToken);
Refactored IntentOutput from a mutable class to an immutable record with positional parameters (Intent, Filters). Updated IntentClassifier to use the new record constructor and moved XML documentation to the record definition.
Consolidated default pipeline registration into AgentsFeatureExtensions and removed DefaultDexPipeline.cs. Replaced RagPipelineOutput and QueryRewriteOutput classes with C# record types for immutability. Updated all pipeline steps and DexChatClient to use new output types and improved dependency injection. Cleaned up unused usings and enhanced documentation comments.
- Moved core data models (e.g., Chunk, Intent) to Indice.Features.Agents.Core.Models for better separation of concerns.
- Relocated ingestion pipeline and related types to Indice.Features.Agents.Core.Workflows.Ingestion.
- Renamed DefaultIngestionPipeline to IngestionPipeline and updated DI registration.
- Extracted FAQ and Markdown chunking logic into FaqChunker and MarkdownChunker classes.
- Moved interface definitions (IIngestionPipeline, ILlmReranker, IDexChatClient) to their respective files and namespaces.
- Updated all usages and imports to reflect new structure.
- Improves modularity, maintainability, and code clarity.
Refactored chat client by replacing DexChatClient with AgentsChatClient using a unified event model for streaming and non-streaming responses. Updated dependency injection and ChatsService to support new event types. Changed AnswerComposer and PurposeResponder to emit AgentResponseUpdateEvent. Enhanced Citation model with Snippet and SourceUrl. Updated tests for new ingestion pipeline and added AIContentTests with sample PNG. Cleaned up usings and XML docs.
Introduced StepProgressContent, a sealed class for ephemeral workflow step progress updates during streaming. AgentsChatClient now emits StepProgressContent instead of TextReasoningContent at step start. GetResponseAsync filters out StepProgressContent from final ChatResponse. Improved code clarity with comments and debugger displays.
Replaced all "Session" terminology with "Conversation" for improved clarity and alignment with chat app conventions. Renamed classes, interfaces, DTOs, and updated all references, method names, and parameters. Added new conversation-based files and removed obsolete session-based logic. Updated database mappings to use ConversationId. Refactored business logic, DI, and controllers to operate on conversations. Improved chat client error handling and added citation annotation logic in answer composer. Ensured all usage guards, history providers, and token accounting reference conversations. Includes minor enhancements and bug fixes.
Comment thread src/Indice.Features.Agents.Core/Services/ChatsService.cs Fixed
Comment on lines +113 to +138
foreach (Match group in Regex.Matches(answer, @"<sup>(.*?)</su\w*>", RegexOptions.Singleline)) {
var inner = group.Groups[1];
foreach (Match marker in Regex.Matches(inner.Value, @"\[(\d+)\](?:\(#([0-9a-fA-F\-]{36})\))?")) {
Models.Citation? citation = null;
if (marker.Groups[2].Success && Guid.TryParse(marker.Groups[2].Value, out var chunkId)) {
citationsByChunkId.TryGetValue(chunkId, out citation);
}
if (citation is null && int.TryParse(marker.Groups[1].Value, out var number)) {
citationsByNumber.TryGetValue(number, out citation);
}
if (citation is null) {
continue;
}
// Annotate the whole marker ([n] or [n](#chunkId)) at its absolute position in the answer.
var start = inner.Index + marker.Index;
var end = start + marker.Length;
annotations.Add(new CitationAnnotation {
Title = citation.Title,
Url = Uri.TryCreate(citation.SourceUrl, UriKind.Absolute, out var url) ? url : null,
FileId = citation.ChunkId.ToString(),
Snippet = citation.Snippet,
AnnotatedRegions = [new TextSpanAnnotatedRegion { StartIndex = start, EndIndex = end }],
RawRepresentation = citation
});
}
}
Refactor chat turn handling to accept and persist ChatResponse objects, enabling consistent storage of usage details and response IDs. Update DbMessage with optional ResponseId for reply chains. Revise streaming logic to collect and persist complete responses, use StepProgressContent for updates, and clean up unused code. Improve naming consistency and update ToDb helper for new structure.
Comment thread src/Indice.Features.Agents.Core/Services/ChatsService.cs Fixed
KrikTze and others added 3 commits July 21, 2026 18:29
Refactored chat API to use new product-focused DTOs (`DexChatResponse`, `DexChatMessage`, `DexConversation`) with explicit token usage and session counters. Renamed token and question counter properties for clarity. Updated service interfaces, handlers, and database mappings. Added conversion logic and unit tests to ensure mapping fidelity. Improves API clarity and client usability.
The Conversation class was relocated from Session.cs to a new file, Conversation.cs. All related code and documentation were moved without modification.
Removed the unnecessary using directive for Azure in AgentsChatClient.cs. All other using directives remain unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants