Skip to content

Conversation

@marc-romu
Copy link
Member

@marc-romu marc-romu commented Aug 25, 2025

Description

This PR delivers a major architectural refactor and feature set focused on conversation orchestration, centralized validation, streaming, and model management. Changes are summarized and grouped below based on commit messages and the [Unreleased] section in CHANGELOG.md.

  • Architecture & Core
    • ConversationSession service: IConversationSession, IConversationObserver, SessionOptions; multi‑turn and tool orchestration with observer callbacks; single source of truth for long‑running interactions.
    • PolicyPipeline (always‑on): request/response policies including compatibility decode, timeout, schema attach/validate, tool validation, and context normalization.
    • Immutable AIBody with AIBodyBuilder; AIRequestKind to distinguish generation vs backoffice flows.
    • AIRequestCall.Exec() clarified as single‑turn; multi‑turn flows handled via ConversationSession.
    • JSON Schema service and provider adapters to automatically attach/validate schemas.
  • Streaming
    • Unified streaming via AIProviderStreamingAdapter; OpenAI streaming adapter now derives from the shared base.
    • Centralized streaming capability checks in ModelManager.ModelSupportsStreaming(...).
    • ConversationSession.Stream() clearly gates unsupported models and emits actionable errors.
    • WebChat streaming robustness and metrics propagation; partial updates surfaced and merged correctly in UI.
  • Validation & Tooling
    • Tool validators: existence, JSON schema, capability checks.
    • Structured AIMessageCode surfaced through AIRuntimeMessage and consumed by components (e.g., badges).
    • Centralized validation in PolicyPipeline; simplified AIToolCall and AIRequest validation.
  • Model Management & Selection
    • Provider‑scoped model selection: IAIProvider.SelectModel(...) delegates to centralized ModelManager.SelectBestModel while honoring provider defaults/settings.
    • Models retrieved via IAIProviderModels.RetrieveModels() and registered centrally.
    • Capability names consolidated: Text2Text, ToolChat, ReasoningChat, ToolReasoningChat, Text2Json, Text2Image, Text2Speech, Speech2Text, Image2Text.
    • Verified/replaced/invalid model badge logic aligned with capability checks and selection fallbacks.
  • Components & UI
    • AIChat: live outputs for chat history and metrics; unified snapshot management; synchronized metrics output with chat.
    • Badges: early surfacing of invalid/replaced/verified states; error codes drive badge decisions.
    • CanvasButton: user setting to enable/disable; stable dialog GUID for reuse.
    • WebChat: reasoning-only rendering; improved chunking behavior on first and subsequent stream parts.
  • Providers
    • OpenAI/Mistral/DeepSeek adapters updated for schema/streaming/validation integration.
    • Defaults and verified models updated (e.g., OpenAI defaults).
    • Provider settings include EnableStreaming.
  • Tests & Docs
    • New data processing test components and expectations.
    • Added tests for Model/Context managers.
    • Documentation updates and reorganization aligned with new architecture.
  • Fixes
    • Eliminates “Invalid model” due to wildcard defaults.
    • Stabilizes WebChat and streaming metrics propagation.
    • Corrects list_generate result output and image output propagation to ImageViewer.
    • Improves build stability and infrastructure resilience.

Breaking Changes

  • AIRequestCall.Exec() is now explicitly single‑turn; multi‑turn/tool passes require ConversationSession.
  • Capability identifiers renamed (Text2Text, ToolChat, ReasoningChat, ToolReasoningChat, Text2Json, Text2Image, Text2Speech, Speech2Text, Image2Text).
  • Legacy provider model methods removed: RetrieveAvailable, RetrieveCapabilities, RetrieveDefault in favor of RetrieveModels() and centralized ModelManager.
  • Removed TemplateProvider and AIToolCall.ReplaceReuseCount() (unified metrics handling).

Testing Done

  • Built solution and ran chat flows with streaming enabled/disabled; verified metrics propagation in UI. <- still some bugs
  • Validated badge states for invalid/replaced/verified across providers/models. <- needs redesign some badges
  • Exercised data processing test components; fixed expectations. <- one component fails the test
  • Manually verified image output flow to ImageViewer.
  • Confirmed schema attach/validation and tool call validation via PolicyPipeline.

Checklist

  • This PR is focused on a single feature or bug fix
  • Version in Solution.props was updated, if necessary, and follows semantic versioning
  • CHANGELOG.md has been updated
  • PR title follows Conventional Commits format
  • PR description follows Pull Request Description Template

