Skip to content

Commit

Permalink
fix: Removed LangChain.Core usage over repo.
Browse files Browse the repository at this point in the history
  • Loading branch information
HavenDV committed Sep 18, 2024
1 parent b20fe91 commit 664de71
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 250 deletions.
2 changes: 2 additions & 0 deletions src/Abstractions/src/LangChain.Databases.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="LangChain.Polyfills" />
<PackageReference Include="LangChain.Providers.Abstractions" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
97 changes: 97 additions & 0 deletions src/Abstractions/src/MessageHistory/BaseChatMessageHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using LangChain.Providers;

namespace LangChain.Memory;

/// <summary>
/// Abstract base class for storing chat message history.
///
/// Implementations should over-ride the AddMessages method to handle bulk addition
/// of messages.
///
/// The default implementation of AddMessages will correctly call AddMessage, so
/// it is not necessary to implement both methods.
///
/// When used for updating history, users should favor usage of `AddMessages`
/// over `AddMessage` or other variants like `AddUserMessage` and `AddAiMessage`
/// to avoid unnecessary round-trips to the underlying persistence layer.
/// </summary>
public abstract class BaseChatMessageHistory
{
/// <summary>
/// A list of messages stored in-memory.
/// </summary>
public abstract IReadOnlyList<Message> Messages { get; }

/// <summary>
/// Convenience method for adding a human message string to the store.
///
/// Please note that this is a convenience method. Code should favor the
/// bulk AddMessages interface instead to save on round-trips to the underlying
/// persistence layer.
///
/// This method may be deprecated in a future release.
/// </summary>
/// <param name="message">The human message to add</param>
public async Task AddUserMessage(string message)
{
await AddMessage(message.AsHumanMessage()).ConfigureAwait(false);
}

/// <summary>
/// Convenience method for adding an AI message string to the store.
///
/// Please note that this is a convenience method. Code should favor the bulk
/// AddMessages interface instead to save on round-trips to the underlying
/// persistence layer.
///
/// This method may be deprecated in a future release.
/// </summary>
/// <param name="message"></param>
public async Task AddAiMessage(string message)
{
await AddMessage(message.AsAiMessage()).ConfigureAwait(false);
}

/// <summary>
/// Add a message object to the store.
/// </summary>
/// <param name="message">A message object to store</param>
public abstract Task AddMessage(Message message);

/// <summary>
/// Add a list of messages.
///
/// Implementations should override this method to handle bulk addition of messages
/// in an efficient manner to avoid unnecessary round-trips to the underlying store.
/// </summary>
/// <param name="messages">A list of message objects to store.</param>
public virtual async Task AddMessages(IEnumerable<Message> messages)
{
messages = messages ?? throw new ArgumentNullException(nameof(messages));

foreach (var message in messages)
{
await AddMessage(message).ConfigureAwait(false);
}
}

/// <summary>
/// Replace the list of messages.
///
/// Implementations should override this method to handle bulk addition of messages
/// in an efficient manner to avoid unnecessary round-trips to the underlying store.
/// </summary>
/// <param name="messages">A list of message objects to store.</param>
public virtual async Task SetMessages(IEnumerable<Message> messages)
{
messages = messages ?? throw new ArgumentNullException(nameof(messages));

await Clear().ConfigureAwait(false);
await AddMessages(messages).ConfigureAwait(false);
}

/// <summary>
/// Remove all messages from the store
/// </summary>
public abstract Task Clear();
}
40 changes: 40 additions & 0 deletions src/Abstractions/src/MessageHistory/ChatMessageHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using LangChain.Providers;

namespace LangChain.Memory;

