diff --git a/LLama/ChatSession.cs b/LLama/ChatSession.cs index 251573fc..1cc7d29e 100644 --- a/LLama/ChatSession.cs +++ b/LLama/ChatSession.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using LLama.Abstractions; using LLama.Common; +using static LLama.Common.ChatHistory; using static LLama.InteractiveExecutor; using static LLama.LLamaContext; using static LLama.StatefulExecutorBase; @@ -53,19 +54,16 @@ public class ChatSession /// /// The executor for this session /// History for this session - /// Cancellation token to stop session pre-processing /// public static async Task InitializeSessionFromHistoryAsync( - ILLamaExecutor executor, - ChatHistory history, - CancellationToken cancellationToken = default) + ILLamaExecutor executor, ChatHistory history) { if (executor is not StatefulExecutorBase statefulExecutor) { throw new ArgumentException("Executor must have a StatefulExecutorBase", nameof(executor)); } var session = new ChatSession(executor, history); - await statefulExecutor.AddPromptAsync(session.HistoryTransform.HistoryToText(history), cancellationToken); + await statefulExecutor.PrefillPromptAsync(session.HistoryTransform.HistoryToText(history)); return session; } @@ -164,13 +162,13 @@ public class ChatSession /// SessionState object representing session state in-memory public SessionState GetSessionState() { - return new SessionState(Executor.Context.GetState(), ((StatefulExecutorBase)Executor).GetStateData()) - { - InputTransformPipeline = InputTransformPipeline, - OutputTransform = OutputTransform, - HistoryTransform = HistoryTransform, - History = History.ToJson() - }; + return new SessionState( + Executor.Context.GetState(), + ((StatefulExecutorBase)Executor).GetStateData(), + History, + InputTransformPipeline, + OutputTransform, + HistoryTransform); } /// @@ -183,18 +181,17 @@ public class ChatSession { if (Executor is StatefulExecutorBase statefulExecutor) { - statefulExecutor.LoadState( - JsonSerializer.Deserialize( - state.ExecutorState, statefulExecutor.GetStateData().GetType() - ) as ExecutorBaseState ?? throw new ArgumentException("Executor state is invalid", nameof(state)) - ); + statefulExecutor.LoadState(state.ExecutorState); } else { throw new ArgumentException("Executor must be a StatefulExecutorBase to support loading of session state", nameof(state)); } Executor.Context.LoadState(state.ContextState); - History = ChatHistory.FromJson(state.History) ?? new(); + History = new ChatHistory(state.History); + InputTransformPipeline = state.InputTransformPipeline.ToList(); + OutputTransform = state.OutputTransform; + HistoryTransform = state.HistoryTransform; } /// @@ -288,7 +285,7 @@ public class ChatSession content = inputTransform.Transform(content); } - await statefulExecutor.AddPromptAsync(content); + await statefulExecutor.PrefillPromptAsync(content); History.AddMessage(AuthorRole.System, content); return this; @@ -593,41 +590,52 @@ public record SessionState /// /// Saved executor state for the session in JSON format. /// - public string ExecutorState { get; init; } + public ExecutorBaseState ExecutorState { get; set; } /// /// Saved context state (KV cache) for the session. /// - public State ContextState { get; init; } + public State ContextState { get; set; } /// /// The input transform pipeline used in this session. /// - public List InputTransformPipeline { get; init; } = new(); + public ITextTransform[] InputTransformPipeline { get; set; } = Array.Empty(); /// /// The output transform used in this session. /// - public ITextStreamTransform OutputTransform { get; init; } = new LLamaTransforms.EmptyTextOutputStreamTransform(); + public ITextStreamTransform OutputTransform { get; set; } = new LLamaTransforms.EmptyTextOutputStreamTransform(); /// /// The history transform used in this session. /// - public IHistoryTransform HistoryTransform { get; init; } = new LLamaTransforms.DefaultHistoryTransform(); + public IHistoryTransform HistoryTransform { get; set; } = new LLamaTransforms.DefaultHistoryTransform(); /// - /// The JSON representation of the chat history for this session. + /// The the chat history messages for this session. /// - public string History { get; init; } = new ChatHistory().ToJson(); + public Message[] History { get; set; } = Array.Empty(); /// /// Create a new session state. /// /// /// - public SessionState(State contextState, ExecutorBaseState executorState) + /// + /// + /// + /// + public SessionState( + State contextState, ExecutorBaseState executorState, + ChatHistory history, List inputTransformPipeline, + ITextStreamTransform outputTransform, IHistoryTransform historyTransform) { ContextState = contextState; - ExecutorState = JsonSerializer.Serialize(executorState); + ExecutorState = executorState; + History = history.Messages.ToArray(); + InputTransformPipeline = inputTransformPipeline.ToArray(); + OutputTransform = outputTransform; + HistoryTransform = historyTransform; } } \ No newline at end of file diff --git a/LLama/Common/ChatHistory.cs b/LLama/Common/ChatHistory.cs index dc741449..c22cc7c0 100644 --- a/LLama/Common/ChatHistory.cs +++ b/LLama/Common/ChatHistory.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; @@ -80,6 +81,15 @@ namespace LLama.Common [JsonConstructor] public ChatHistory() { } + /// + /// Create a new instance of the chat history from array of messages + /// + /// + public ChatHistory(Message[] messageHistory) + { + this.Messages = messageHistory.ToList(); + } + /// /// Add a message to the chat history ///