…ts with observers and multi-turn flows and tool passes
…/tools

- Remove legacy AICall types under Infrastructure/AICall/*
- Update components, GH tools, and providers to new Core namespaces
- Tweak ConversationSession and interfaces accordingly
- Refresh docs/Tools/index.md and CHANGELOG entries
…een generation and backoffice calls which validate differently
Copilot AI review requested due to automatic review settings August 25, 2025 22:21
@github-actions github-actions bot added this to the 0.6.0-alpha milestone Aug 25, 2025
@github-actions
Copy link
Contributor

🏷️ This PR has been automatically assigned to milestone 0.6.0-alpha based on the version in Solution.props.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a major architectural refactor focused on conversation orchestration, streaming capabilities, and centralized validation. The changes implement ConversationSession as the primary orchestrator for multi-turn conversations with tool execution, while maintaining backward compatibility through existing AIRequestCall for single-turn operations.

Key changes include:

  • ConversationSession architecture: New session-based orchestration with observer patterns for multi-turn conversations and tool execution
  • Unified streaming framework: Provider-agnostic streaming adapters with centralized capability checks and consistent delta emission
  • Centralized validation and policy pipeline: Request/response policies for schema validation, tool validation, and response normalization

Reviewed Changes

Copilot reviewed 164 out of 164 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Provider settings files Added EnableStreaming setting across OpenAI, MistralAI, and DeepSeek providers
Provider model files Updated model capabilities and added RetrieveApiModels() method implementations
Provider main files Added streaming adapters and centralized JSON schema handling
JSON schema adapters New provider-specific schema wrapping/unwrapping logic
Assistant settings Added canvas button toggle and reorganized settings structure
Streaming infrastructure New IStreamingAdapter interface and base classes for provider streaming
Validation framework Comprehensive tool and schema validators with structured error reporting
Session management ConversationSession implementation for multi-turn orchestration
Policy pipeline Request/response policies for centralized validation and normalization
Metrics framework Enhanced metrics tracking with correlation and domain-specific records
Comments suppressed due to low confidence (1)

src/SmartHopper.Infrastructure/AICall/Sessions/ConversationSession.cs:1

  • The timeout logic creates a potential memory leak as the original execTask continues running even after timeout. Consider implementing proper cancellation token propagation to AIToolManager.ExecuteTool() to actually cancel the underlying work.
/*

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

};

// Rebuild body immutably with context as first item and filter-out any pre-existing context interactions
var rest = body.Interactions?.Where(i => i != null && i.Agent != AIAgent.Context) ?? Enumerable.Empty<IAIInteraction>();
Copy link

Copilot AI Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LINQ Where clause filters out existing context interactions, but this creates a new enumerable each time. Consider materializing this to a list if the collection will be enumerated multiple times in AddRange().

Suggested change
var rest = body.Interactions?.Where(i => i != null && i.Agent != AIAgent.Context) ?? Enumerable.Empty<IAIInteraction>();
var rest = body.Interactions?.Where(i => i != null && i.Agent != AIAgent.Context).ToList() ?? new List<IAIInteraction>();

Copilot uses AI. Check for mistakes.
Comment on lines 352 to 355
if (interaction is AIInteractionToolCall || interaction is AIInteractionToolResult)
{
this.Request.Body = this.Request.Body.WithAppended(interaction);
}
Copy link

Copilot AI Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During streaming, the request body is being rebuilt repeatedly with each interaction. This creates multiple immutable copies. Consider batching these updates or using a more efficient accumulation strategy.

Copilot uses AI. Check for mistakes.
/// </summary>
public static class JsonSchemaAdapterRegistry
{
private static readonly ConcurrentDictionary<string, IJsonSchemaAdapter> _adapters = new ConcurrentDictionary<string, IJsonSchemaAdapter>(StringComparer.OrdinalIgnoreCase);
Copy link

Copilot AI Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The static ConcurrentDictionary for adapter registration could lead to issues in testing scenarios where adapters need to be reset between tests. Consider providing a Reset() method for test scenarios or making the registry injectable.

Copilot uses AI. Check for mistakes.
@marc-romu marc-romu merged commit 5208484 into dev Aug 25, 2025
10 checks passed
@github-actions github-actions bot deleted the feature/0.6.0-conversation-session branch August 25, 2025 22:31
@marc-romu marc-romu modified the milestones: 0.6.0-alpha, 1.0.0-alpha Oct 11, 2025
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.

2 participants