/// <summary>
/// In memory implementation of chat message history.
///
/// Stores messages in an in memory list.
/// </summary>
public class ChatMessageHistory : BaseChatMessageHistory
{
private readonly List<Message> _messages = new List<Message>();

/// <summary>
/// Used to inspect and filter messages on their way to the history store
/// NOTE: This is not a feature of python langchain
/// </summary>
public Predicate<Message> IsMessageAccepted { get; set; } = (x => true);

/// <inheritdoc/>
public override IReadOnlyList<Message> Messages => _messages;

/// <inheritdoc/>
public override Task AddMessage(Message message)
{
if (IsMessageAccepted(message))
{
_messages.Add(message);
}

return Task.CompletedTask;
}

/// <inheritdoc/>
public override Task Clear()
{
_messages.Clear();
return Task.CompletedTask;
}
}
81 changes: 81 additions & 0 deletions src/Abstractions/src/MessageHistory/FileChatMessageHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using LangChain.Providers;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace LangChain.Memory;

/// <summary>
/// Chat message history that stores history in a local file.
/// </summary>
public class FileChatMessageHistory : BaseChatMessageHistory
{
private string MessagesFilePath { get; }

private List<Message> _messages = new List<Message>();

/// <inheritdoc/>
public override IReadOnlyList<Message> Messages => _messages;

/// <summary>
/// Initializes new history instance with provided file path
/// </summary>
/// <param name="messagesFilePath">path of the local file to store the messages</param>
/// <exception cref="ArgumentNullException"></exception>
private FileChatMessageHistory(string messagesFilePath)
{
MessagesFilePath = messagesFilePath ?? throw new ArgumentNullException(nameof(messagesFilePath));
}

/// <summary>
/// Create new history instance with provided file path
/// </summary>
/// <param name="path">path of the local file to store the messages</param>
/// <param name="cancellationToken"></param>
public static async Task<FileChatMessageHistory> CreateAsync(string path, CancellationToken cancellationToken = default)
{
FileChatMessageHistory chatHistory = new FileChatMessageHistory(path);
await chatHistory.LoadMessages().ConfigureAwait(false);

return chatHistory;
}

/// <inheritdoc/>
public override Task AddMessage(Message message)
{
_messages.Add(message);
SaveMessages();

return Task.CompletedTask;
}

/// <inheritdoc/>
public override Task Clear()
{
_messages.Clear();
SaveMessages();

return Task.CompletedTask;
}

private void SaveMessages()
{
var json = JsonSerializer.Serialize(_messages, SourceGenerationContext.Default.ListMessage);

File.WriteAllText(MessagesFilePath, json);
}

private async Task LoadMessages()
{
if (File.Exists(MessagesFilePath))
{
var json = await File2.ReadAllTextAsync(MessagesFilePath).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(json))
{
_messages = JsonSerializer.Deserialize(json, SourceGenerationContext.Default.ListMessage) ?? new List<Message>();
}
}
}
}

