Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,27 @@ public sealed class ChatMessageCompletedContext
/// Gets the AI profile that was used.
/// </summary>
public required AIProfile Profile { get; init; }

/// <summary>
/// Gets the current chat session.
/// </summary>
public required AIChatSession ChatSession { get; init; }

/// <summary>
/// Gets the prompts associated with the current chat session.
/// </summary>
public required IReadOnlyList<AIChatSessionPrompt> Prompts { get; init; }

/// <summary>
/// Gets or sets the time in milliseconds the AI took to generate the response.
/// </summary>
public double ResponseLatencyMs { get; init; }

/// <summary>
/// Gets or sets the number of input tokens used in this completion.
/// </summary>
public int InputTokenCount { get; init; }

/// <summary>
/// Gets or sets the number of output tokens generated in this completion.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.AI;

namespace CrestApps.Core.AI.Clients;

/// <summary>
/// Provides methods to obtain AI chat clients and embedding generators for specific providers.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public sealed class AIChatSession : ExtensibleEntity
public DateTime LastActivityUtc { get; set; }

/// <summary>
/// Gets or sets the UTC date and time when the session was closed due to inactivity.
/// Gets or sets the UTC date and time when the session ended.
/// </summary>
public DateTime? ClosedAtUtc { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,89 +10,109 @@ public sealed class AIChatSessionEvent : ExtensibleEntity
/// Gets or sets the unique identifier for the chat session this event is associated with.
/// </summary>
public string SessionId { get; set; }

/// <summary>
/// Gets or sets the AI profile identifier used in this session.
/// </summary>
public string ProfileId { get; set; }

/// <summary>
/// Gets or sets the persistent anonymous visitor identifier.
/// Generated on the client side and stored in localStorage for cross-session tracking.
/// </summary>
public string VisitorId { get; set; }

/// <summary>
/// Gets or sets the authenticated user identifier, if available.
/// </summary>
public string UserId { get; set; }

/// <summary>
/// Gets or sets whether the user was authenticated during this session.
/// </summary>
public bool IsAuthenticated { get; set; }

/// <summary>
/// Gets or sets the UTC timestamp when the session started.
/// </summary>
public DateTime SessionStartedUtc { get; set; }

/// <summary>
/// Gets or sets the UTC timestamp when the session ended.
/// Null if the session is still active.
/// </summary>
public DateTime? SessionEndedUtc { get; set; }

/// <summary>
/// Gets or sets the total number of messages exchanged in this session (user + assistant).
/// </summary>
public int MessageCount { get; set; }

/// <summary>
/// Gets or sets the total handle time in seconds (duration from first to last message).
/// </summary>
public double HandleTimeSeconds { get; set; }

/// <summary>
/// Gets or sets whether the session was resolved within the chat (natural ending)
/// versus abandoned (closed due to inactivity).
/// Used to calculate containment rate.
/// </summary>
public bool IsResolved { get; set; }

/// <summary>
/// Gets or sets the total number of input tokens consumed across all completions in this session.
/// </summary>
public int TotalInputTokens { get; set; }

/// <summary>
/// Gets or sets the total number of output tokens generated across all completions in this session.
/// </summary>
public int TotalOutputTokens { get; set; }

/// <summary>
/// Gets or sets the average AI response latency in milliseconds across all completions in this session.
/// </summary>
public double AverageResponseLatencyMs { get; set; }

/// <summary>
/// Gets or sets the number of assistant responses that contributed to <see cref="AverageResponseLatencyMs"/>.
/// </summary>
public int CompletionCount { get; set; }

/// <summary>
/// Gets or sets the user's feedback rating for this session.
/// Null means no feedback was provided, true means positive (thumbs up), false means negative (thumbs down).
/// </summary>
public bool? UserRating { get; set; }

/// <summary>
/// Gets or sets the total number of thumbs-up ratings across all messages in this session.
/// </summary>
public int ThumbsUpCount { get; set; }

/// <summary>
/// Gets or sets the total number of thumbs-down ratings across all messages in this session.
/// </summary>
public int ThumbsDownCount { get; set; }

/// <summary>
/// Gets or sets the aggregate conversion score across all goals.
/// Null if conversion metrics are not enabled.
/// </summary>
public int? ConversionScore { get; set; }

/// <summary>
/// Gets or sets the maximum possible conversion score across all goals.
/// Null if conversion metrics are not enabled.
/// </summary>
public int? ConversionMaxScore { get; set; }

/// <summary>
/// Gets or sets the individual goal results from AI evaluation.
/// </summary>
public List<ConversionGoalResult> ConversionGoalResults { get; set; } = [];

/// <summary>
/// Gets or sets the UTC timestamp when this event record was created.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace CrestApps.Core.AI.Models;
public class AIDeployment : SourceCatalogEntry, INameAwareModel, ISourceAwareModel, ICloneable<AIDeployment>
{
private string _modelName;

/// <summary>
/// Gets or sets the technical name of the AI client implementation to use for this deployment.
/// This maps to a registered key in <c>AIOptions.Clients</c>.
Expand All @@ -25,10 +26,12 @@ public string ClientName
[JsonInclude]
[JsonPropertyName("ProviderName")]
private string _providerNameBackingField { set => Source = value; }

/// <summary>
/// Gets or sets the unique technical name used to identify this deployment in settings, profiles, and recipes.
/// </summary>
public string Name { get; set; }

/// <summary>
/// Gets or sets the provider-facing model or deployment name.
/// Falls back to <see cref = "Name"/> for backward compatibility with legacy records.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public enum ChatSessionStatus
{
Active,
Closed,
Abandoned,
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ public sealed class ProfileTemplateMetadata
/// Gets or sets the type of AI profile this template creates.
/// </summary>
public AIProfileType? ProfileType { get; set; }

/// <summary>
/// Gets or sets the legacy connection name used by older templates.
/// Retained for backward compatibility with existing template metadata.
/// </summary>
[Obsolete("Use ChatDeploymentName and UtilityDeploymentName. The selected deployment determines the connection.")]
public string ConnectionName { get; set; }

/// <summary>
/// Gets or sets the chat deployment identifier to pre-fill.
/// </summary>
public string ChatDeploymentName { get; set; }

/// <summary>
/// Gets or sets the utility deployment identifier to pre-fill.
/// </summary>
Expand Down Expand Up @@ -58,78 +61,96 @@ private string _utilityDeploymentId
{
set => UtilityDeploymentName = value;
}

/// <summary>
/// Gets or sets the name of the orchestrator to use.
/// </summary>
public string OrchestratorName { get; set; }

/// <summary>
/// Gets or sets the system message for the profile.
/// </summary>
public string SystemMessage { get; set; }

/// <summary>
/// Gets or sets the welcome message shown to users.
/// </summary>
public string WelcomeMessage { get; set; }

/// <summary>
/// Gets or sets the template for the prompt.
/// </summary>
public string PromptTemplate { get; set; }

/// <summary>
/// Gets or sets the subject of the prompt.
/// </summary>
public string PromptSubject { get; set; }

/// <summary>
/// Gets or sets the type of title used in the session.
/// </summary>
public AISessionTitleType? TitleType { get; set; }

/// <summary>
/// Gets or sets the temperature parameter for AI completion.
/// </summary>
public float? Temperature { get; set; }

/// <summary>
/// Gets or sets the TopP parameter for AI completion.
/// </summary>
public float? TopP { get; set; }

/// <summary>
/// Gets or sets the frequency penalty parameter.
/// </summary>
public float? FrequencyPenalty { get; set; }

/// <summary>
/// Gets or sets the presence penalty parameter.
/// </summary>
public float? PresencePenalty { get; set; }

/// <summary>
/// Gets or sets the maximum number of tokens for AI completion.
/// </summary>
public int? MaxOutputTokens { get; set; }

/// <summary>
/// Gets or sets the number of past messages to include in context.
/// </summary>
public int? PastMessagesCount { get; set; }

/// <summary>
/// Gets or sets the tool names to associate with the profile.
/// </summary>
public string[] ToolNames { get; set; } = [];

/// <summary>
/// Gets or sets the A2A connection identifiers to associate with the profile.
/// </summary>
public string[] A2AConnectionIds { get; set; } = [];

/// <summary>
/// Gets or sets the agent profile names to associate with the profile.
/// </summary>
public string[] AgentNames { get; set; } = [];

/// <summary>
/// Gets or sets the description of the profile's capabilities.
/// Used for <see cref="AIProfileType.Agent"/> templates to describe
/// what the agent does.
/// </summary>
public string Description { get; set; }

/// <summary>
/// Gets or sets the availability mode for agent profiles.
/// Controls whether the agent is always included in every request
/// or only when matched by relevance scoring.
/// </summary>
public AgentAvailability? AgentAvailability { get; set; }

/// <summary>
/// Gets or sets the name of the initial <see cref="IChatResponseHandler"/>
/// for new sessions created from profiles based on this template.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using CrestApps.Core.AI.Tooling;

namespace CrestApps.Core.AI.Orchestration;

/// <summary>
/// Per-invocation context for AI operations, providing isolation between concurrent
/// SignalR hub method calls. Each hub invocation creates its own instance via
Expand Down Expand Up @@ -29,34 +30,41 @@ namespace CrestApps.Core.AI.Orchestration;
public sealed class AIInvocationContext
{
private int _referenceIndex;

/// <summary>
/// Gets or sets the <see cref = "AIToolExecutionContext"/> for the current invocation,
/// providing provider, connection, and resource information.
/// </summary>
public AIToolExecutionContext ToolExecutionContext { get; set; }

/// <summary>
/// Gets or sets the completion context for the current invocation.
/// </summary>
public AICompletionContext CompletionContext { get; set; }

/// <summary>
/// Gets or sets the chat session for the current invocation.
/// </summary>
public AIChatSession ChatSession { get; set; }

/// <summary>
/// Gets or sets the chat interaction for the current invocation.
/// </summary>
public ChatInteraction ChatInteraction { get; set; }

/// <summary>
/// Gets or sets the data source identifier for the current invocation.
/// Used by <c>DataSourceSearchTool</c> to scope searches to the correct data source.
/// </summary>
public string DataSourceId { get; set; }

/// <summary>
/// Gets the dictionary of citation references collected during tool execution
/// (e.g., from <c>DataSourceSearchTool</c> and <c>SearchDocumentsTool</c>).
/// Keyed by the citation marker (e.g., "[doc:1]") with the reference metadata as value.
/// </summary>
public Dictionary<string, AICompletionReference> ToolReferences { get; } = new(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Gets a general-purpose property bag for extensibility.
/// Handlers and tools can store arbitrary per-invocation data here.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
namespace CrestApps.Core.AI.Orchestration;

/// <summary>
/// Manages an <see cref = "AsyncLocal{T}"/>-backed ambient context for AI invocations.
/// Each SignalR hub method call (or any entry point) creates a scope with
Expand Down Expand Up @@ -28,6 +29,7 @@ namespace CrestApps.Core.AI.Orchestration;
public static class AIInvocationScope
{
private static readonly AsyncLocal<AIInvocationContext> _current = new();

/// <summary>
/// Gets the <see cref = "AIInvocationContext"/> for the current async execution flow,
/// or <c>null</c> if no scope has been started.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.Extensions.AI;

namespace CrestApps.Core.AI.ResponseHandling;

/// <summary>
/// Represents the result of an <see cref = "IChatResponseHandler"/> processing a chat prompt.
/// A result is either <em>streaming</em> (the response is available immediately as a stream
Expand All @@ -16,6 +17,7 @@ public sealed class ChatResponseHandlerResult
/// asynchronously (e.g., via webhook, background task, or external callback).
/// </summary>
public bool IsDeferred { get; init; }

/// <summary>
/// Gets the streaming response. Only available when <see cref = "IsDeferred"/> is <see langword="false"/>.
/// Each <see cref = "ChatResponseUpdate"/> contains a partial text chunk to be streamed to the client.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public interface IChatResponseHandler
/// Gets the unique technical name of this handler (e.g., <c>"AI"</c>, <c>"Genesys"</c>).
/// </summary>
string Name { get; }

/// <summary>
/// Processes a chat prompt and returns a result indicating whether the response
/// is available immediately (streaming) or will be delivered later (deferred).
Expand Down
Loading
Loading