[JsonSerializable(typeof(List<Message>))]
internal sealed partial class SourceGenerationContext : JsonSerializerContext;
23 changes: 22 additions & 1 deletion src/Abstractions/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
abstract LangChain.Memory.BaseChatMessageHistory.AddMessage(LangChain.Providers.Message message) -> System.Threading.Tasks.Task!
abstract LangChain.Memory.BaseChatMessageHistory.Clear() -> System.Threading.Tasks.Task!
abstract LangChain.Memory.BaseChatMessageHistory.Messages.get -> System.Collections.Generic.IReadOnlyList<LangChain.Providers.Message>!
const LangChain.Databases.VectorCollection.DefaultName = "langchain" -> string!
LangChain.Databases.DistanceStrategy
LangChain.Databases.DistanceStrategy.Cosine = 1 -> LangChain.Databases.DistanceStrategy
Expand Down Expand Up @@ -67,11 +70,29 @@ LangChain.Databases.VectorSearchType
LangChain.Databases.VectorSearchType.MaximumMarginalRelevance = 2 -> LangChain.Databases.VectorSearchType
LangChain.Databases.VectorSearchType.Similarity = 0 -> LangChain.Databases.VectorSearchType
LangChain.Databases.VectorSearchType.SimilarityScoreThreshold = 1 -> LangChain.Databases.VectorSearchType
LangChain.Memory.BaseChatMessageHistory
LangChain.Memory.BaseChatMessageHistory.AddAiMessage(string! message) -> System.Threading.Tasks.Task!
LangChain.Memory.BaseChatMessageHistory.AddUserMessage(string! message) -> System.Threading.Tasks.Task!
LangChain.Memory.BaseChatMessageHistory.BaseChatMessageHistory() -> void
LangChain.Memory.ChatMessageHistory
LangChain.Memory.ChatMessageHistory.ChatMessageHistory() -> void
LangChain.Memory.ChatMessageHistory.IsMessageAccepted.get -> System.Predicate<LangChain.Providers.Message>!
LangChain.Memory.ChatMessageHistory.IsMessageAccepted.set -> void
LangChain.Memory.FileChatMessageHistory
override LangChain.Memory.ChatMessageHistory.AddMessage(LangChain.Providers.Message message) -> System.Threading.Tasks.Task!
override LangChain.Memory.ChatMessageHistory.Clear() -> System.Threading.Tasks.Task!
override LangChain.Memory.ChatMessageHistory.Messages.get -> System.Collections.Generic.IReadOnlyList<LangChain.Providers.Message>!
override LangChain.Memory.FileChatMessageHistory.AddMessage(LangChain.Providers.Message message) -> System.Threading.Tasks.Task!
override LangChain.Memory.FileChatMessageHistory.Clear() -> System.Threading.Tasks.Task!
override LangChain.Memory.FileChatMessageHistory.Messages.get -> System.Collections.Generic.IReadOnlyList<LangChain.Providers.Message>!
static LangChain.Databases.RelevanceScoreFunctions.Cosine(float distance) -> float
static LangChain.Databases.RelevanceScoreFunctions.Euclidean(float distance) -> float
static LangChain.Databases.RelevanceScoreFunctions.Get(LangChain.Databases.DistanceStrategy distanceStrategy) -> System.Func<float, float>!
static LangChain.Databases.RelevanceScoreFunctions.MaxInnerProduct(float distance) -> float
static LangChain.Databases.VectorSearchRequest.implicit operator LangChain.Databases.VectorSearchRequest!(float[]! embedding) -> LangChain.Databases.VectorSearchRequest!
static LangChain.Databases.VectorSearchRequest.implicit operator LangChain.Databases.VectorSearchRequest!(float[]![]! embeddings) -> LangChain.Databases.VectorSearchRequest!
static LangChain.Databases.VectorSearchRequest.ToVectorSearchRequest(float[]! embedding) -> LangChain.Databases.VectorSearchRequest!
static LangChain.Databases.VectorSearchRequest.ToVectorSearchRequest(float[]![]! embeddings) -> LangChain.Databases.VectorSearchRequest!
static LangChain.Databases.VectorSearchRequest.ToVectorSearchRequest(float[]![]! embeddings) -> LangChain.Databases.VectorSearchRequest!
static LangChain.Memory.FileChatMessageHistory.CreateAsync(string! path, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<LangChain.Memory.FileChatMessageHistory!>!
virtual LangChain.Memory.BaseChatMessageHistory.AddMessages(System.Collections.Generic.IEnumerable<LangChain.Providers.Message>! messages) -> System.Threading.Tasks.Task!
virtual LangChain.Memory.BaseChatMessageHistory.SetMessages(System.Collections.Generic.IEnumerable<LangChain.Providers.Message>! messages) -> System.Threading.Tasks.Task!
6 changes: 3 additions & 3 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageVersion>
<PackageVersion Include="LangChain.Core" Version="0.15.1-dev.129" />
<PackageVersion Include="LangChain.DocumentLoaders.Pdf" Version="0.15.1-dev.129" />
<PackageVersion Include="LangChain.DocumentLoaders.Abstractions" Version="0.15.1-dev.129" />
<PackageVersion Include="LangChain.Polyfills" Version="0.15.1-dev.129" />
<PackageVersion Include="LangChain.Providers.Amazon.Bedrock" Version="0.15.2" />
<PackageVersion Include="LangChain.Providers.Abstractions" Version="0.15.2" />
<PackageVersion Include="LangChain.Serve.Abstractions" Version="0.15.1-dev.129" />
<PackageVersion Include="LangChain.Splitters.Abstractions" Version="0.15.1-dev.129" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.8" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
Expand Down
Loading

0 comments on commit 664de71

Please sign in to comment.