├── src ├── Splitters │ ├── Abstractions │ │ ├── src │ │ │ ├── PublicAPI.Shipped.txt │ │ │ ├── Code │ │ │ │ ├── CodePartType.cs │ │ │ │ ├── ICodeSplitter.cs │ │ │ │ ├── CodePart.cs │ │ │ │ └── ICodeCutter.cs │ │ │ ├── Text │ │ │ │ ├── ITextSplitter.cs │ │ │ │ └── CharacterTextSplitter.cs │ │ │ └── LangChain.Splitters.Abstractions.csproj │ │ └── test │ │ │ ├── LangChain.Splitters.Abstractions.Tests.csproj │ │ │ ├── Tests.RecursiveCharacter.cs │ │ │ └── Tests.MarkdownHeader.cs │ ├── CSharp │ │ ├── test │ │ │ └── LangChain.Splitters.CSharp.Tests.csproj │ │ └── src │ │ │ └── LangChain.Splitters.CSharp.csproj │ └── Directory.Build.props ├── DocumentLoaders │ ├── Abstractions │ │ └── src │ │ │ ├── PublicAPI.Shipped.txt │ │ │ ├── DataSourceType.cs │ │ │ ├── DocumentLoaderSettings.cs │ │ │ ├── IDocumentLoader.cs │ │ │ ├── DocumentLookupExtensions.cs │ │ │ ├── LangChain.DocumentLoaders.Abstractions.csproj │ │ │ └── FileLoader.cs │ ├── IntegrationTests │ │ ├── Tests.cs │ │ ├── Resources │ │ │ ├── sample.pdf │ │ │ ├── file-sample_1MB.docx │ │ │ └── file_example_XLSX_50.xlsx │ │ ├── Tests.Html.cs │ │ ├── LangChain.DocumentLoaders.IntegrationTests.csproj │ │ ├── Tests.Word.cs │ │ └── Tests.Pdf.cs │ ├── Directory.Build.props │ ├── Word │ │ └── src │ │ │ ├── LangChain.DocumentLoaders.Word.csproj │ │ │ ├── ExcelLoader.cs │ │ │ └── WordLoader.cs │ ├── WebBase │ │ └── src │ │ │ ├── LangChain.DocumentLoaders.Html.csproj │ │ │ └── HtmlLoader.cs │ └── Pdf │ │ └── src │ │ ├── AsposePdfSource.cs │ │ ├── LangChain.DocumentLoaders.Pdf.csproj │ │ └── PdfPigPdfSource.cs ├── key.snk ├── Helpers │ ├── TrimmingHelper │ │ ├── Program.cs │ │ └── TrimmingHelper.csproj │ └── GenerateDocs │ │ └── GenerateDocs.csproj ├── Core │ ├── src │ │ ├── Cache │ │ │ └── BaseCache.cs │ │ ├── Base │ │ │ ├── IBaseLanguageModelCallOptions.cs │ │ │ ├── Handler.cs │ │ │ ├── IBaseLanguageModelParams.cs │ │ │ ├── IBaseLangChainParams.cs │ │ │ ├── ChainInputs.cs │ │ │ ├── BaseLangChain.cs │ │ │ ├── Tracers │ │ │ │ ├── TracerException.cs │ │ │ │ ├── BaseCallbackHandlerInput.cs │ │ │ │ └── StringExtensions.cs │ │ │ ├── IBaseCallbackHandlerInput.cs │ │ │ ├── BaseLanguageModel.cs │ │ │ └── IChainInputs.cs │ │ ├── Schema │ │ │ ├── IPromptValue.cs │ │ │ ├── ChatGeneration.cs │ │ │ ├── IInputValues.cs │ │ │ ├── IChainValues.cs │ │ │ ├── PartialValues.cs │ │ │ ├── InputValues.cs │ │ │ ├── OutputValues.cs │ │ │ ├── BasePromptValue.cs │ │ │ ├── Generation.cs │ │ │ ├── LLMResult.cs │ │ │ └── OutputParserException.cs │ │ ├── LLMs │ │ │ ├── IBaseLlmCallOptions.cs │ │ │ └── IBaseLlmParams.cs │ │ ├── Callback │ │ │ ├── CallbackManagerMethod.cs │ │ │ ├── ICallbackManagerOptions.cs │ │ │ ├── ICallbacks.cs │ │ │ ├── CallbackManagerForToolRun.cs │ │ │ └── ParentRunManager.cs │ │ ├── Chains │ │ │ ├── SerializedBaseChain.cs │ │ │ ├── StackableChains │ │ │ │ ├── Hooks │ │ │ │ │ ├── StackableChainValues.cs │ │ │ │ │ └── StackableChainHook.cs │ │ │ │ ├── Agents │ │ │ │ │ ├── Tools │ │ │ │ │ │ ├── BuiltIn │ │ │ │ │ │ │ └── Classes │ │ │ │ │ │ │ │ └── GoogleResults.cs │ │ │ │ │ │ ├── AgentToolLambda.cs │ │ │ │ │ │ └── AgentTool.cs │ │ │ │ │ ├── Crew │ │ │ │ │ │ ├── Tools │ │ │ │ │ │ │ ├── CrewAgentToolLambda.cs │ │ │ │ │ │ │ └── CrewAgentTool.cs │ │ │ │ │ │ ├── Crew.cs │ │ │ │ │ │ └── AgentTask.cs │ │ │ │ │ └── PromptedAgent.cs │ │ │ │ ├── Extensions │ │ │ │ │ └── HookExtension.cs │ │ │ │ ├── Exceptions │ │ │ │ │ └── StackableChainException.cs │ │ │ │ ├── SetLambdaChain.cs │ │ │ │ ├── SetChain.cs │ │ │ │ ├── DoChain.cs │ │ │ │ ├── UpdateMemoryChain.cs │ │ │ │ ├── LoadMemoryChain.cs │ │ │ │ ├── ImageToTextGeneration │ │ │ │ │ └── ImageToTextGenerationChain.cs │ │ │ │ ├── ImageGeneration │ │ │ │ │ └── ImageGenerationChain.cs │ │ │ │ ├── Files │ │ │ │ │ └── SaveIntoFileChain.cs │ │ │ │ └── RetreiveDocumentsChain.cs │ │ │ ├── LLM │ │ │ │ ├── SerializedLLMChain.cs │ │ │ │ ├── ILlmChainInput.cs │ │ │ │ ├── ILlmChain.cs │ │ │ │ └── LLMChainInput.cs │ │ │ ├── CombineDocuments │ │ │ │ ├── BaseCombineDocumentsChainInput.cs │ │ │ │ ├── AnalyzeDocumentsChainInput.cs │ │ │ │ ├── ReduceDocumentsChainInput.cs │ │ │ │ ├── MapReduceDocumentsChainInput.cs │ │ │ │ └── StuffDocumentsChainInput.cs │ │ │ ├── RetrievalQA │ │ │ │ ├── RetrievalQaChainInput.cs │ │ │ │ ├── BaseRetrievalQaChainInput.cs │ │ │ │ └── RetrievalQaChain.cs │ │ │ ├── ConversationalRetrieval │ │ │ │ ├── ChatTurnTypeHelper.cs │ │ │ │ └── ConversationalRetrievalChainInput.cs │ │ │ └── Sequentials │ │ │ │ └── SequentialChainInput.cs │ │ ├── Prompts │ │ │ ├── LiteralNode.cs │ │ │ ├── SerializedPromptTemplate.cs │ │ │ ├── VariableNode.cs │ │ │ ├── TemplateFormatOptions.cs │ │ │ ├── ParsedFStringNode.cs │ │ │ ├── Base │ │ │ │ ├── IBasePromptTemplateInput.cs │ │ │ │ ├── StringPromptValue.cs │ │ │ │ └── BaseStringPromptTemplate.cs │ │ │ ├── IPromptTemplateInput.cs │ │ │ ├── SerializedBasePromptTemplate.cs │ │ │ ├── SerializedMessagePromptTemplate.cs │ │ │ ├── ChatPromptTemplateInput.cs │ │ │ ├── ChatPromptValue.cs │ │ │ ├── PromptTemplateInput.cs │ │ │ ├── AIMessagePromptTemplate.cs │ │ │ ├── HumanMessagePromptTemplate.cs │ │ │ ├── SystemMessagePromptTemplate.cs │ │ │ ├── ChatMessagePromptTemplate.cs │ │ │ ├── BaseMessageStringPromptTemplate.cs │ │ │ ├── BaseChatPromptTemplate.cs │ │ │ └── BaseMessagePromptTemplate.cs │ │ ├── Extensions │ │ │ ├── AddDocumentsToDatabaseBehavior.cs │ │ │ ├── VectorSearchResponseExtesions.cs │ │ │ ├── SourceExtensions.cs │ │ │ └── VectorStoreIndexWrapper.cs │ │ ├── Common │ │ │ └── DictionaryExtensions.cs │ │ ├── Retrievers │ │ │ ├── WebSearchRetriever.cs │ │ │ └── VectorStoreRetrieverExtensions.cs │ │ ├── Utilities │ │ │ └── IWebSearch.cs │ │ └── Memory │ │ │ ├── ConversationBufferMemory.cs │ │ │ └── BaseMemory.cs │ └── test │ │ └── UnitTests │ │ ├── LangChain.Core.UnitTests.csproj │ │ ├── Tools │ │ └── GoogleCustomSearchToolTests.cs │ │ ├── DocumentLoaderTests.cs │ │ ├── PromptTests.cs │ │ ├── Utilities │ │ └── DuckDuckGoSearchTests.cs │ │ └── MemoryTests.cs ├── Meta │ ├── test │ │ ├── Resources │ │ │ └── Harry-Potter-Book-1.pdf │ │ ├── ProviderType.cs │ │ ├── WikiTests.HowToUseOpenAiProviderSmaller.cs │ │ ├── DatabaseTestEnvironment.cs │ │ ├── LangChain.IntegrationTests.csproj │ │ ├── CalculatorTool.cs │ │ ├── AzureOpenAiTests.cs │ │ └── OpenAiTests.cs │ └── src │ │ └── LangChain.csproj ├── Directory.Build.targets ├── Testing.targets ├── Cli │ ├── src │ │ ├── Models │ │ │ ├── Provider.cs │ │ │ ├── Format.cs │ │ │ └── Tool.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Program.cs │ │ ├── Commands │ │ │ └── DoCommand.cs │ │ ├── CommonOptions.cs │ │ └── LangChain.Cli.csproj │ ├── test │ │ └── LangChain.Cli.IntegrationTests │ │ │ ├── LangChain.Cli.IntegrationTests.csproj │ │ │ └── TestExtensions.cs │ └── README.md ├── Serve │ ├── Abstractions │ │ └── LangChain.Serve.Abstractions │ │ │ ├── Repository │ │ │ ├── MessageAuthor.cs │ │ │ ├── StoredMessage.cs │ │ │ └── StoredConversation.cs │ │ │ ├── IConversationNameProvider.cs │ │ │ ├── LangChain.Serve.Abstractions.csproj │ │ │ └── IConversationRepository.cs │ ├── src │ │ ├── Classes │ │ │ └── DTO │ │ │ │ ├── ConversationCreationDTO.cs │ │ │ │ ├── PostMessageDTO.cs │ │ │ │ ├── MessageDTO.cs │ │ │ │ └── ConversationDTO.cs │ │ ├── Services │ │ │ ├── CustomNameProvider.cs │ │ │ └── DateConversationNameProvider.cs │ │ ├── LangChain.Serve.csproj │ │ └── ServeOptions.cs │ └── OpenAI │ │ ├── ServeOptions.cs │ │ ├── LangChain.Serve.OpenAI.csproj │ │ └── ServeController.cs ├── Utilities │ ├── Sql │ │ └── src │ │ │ ├── SqlRunFetchType.cs │ │ │ ├── LangChain.Utilities.Sql.csproj │ │ │ └── StringHelperer.cs │ ├── Directory.Build.props │ ├── Pollyfils │ │ └── src │ │ │ ├── StringExtensions.StartsWith.cs │ │ │ ├── StreamExtensions.CopyToAsync.cs │ │ │ ├── HttpContext.ReadAsStringAsync.CancellationToken.cs │ │ │ ├── HttpClient.GetStreamAsync.CancellationToken.cs │ │ │ ├── HttpClient.GetByteArrayAsync.CancellationToken.cs │ │ │ ├── LangChain.Polyfills.csproj │ │ │ ├── DictionaryExtensions.GetValueOrDefault.cs │ │ │ ├── StringExtensions.Replace.cs │ │ │ └── StringExtensions.Contains.cs │ └── Postgres │ │ ├── src │ │ ├── StringBuilderExtensions.cs │ │ └── LangChain.Utilities.Postgres.csproj │ │ └── test │ │ └── LangChain.Utilities.Postgres.IntegrationTests.csproj ├── Extensions │ ├── Directory.Build.props │ ├── Docker │ │ └── src │ │ │ ├── LangChain.Extensions.Docker.csproj │ │ │ └── Chain.cs │ └── DependencyInjection │ │ └── src │ │ ├── LangChain.Extensions.DependencyInjection.csproj │ │ ├── ServiceCollectionExtensions.OpenAi.cs │ │ ├── ServiceCollectionExtensions.Anyscale.cs │ │ ├── ServiceCollectionExtensions.Anthropic.cs │ │ └── ServiceCollectionExtensions.HuggingFace.cs ├── Directory.Build.props └── Testing.props ├── assets └── nuget_icon.png ├── docs └── media │ └── icon128.png ├── global.json ├── examples ├── LangChain.Samples.AspNet │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── LangChain.Samples.AspNet.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── Controllers │ │ ├── AnthropicSampleController.cs │ │ └── OpenAiSampleController.cs ├── LangChain.Samples.Serve │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── Properties │ │ └── launchSettings.json │ └── LangChain.Samples.Serve.csproj ├── LangChain.Samples.Serve.OpenAI │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── Properties │ │ └── launchSettings.json │ ├── Program.cs │ └── LangChain.Samples.Serve.OpenAI.csproj ├── LangChain.Samples.Azure │ ├── LangChain.Samples.Azure.csproj │ └── Program.cs ├── LangChain.Samples.Memory │ └── LangChain.Samples.Memory.csproj ├── LangChain.Samples.OpenAI │ ├── LangChain.Samples.OpenAI.csproj │ └── Program.cs ├── LangChain.Samples.Prompts │ ├── LangChain.Samples.Prompts.csproj │ └── Program.cs ├── LangChain.Samples.HuggingFace │ ├── LangChain.Samples.HuggingFace.csproj │ └── Program.cs ├── LangChain.Samples.SequentialChain │ ├── LangChain.Samples.SequentialChain.csproj │ └── Program.cs └── LangChain.Samples.LocalRAG │ └── LangChain.Samples.LocalRAG.csproj ├── .github ├── workflows │ ├── pull-request.yml │ ├── auto-labeling.yml │ ├── dotnet.yml │ └── github-releases-to-discord.yml └── dependabot.yml ├── LangChain.sln.DotSettings ├── LICENSE └── sweep.yaml /src/Splitters/Abstractions/src/PublicAPI.Shipped.txt: -------------------------------------------------------------------------------- 1 | #nullable enable -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/PublicAPI.Shipped.txt: -------------------------------------------------------------------------------- 1 | #nullable enable -------------------------------------------------------------------------------- /src/key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/src/key.snk -------------------------------------------------------------------------------- /assets/nuget_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/assets/nuget_icon.png -------------------------------------------------------------------------------- /docs/media/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/docs/media/icon128.png -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "rollForward": "latestMajor", 4 | "allowPrerelease": false 5 | } 6 | } -------------------------------------------------------------------------------- /src/Helpers/TrimmingHelper/Program.cs: -------------------------------------------------------------------------------- 1 | Console.WriteLine("Build, rebuild or publish this app to see trimming warnings."); -------------------------------------------------------------------------------- /src/Core/src/Cache/BaseCache.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Cache; 2 | 3 | /// 4 | /// 5 | /// 6 | public abstract class BaseCache; -------------------------------------------------------------------------------- /src/Meta/test/Resources/Harry-Potter-Book-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/src/Meta/test/Resources/Harry-Potter-Book-1.pdf -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Tests.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders.IntegrationTests; 2 | 3 | [TestFixture] 4 | public partial class Tests; -------------------------------------------------------------------------------- /src/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Testing.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Resources/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/src/DocumentLoaders/IntegrationTests/Resources/sample.pdf -------------------------------------------------------------------------------- /src/Cli/src/Models/Provider.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Cli.Models; 2 | 3 | internal enum Provider 4 | { 5 | OpenAi, 6 | OpenRouter, 7 | Anthropic, 8 | Free, 9 | } -------------------------------------------------------------------------------- /src/Core/src/Base/IBaseLanguageModelCallOptions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IBaseLanguageModelCallOptions; -------------------------------------------------------------------------------- /src/Core/src/Schema/IPromptValue.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Abstractions.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IPromptValue 7 | { 8 | 9 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/DataSourceType.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | public enum DataSourceType 4 | { 5 | Uri, 6 | Path, 7 | Stream, 8 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Resources/file-sample_1MB.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/src/DocumentLoaders/IntegrationTests/Resources/file-sample_1MB.docx -------------------------------------------------------------------------------- /src/Cli/src/Models/Format.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Cli; 2 | 3 | internal enum Format 4 | { 5 | Text, 6 | Lines, 7 | Json, 8 | Markdown, 9 | ConventionalCommit, 10 | } -------------------------------------------------------------------------------- /src/Cli/src/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "FixOpenApiSpec": { 4 | "commandName": "Project", 5 | "commandLineArgs": "do --help" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Resources/file_example_XLSX_50.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tryAGI/LangChain/HEAD/src/DocumentLoaders/IntegrationTests/Resources/file_example_XLSX_50.xlsx -------------------------------------------------------------------------------- /src/Core/src/LLMs/IBaseLlmCallOptions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | 3 | namespace LangChain.LLMS; 4 | 5 | /// 6 | public interface IBaseLlmCallOptions : IBaseLanguageModelCallOptions { } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/Repository/MessageAuthor.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Serve.Abstractions.Repository; 2 | 3 | public enum MessageAuthor 4 | { 5 | User, 6 | Ai, 7 | } -------------------------------------------------------------------------------- /src/Core/src/Callback/CallbackManagerMethod.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Callback; 2 | 3 | /// 4 | /// 5 | /// 6 | public delegate Task CallbackManagerMethod(params object[] args); -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Serve/src/Classes/DTO/ConversationCreationDTO.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Serve.Classes.DTO; 2 | 3 | public class ConversationCreationDto 4 | { 5 | public string ModelName { get; set; } = string.Empty; 6 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve.OpenAI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve.OpenAI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/Core/src/Schema/ChatGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | public class ChatGeneration : Generation 5 | { 6 | /// 7 | /// 8 | /// 9 | public string Message { get; set; } = string.Empty; 10 | } -------------------------------------------------------------------------------- /src/Core/src/Base/Handler.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | public abstract class Handler : BaseCallbackHandler 5 | { 6 | /// 7 | protected Handler(IBaseCallbackHandlerInput input) : base(input) 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Core/src/Base/IBaseLanguageModelParams.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | public interface IBaseLanguageModelParams : IBaseLangChainParams 5 | { 6 | /// 7 | /// 8 | /// 9 | public string ApiKey { get; set; } 10 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/IInputValues.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Abstractions.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IInputValues 7 | { 8 | /// 9 | /// 10 | /// 11 | Dictionary Value { get; } 12 | } -------------------------------------------------------------------------------- /src/Helpers/GenerateDocs/GenerateDocs.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Core/src/Schema/IChainValues.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Abstractions.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IChainValues 7 | { 8 | /// 9 | /// 10 | /// 11 | public Dictionary Value { get; } 12 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/SerializedBaseChain.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains; 2 | 3 | /// 4 | /// 5 | /// 6 | public abstract class SerializedBaseChain 7 | { 8 | /// 9 | /// 10 | /// 11 | public string Type { get; set; } = string.Empty; 12 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/LiteralNode.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | public class LiteralNode( 5 | string text) 6 | : ParsedFStringNode("literal") 7 | { 8 | /// 9 | /// 10 | /// 11 | public string Text { get; } = text; 12 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/SerializedPromptTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | public class SerializedPromptTemplate : SerializedBasePromptTemplate 5 | { 6 | /// 7 | /// 8 | /// 9 | public new string Type => "prompt"; 10 | } 11 | -------------------------------------------------------------------------------- /src/Cli/src/Program.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using LangChain.Cli.Commands; 3 | 4 | var rootCommand = new RootCommand( 5 | description: "CLI tool to use LangChain for common tasks"); 6 | rootCommand.AddCommand(new DoCommand()); 7 | 8 | return await rootCommand.InvokeAsync(args).ConfigureAwait(false); -------------------------------------------------------------------------------- /src/Meta/test/ProviderType.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.IntegrationTests; 2 | 3 | public enum ProviderType 4 | { 5 | OpenAi, 6 | Together, 7 | Anyscale, 8 | Fireworks, 9 | OpenRouter, 10 | DeepInfra, 11 | Google, 12 | Anthropic, 13 | Groq, 14 | DeepSeek, 15 | Azure, 16 | } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/IConversationNameProvider.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve.Abstractions; 4 | 5 | public interface IConversationNameProvider 6 | { 7 | public Task GetConversationName(IReadOnlyCollection messages); 8 | } -------------------------------------------------------------------------------- /src/Core/src/LLMs/IBaseLlmParams.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | using LangChain.Cache; 3 | 4 | namespace LangChain.LLMS; 5 | 6 | /// 7 | public interface IBaseLlmParams : IBaseLanguageModelParams 8 | { 9 | internal decimal? Concurrency { get; set; } 10 | 11 | internal BaseCache? Cache { get; set; } 12 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/VariableNode.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | /// 5 | /// 6 | public class VariableNode( 7 | string name) 8 | : ParsedFStringNode("variable") 9 | { 10 | /// 11 | /// 12 | /// 13 | public string Name { get; } = name; 14 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/PartialValues.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public class PartialValues( 7 | Dictionary value) 8 | { 9 | /// 10 | /// 11 | /// 12 | public Dictionary Value { get; set; } = value; 13 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/TemplateFormatOptions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | /// 5 | /// 6 | public enum TemplateFormatOptions 7 | { 8 | /// 9 | /// 10 | /// 11 | FString, 12 | 13 | /// 14 | /// 15 | /// 16 | Jinja2 17 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/ParsedFStringNode.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | /// 5 | /// 6 | /// 7 | public abstract class ParsedFStringNode( 8 | string type) 9 | { 10 | /// 11 | /// 12 | /// 13 | public string Type { get; } = type; 14 | } -------------------------------------------------------------------------------- /src/Utilities/Sql/src/SqlRunFetchType.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Utilities.Sql; 2 | 3 | /// 4 | /// 5 | /// 6 | public enum SqlRunFetchType 7 | { 8 | /// 9 | /// Fetch all rows 10 | /// 11 | All, 12 | 13 | /// 14 | /// Fetch only one row 15 | /// 16 | One 17 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/InputValues.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | /// 7 | public class InputValues( 8 | Dictionary value) 9 | { 10 | /// 11 | /// 12 | /// 13 | public Dictionary Value { get; } = value; 14 | } -------------------------------------------------------------------------------- /src/Splitters/CSharp/test/LangChain.Splitters.CSharp.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Core/src/Schema/OutputValues.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | /// 7 | public class OutputValues( 8 | Dictionary value) 9 | { 10 | /// 11 | /// 12 | /// 13 | public Dictionary Value { get; set; } = value; 14 | } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/Repository/StoredMessage.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Serve.Abstractions.Repository; 2 | 3 | public class StoredMessage 4 | { 5 | public Guid ConversationId { get; set; } 6 | public Guid MessageId { get; set; } 7 | public MessageAuthor Author { get; set; } 8 | public string Content { get; set; } = string.Empty; 9 | } -------------------------------------------------------------------------------- /src/Extensions/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LangChain.Extensions 7 | 8 | 9 | 10 | $(PackageTags);extensions 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Splitters/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LangChain.Splitters 7 | 8 | 9 | 10 | $(PackageTags);splitters 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Core/src/Callback/ICallbackManagerOptions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Callback; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface ICallbackManagerOptions 7 | { 8 | /// 9 | /// 10 | /// 11 | bool Verbose { get; set; } 12 | 13 | /// 14 | /// 15 | /// 16 | bool Tracing { get; set; } 17 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Hooks/StackableChainValues.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Schema; 2 | 3 | namespace LangChain.Chains.StackableChains.Context; 4 | 5 | /// 6 | /// 7 | /// 8 | public class StackableChainValues : ChainValues 9 | { 10 | /// 11 | /// 12 | /// 13 | public StackableChainHook? Hook { get; set; } 14 | } -------------------------------------------------------------------------------- /src/Core/src/Base/IBaseLangChainParams.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IBaseLangChainParams 7 | { 8 | /// 9 | /// Whether or not run in verbose mode. In verbose mode, some intermediate logs 10 | /// will be printed to the console. 11 | /// 12 | bool Verbose { get; set; } 13 | } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/Repository/StoredConversation.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Serve.Abstractions.Repository; 2 | 3 | public class StoredConversation 4 | { 5 | public Guid ConversationId { get; set; } 6 | public string ModelName { get; set; } = string.Empty; 7 | public string? ConversationName { get; set; } 8 | public DateTime CreatedAt { get; set; } 9 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LangChain.DocumentLoaders 7 | 8 | 9 | 10 | $(PackageTags);documentloaders;loaders;documents 11 | 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/pull-request.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | test: 9 | name: Test 10 | uses: HavenDV/workflows/.github/workflows/dotnet_build-test-publish.yml@main 11 | with: 12 | generate-build-number: false 13 | conventional-commits-publish-conditions: false 14 | additional-test-arguments: '--logger GitHubActions' -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "OpenAI": { 10 | "ModelId": "gpt-3.5-turbo", 11 | "ApiKey": "sk-*" 12 | }, 13 | "Anthropic": { 14 | "ModelId": "claude-instant-1", 15 | "ApiKey": "sk-*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Utilities/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | LangChain.Utilities 7 | $(NoWarn);NU5104 8 | 9 | 10 | 11 | $(PackageTags);utilities 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Code/CodePartType.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Code; 2 | 3 | /// 4 | /// 5 | /// 6 | public enum CodePartType 7 | { 8 | /// 9 | /// 10 | /// 11 | Unknown, 12 | 13 | /// 14 | /// 15 | /// 16 | Method, 17 | 18 | /// 19 | /// 20 | /// 21 | Constructor, 22 | } -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Text/ITextSplitter.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Text; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface ITextSplitter 7 | { 8 | /// 9 | /// Divides a chunk of text into smaller chunks. 10 | /// 11 | /// 12 | /// 13 | public IReadOnlyList SplitText(string text); 14 | } -------------------------------------------------------------------------------- /src/Splitters/Abstractions/test/LangChain.Splitters.Abstractions.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Serve/src/Services/CustomNameProvider.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions; 2 | using LangChain.Serve.Abstractions.Repository; 3 | 4 | namespace LangChain.Serve.Services; 5 | 6 | public class CustomNameProvider(Func, Task> generator) : IConversationNameProvider 7 | { 8 | public Task GetConversationName(IReadOnlyCollection messages) 9 | { 10 | return generator(messages); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/LLM/SerializedLLMChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.LLMS; 2 | using LangChain.Prompts; 3 | 4 | namespace LangChain.Chains.LLM; 5 | 6 | /// 7 | public class SerializedLlmChain : SerializedBaseChain 8 | { 9 | /// 10 | /// 11 | /// 12 | public required BaseLlm Llm { get; set; } 13 | 14 | /// 15 | /// 16 | /// 17 | public SerializedPromptTemplate Prompt { get; set; } = new(); 18 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Azure/LangChain.Samples.Azure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Memory/LangChain.Samples.Memory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/StringExtensions.StartsWith.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | 4 | namespace System; 5 | 6 | public static partial class PolyfillStringExtensions 7 | { 8 | public static bool StartsWith(this string text, char value) 9 | { 10 | text = text ?? throw new ArgumentNullException(nameof(text)); 11 | 12 | return text.StartsWith(value.ToString(), StringComparison.Ordinal); 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /examples/LangChain.Samples.OpenAI/LangChain.Samples.OpenAI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Prompts/LangChain.Samples.Prompts.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Cli/test/LangChain.Cli.IntegrationTests/LangChain.Cli.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/DocumentLoaderSettings.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | /// 4 | /// Document loader settings used to configure the behavior of the document loader. 5 | /// 6 | public class DocumentLoaderSettings 7 | { 8 | /// 9 | /// Should the document loader collect metadata about the document.
10 | /// Default is true. 11 | ///
12 | public bool ShouldCollectMetadata { get; set; } = true; 13 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.HuggingFace/LangChain.Samples.HuggingFace.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.SequentialChain/LangChain.Samples.SequentialChain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Core/src/Chains/CombineDocuments/BaseCombineDocumentsChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | 3 | namespace LangChain.Chains.CombineDocuments; 4 | 5 | /// 6 | public abstract class BaseCombineDocumentsChainInput : ChainInputs 7 | { 8 | /// 9 | /// 10 | /// 11 | public string InputKey { get; set; } = "input_documents"; 12 | 13 | /// 14 | /// 15 | /// 16 | public string OutputKey { get; set; } = "output_text"; 17 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Tools/BuiltIn/Classes/GoogleResults.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace LangChain.Chains.StackableChains.Agents.Tools.BuiltIn.Classes; 4 | 5 | public class GoogleResult 6 | { 7 | public class Item 8 | { 9 | public string title { get; set; } = string.Empty; 10 | public string link { get; set; } = string.Empty; 11 | public string snippet { get; set; } = string.Empty; 12 | 13 | } 14 | 15 | public List items { get; set; } = []; 16 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.OpenAI/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Providers.OpenAI.Predefined; 3 | 4 | var apiKey = 5 | Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? 6 | throw new InvalidOperationException("OPENAI_API_KEY environment variable is not found."); 7 | var model = new OpenAiLatestFastChatModel(apiKey); 8 | 9 | var result = await model.GenerateAsync("What is a good name for a company that sells colourful socks?"); 10 | 11 | Console.WriteLine(result); 12 | 13 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Extensions/HookExtension.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | 4 | namespace LangChain.Chains.StackableChains.Extensions; 5 | 6 | public static class HookExtension 7 | { 8 | public static T Hook(this T chain, Action hook) where T : BaseStackableChain 9 | { 10 | chain = chain ?? throw new ArgumentNullException(nameof(chain)); 11 | 12 | chain.SetHook(hook); 13 | return chain; 14 | } 15 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/Base/IBasePromptTemplateInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Schema; 2 | 3 | namespace LangChain.Prompts.Base; 4 | 5 | using System.Collections.Generic; 6 | 7 | /// 8 | /// 9 | /// 10 | public interface IBasePromptTemplateInput 11 | { 12 | /// 13 | /// 14 | /// 15 | IReadOnlyList InputVariables { get; } 16 | 17 | /// 18 | /// 19 | /// 20 | Dictionary PartialVariables { get; } 21 | } 22 | -------------------------------------------------------------------------------- /src/Core/src/Schema/BasePromptValue.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | 3 | namespace LangChain.Schema; 4 | 5 | /// 6 | /// 7 | /// 8 | public abstract class BasePromptValue 9 | { 10 | /// 11 | /// 12 | /// 13 | /// 14 | public abstract IReadOnlyCollection ToChatMessages(); 15 | 16 | /// 17 | /// 18 | /// 19 | /// 20 | public override abstract string ToString(); 21 | } -------------------------------------------------------------------------------- /src/Core/src/Base/ChainInputs.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Callback; 2 | 3 | namespace LangChain.Base; 4 | 5 | /// 6 | public class ChainInputs : IChainInputs 7 | { 8 | /// 9 | public ICallbacks? Callbacks { get; set; } 10 | 11 | /// 12 | public List Tags { get; set; } = new(); 13 | 14 | /// 15 | public Dictionary Metadata { get; set; } = new(); 16 | 17 | /// 18 | public bool Verbose { get; set; } 19 | } -------------------------------------------------------------------------------- /src/Serve/src/Services/DateConversationNameProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using LangChain.Serve.Abstractions; 3 | using LangChain.Serve.Abstractions.Repository; 4 | 5 | namespace LangChain.Serve.Services; 6 | 7 | public class DateConversationNameProvider : IConversationNameProvider 8 | { 9 | public Task GetConversationName(IReadOnlyCollection messages) 10 | { 11 | return Task.FromResult(DateTime.Now.ToString("yy-MM-dd HH:mm", CultureInfo.InvariantCulture)); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/LangChain.Core.UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Always 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Core/src/Prompts/IPromptTemplateInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | 3 | namespace LangChain.Prompts; 4 | 5 | /// 6 | public interface IPromptTemplateInput : IBasePromptTemplateInput 7 | { 8 | /// 9 | /// 10 | /// 11 | string Template { get; } 12 | 13 | /// 14 | /// 15 | /// 16 | TemplateFormatOptions? TemplateFormat { get; } 17 | 18 | /// 19 | /// 20 | /// 21 | bool? ValidateTemplate { get; } 22 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/LLM/ILlmChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | using LangChain.Prompts.Base; 3 | using LangChain.Providers; 4 | 5 | namespace LangChain.Chains.LLM; 6 | 7 | /// 8 | public interface ILlmChainInput : IChainInputs 9 | { 10 | /// 11 | /// 12 | /// 13 | BasePromptTemplate Prompt { get; } 14 | 15 | /// 16 | /// 17 | /// 18 | IChatModel Llm { get; } 19 | 20 | /// 21 | /// 22 | /// 23 | string OutputKey { get; set; } 24 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/Generation.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public class Generation 7 | { 8 | /// 9 | /// Generated text output 10 | /// 11 | public string? Text { get; set; } 12 | 13 | /// 14 | /// Raw generation info response from the provider. 15 | /// May include things like reason for finishing (e.g. in OpenAi) 16 | /// 17 | public Dictionary GenerationInfo { get; set; } = new Dictionary(); 18 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/LangChain.Samples.AspNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Meta/test/WikiTests.HowToUseOpenAiProviderSmaller.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers.OpenAI.Predefined; 2 | using static LangChain.Chains.Chain; 3 | 4 | namespace LangChain.IntegrationTests; 5 | 6 | [TestFixture] 7 | public partial class WikiTests 8 | { 9 | [Test] 10 | public async Task HowToUseOpenAiProviderSmaller() 11 | { 12 | var model = new OpenAiLatestFastChatModel("your_openAI_key"); 13 | var chain = 14 | Set("Hello!") 15 | | LLM(model); 16 | 17 | Console.WriteLine(await chain.RunAsync("text")); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Serve/src/Classes/DTO/PostMessageDTO.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve.Classes.DTO; 4 | 5 | public class PostMessageDto 6 | { 7 | public string Content { get; set; } = string.Empty; 8 | 9 | public StoredMessage ToStoredMessage(Guid conversationId) 10 | { 11 | return new StoredMessage 12 | { 13 | ConversationId = conversationId, 14 | Author = MessageAuthor.User, 15 | Content = Content, 16 | MessageId = Guid.NewGuid() 17 | }; 18 | } 19 | } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/LangChain.Serve.Abstractions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net8.0;net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | Abstractions for LangChain Serve 11 | $(PackageTags);serve;abstractions 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/StreamExtensions.CopyToAsync.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | 4 | namespace System; 5 | 6 | public static partial class PolyfillStreamExtensions 7 | { 8 | public static Task CopyToAsync( 9 | this Stream stream, 10 | Stream destination, 11 | CancellationToken cancellationToken) 12 | { 13 | stream = stream ?? throw new ArgumentNullException(nameof(stream)); 14 | 15 | return stream.CopyToAsync(destination, bufferSize: 81920, cancellationToken); 16 | } 17 | } 18 | #endif -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Exceptions/StackableChainException.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.HelperChains.Exceptions; 2 | 3 | /// 4 | [Serializable] 5 | public class StackableChainException : Exception 6 | { 7 | /// 8 | public StackableChainException(string message, Exception inner) : base(message, inner) 9 | { 10 | } 11 | 12 | /// 13 | public StackableChainException() 14 | { 15 | } 16 | 17 | /// 18 | public StackableChainException(string message) : base(message) 19 | { 20 | } 21 | } -------------------------------------------------------------------------------- /src/Core/src/Base/BaseLangChain.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | public abstract class BaseLangChain : IBaseLangChainParams 5 | { 6 | /// 7 | /// 8 | /// 9 | public bool Verbose { get; set; } 10 | 11 | /// 12 | /// 13 | /// 14 | /// 15 | protected BaseLangChain(IBaseLangChainParams parameters) 16 | { 17 | parameters = parameters ?? throw new ArgumentNullException(nameof(parameters)); 18 | 19 | Verbose = parameters.Verbose; 20 | } 21 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/HttpContext.ReadAsStringAsync.CancellationToken.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | namespace System.Net.Http; 4 | 5 | public static partial class HttpContextExtensions 6 | { 7 | public static async Task ReadAsStringAsync( 8 | this HttpContent content, 9 | CancellationToken cancellationToken = default) 10 | { 11 | content = content ?? throw new ArgumentNullException(nameof(content)); 12 | 13 | return await content.ReadAsStringAsync().ConfigureAwait(false); 14 | } 15 | } 16 | #endif -------------------------------------------------------------------------------- /src/Core/src/Base/Tracers/TracerException.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base.Tracers; 2 | 3 | /// 4 | /// Base class for exceptions in tracers module. 5 | /// 6 | [Serializable] 7 | public class TracerException : Exception 8 | { 9 | /// 10 | public TracerException(string message) : base(message) 11 | { 12 | } 13 | 14 | /// 15 | public TracerException() 16 | { 17 | } 18 | 19 | /// 20 | public TracerException(string message, Exception innerException) : base(message, innerException) 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/HttpClient.GetStreamAsync.CancellationToken.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | namespace System.Net.Http; 4 | 5 | public static partial class HttpClientExtensions 6 | { 7 | public static async Task GetStreamAsync( 8 | this HttpClient client, 9 | Uri uri, 10 | CancellationToken cancellationToken = default) 11 | { 12 | client = client ?? throw new ArgumentNullException(nameof(client)); 13 | 14 | return await client.GetStreamAsync(uri).ConfigureAwait(false); 15 | } 16 | } 17 | #endif -------------------------------------------------------------------------------- /src/Core/src/Chains/CombineDocuments/AnalyzeDocumentsChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Splitters.Text; 2 | 3 | namespace LangChain.Chains.CombineDocuments; 4 | 5 | /// 6 | public class AnalyzeDocumentsChainInput( 7 | BaseCombineDocumentsChain combineDocumentsChain) 8 | : BaseCombineDocumentsChainInput 9 | { 10 | /// 11 | /// 12 | /// 13 | public BaseCombineDocumentsChain CombineDocumentsChain { get; set; } = combineDocumentsChain; 14 | 15 | /// 16 | /// 17 | /// 18 | public ITextSplitter? Splitter { get; set; } 19 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/Base/StringPromptValue.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Schema; 3 | 4 | namespace LangChain.Prompts.Base; 5 | 6 | /// 7 | public class StringPromptValue : BasePromptValue 8 | { 9 | /// 10 | /// 11 | /// 12 | public string Value { get; set; } = string.Empty; 13 | 14 | /// 15 | public override IReadOnlyCollection ToChatMessages() 16 | { 17 | return new[] { Value.AsSystemMessage() }; 18 | } 19 | 20 | /// 21 | public override string ToString() => Value; 22 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/HttpClient.GetByteArrayAsync.CancellationToken.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | namespace System.Net.Http; 4 | 5 | public static partial class HttpClientExtensions 6 | { 7 | public static async Task GetByteArrayAsync( 8 | this HttpClient client, 9 | Uri uri, 10 | CancellationToken cancellationToken = default) 11 | { 12 | client = client ?? throw new ArgumentNullException(nameof(client)); 13 | 14 | return await client.GetByteArrayAsync(uri).ConfigureAwait(false); 15 | } 16 | } 17 | #endif -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Code/ICodeSplitter.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Code; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface ICodeSplitter 7 | { 8 | /// 9 | /// Divides a document into its component parts, returning the title, type, and content of each part. 10 | /// 11 | /// 12 | /// 13 | /// 14 | public Task> SplitAsync( 15 | string content, 16 | CancellationToken cancellationToken = default); 17 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/RetrievalQA/RetrievalQaChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.CombineDocuments; 2 | using LangChain.Retrievers; 3 | 4 | namespace LangChain.Chains.RetrievalQA; 5 | 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | public class RetrievalQaChainInput( 12 | BaseCombineDocumentsChain combineDocumentsChain, 13 | BaseRetriever retriever) 14 | : BaseRetrievalQaChainInput(combineDocumentsChain) 15 | { 16 | /// Documents retriever. 17 | public BaseRetriever Retriever { get; } = retriever; 18 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/SerializedBasePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | /// 5 | /// 6 | public class SerializedBasePromptTemplate 7 | { 8 | /// 9 | /// 10 | /// 11 | public string Type { get; set; } = string.Empty; 12 | 13 | /// 14 | /// 15 | /// 16 | public List InputVariables { get; set; } = new List(); 17 | 18 | //public TemplateFormat TemplateFormat { get; set; } 19 | 20 | /// 21 | /// 22 | /// 23 | public string Template { get; set; } = string.Empty; 24 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/LLMResult.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | /// 5 | /// 6 | public class LlmResult 7 | { 8 | /// 9 | /// List of the things generated. Each input could have multiple , hence this is a list of lists. 10 | /// 11 | public IReadOnlyList Generations { get; set; } = Array.Empty(); 12 | 13 | /// 14 | /// Dictionary of arbitrary LLM-provider specific output. 15 | /// 16 | public Dictionary LlmOutput { get; set; } = new Dictionary(); 17 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Azure/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Providers.Azure; 3 | 4 | var provider = new AzureOpenAiProvider(apiKey: "AZURE_OPEN_AI_KEY", endpoint: "ENDPOINT", deploymentID: "DEPLOYMENT_NAME"); 5 | var llm = new AzureOpenAiChatModel(provider, id: "DEPLOYMENT_NAME"); 6 | 7 | var result = await llm.GenerateAsync("What is a good name for a company that sells colourful socks?"); 8 | 9 | Console.WriteLine(result); 10 | 11 | //Image test 12 | //var imageUrl = await model.GenerateImageAsUrlAsync("a blue horse called azure"); 13 | //Console.WriteLine(model.RevisedPromptResult); 14 | //Console.WriteLine(imageUrl); 15 | -------------------------------------------------------------------------------- /src/Core/src/Base/Tracers/BaseCallbackHandlerInput.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base.Tracers; 2 | 3 | /// 4 | public class BaseCallbackHandlerInput : IBaseCallbackHandlerInput 5 | { 6 | /// 7 | public bool IgnoreLlm { get; set; } 8 | 9 | /// 10 | public bool IgnoreRetry { get; set; } 11 | 12 | /// 13 | public bool IgnoreChain { get; set; } 14 | 15 | /// 16 | public bool IgnoreAgent { get; set; } 17 | 18 | /// 19 | public bool IgnoreRetriever { get; set; } 20 | 21 | /// 22 | public bool IgnoreChatModel { get; set; } 23 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Tests.Html.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders.IntegrationTests; 2 | 3 | public partial class Tests 4 | { 5 | [Test] 6 | public async Task Html() 7 | { 8 | var loader = new HtmlLoader(); 9 | 10 | var documents = await loader.LoadAsync(DataSource.FromUrl("https://en.wikipedia.org/wiki/Web_scraping")); 11 | 12 | documents.Should().NotBeEmpty(); 13 | var first = documents.First(); 14 | 15 | first.PageContent.Should().Contain("Web scraping, web harvesting, or web data extraction is"); 16 | first.PageContent.Should().Contain("This page was last edited on"); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/LangChain.Polyfills.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA1308 6 | 7 | 8 | 9 | LangChain polyfills for .Net Framework/.Net Standard to reduce #ifs in code. 10 | $(PackageTags);polyfills 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Code/CodePart.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Code; 2 | 3 | /// 4 | /// Represents a part of a document. 5 | /// 6 | /// 7 | /// 8 | /// 9 | public readonly record struct CodePart( 10 | string Name, 11 | string Content, 12 | CodePartType Type = CodePartType.Unknown) 13 | { 14 | /// 15 | /// Represents an empty document part. 16 | /// 17 | public static CodePart Empty { get; } = new( 18 | Name: string.Empty, 19 | Content: string.Empty, 20 | Type: CodePartType.Unknown); 21 | } -------------------------------------------------------------------------------- /src/Core/src/Extensions/AddDocumentsToDatabaseBehavior.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Extensions; 2 | 3 | public enum AddDocumentsToDatabaseBehavior 4 | { 5 | /// 6 | /// If the collection already exists, it will be returned without any changes. 7 | /// 8 | JustReturnCollectionIfCollectionIsAlreadyExists, 9 | 10 | /// 11 | /// If the collection already exists, it will be deleted and recreated. 12 | /// 13 | OverwriteExistingCollection, 14 | 15 | /// 16 | /// If the collection already exists, all documents will be added to the existing collection. 17 | /// 18 | AlwaysAddDocuments, 19 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/IDocumentLoader.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | /// 4 | /// Defines a contract for loading documents from a data source. 5 | /// 6 | public interface IDocumentLoader 7 | { 8 | /// 9 | /// Loads documents from a data source. 10 | /// 11 | /// 12 | /// 13 | /// 14 | Task> LoadAsync( 15 | DataSource dataSource, 16 | DocumentLoaderSettings? settings = null, 17 | CancellationToken cancellationToken = default); 18 | } -------------------------------------------------------------------------------- /.github/workflows/auto-labeling.yml: -------------------------------------------------------------------------------- 1 | name: Auto-labeling issue 2 | on: 3 | issues: 4 | types: 5 | - opened 6 | 7 | permissions: 8 | issues: write 9 | 10 | jobs: 11 | auto-labeling: 12 | uses: oscoreio/ai-workflows/.github/workflows/auto-labeling.yml@main 13 | with: 14 | issue-number: ${{ github.event.issue.number }} 15 | model: free-fast 16 | provider: openrouter 17 | instructions: 'if an issue looks simple and does not affect database, add one of aider labels to try to solve it automatically' 18 | secrets: 19 | personal-access-token: ${{ secrets.PERSONAL_TOKEN }} 20 | openrouter-api-key: ${{ secrets.OPENROUTER_API_KEY_FOR_PRS }} -------------------------------------------------------------------------------- /src/Core/src/Prompts/SerializedMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | /// 5 | /// 6 | public class SerializedMessagePromptTemplate 7 | { 8 | /// 9 | /// 10 | /// 11 | public string Type { get; set; } = "message"; 12 | 13 | /// 14 | /// 15 | /// 16 | public List InputVariables { get; set; } = new List(); 17 | 18 | /// 19 | /// 20 | /// 21 | // Additional properties are handled by a dictionary 22 | public Dictionary AdditionalProperties { get; set; } = new Dictionary(); 23 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/LangChain.DocumentLoaders.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | LangChain.DocumentLoaders.IntegrationTests 6 | $(NoWarn) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Code/ICodeCutter.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Code; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface ICodeCutter 7 | { 8 | /// 9 | /// Trims the selected text so that it includes only the required things and the specified names after splitting. 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | public Task CutAsync( 16 | string content, 17 | IReadOnlyCollection requiredNames, 18 | CancellationToken cancellationToken = default); 19 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/DictionaryExtensions.GetValueOrDefault.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | // ReSharper disable once CheckNamespace 5 | 6 | namespace System; 7 | 8 | public static partial class PolyfillDictionaryExtensions 9 | { 10 | [return: NotNullIfNotNull(nameof(defaultValue))] 11 | public static TValue? GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key, TValue? defaultValue = default) 12 | { 13 | dictionary = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); 14 | 15 | return dictionary.TryGetValue(key, out var value) ? value : defaultValue; 16 | } 17 | } 18 | #endif -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "nuget" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | groups: 13 | all: 14 | patterns: 15 | - "*" 16 | ignore: 17 | - dependency-name: Microsoft.CodeAnalysis.CSharp 18 | -------------------------------------------------------------------------------- /src/Utilities/Postgres/src/StringBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace LangChain.Utilities.Postgres; 4 | 5 | internal static class StringBuilderExtensions 6 | { 7 | public static void AppendJoin(this StringBuilder builder, string separator, IEnumerable collection) 8 | { 9 | var first = true; 10 | foreach (var line in collection) 11 | { 12 | if (first) 13 | { 14 | first = false; 15 | builder.Append(line); 16 | } 17 | else 18 | { 19 | builder.Append(separator); 20 | builder.Append(line); 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/ChatPromptTemplateInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | 3 | namespace LangChain.Prompts; 4 | 5 | /// 6 | public class ChatPromptTemplateInput : IBasePromptTemplateInput 7 | { 8 | /// 9 | /// 10 | /// 11 | public List PromptMessages { get; set; } = new(); 12 | 13 | /// 14 | /// 15 | /// 16 | public bool ValidateTemplate { get; set; } = true; 17 | 18 | /// 19 | public IReadOnlyList InputVariables { get; set; } = new List(); 20 | 21 | /// 22 | public Dictionary PartialVariables { get; set; } = new(); 23 | } -------------------------------------------------------------------------------- /src/Core/src/Extensions/VectorSearchResponseExtesions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Databases; 2 | using LangChain.DocumentLoaders; 3 | 4 | namespace LangChain.Extensions; 5 | 6 | /// 7 | /// 8 | /// 9 | public static class VectorSearchResponseExtensions 10 | { 11 | public static IReadOnlyList ToDocuments( 12 | this VectorSearchResponse vectorSearchResponse) 13 | { 14 | vectorSearchResponse = vectorSearchResponse ?? throw new ArgumentNullException(nameof(vectorSearchResponse)); 15 | 16 | return vectorSearchResponse.Items 17 | .Select(static x => new Document(x.Text, x.Metadata?.ToDictionary(x => x.Key, x => x.Value))) 18 | .ToArray(); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Serve/Abstractions/LangChain.Serve.Abstractions/IConversationRepository.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve.Abstractions; 4 | 5 | public interface IConversationRepository 6 | { 7 | public Task CreateConversation(string modelName); 8 | public Task UpdateConversationName(Guid conversationId, string conversationName); 9 | public Task GetConversation(Guid conversationId); 10 | public Task DeleteConversation(Guid conversationId); 11 | public Task> ListConversations(); 12 | 13 | public Task AddMessage(StoredMessage message); 14 | public Task> ListMessages(Guid conversationId); 15 | } -------------------------------------------------------------------------------- /src/Splitters/CSharp/src/LangChain.Splitters.CSharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | 6 | 7 | 8 | LangChain C# Splitter implementation. 9 | $(PackageTags);csharp 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Core/src/Prompts/ChatPromptValue.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public class ChatPromptValue( 9 | IReadOnlyCollection messages) 10 | : BasePromptValue 11 | { 12 | /// 13 | /// 14 | /// 15 | public IReadOnlyCollection Messages { get; set; } = messages; 16 | 17 | /// 18 | public override string ToString() 19 | { 20 | return JsonSerializer.Serialize(this.Messages); 21 | } 22 | 23 | /// 24 | public override IReadOnlyCollection ToChatMessages() 25 | { 26 | return this.Messages; 27 | } 28 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Tests.Word.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders.IntegrationTests; 2 | 3 | public partial class Tests 4 | { 5 | [Test] 6 | public async Task Word() 7 | { 8 | var loader = new WordLoader(); 9 | var documents = await loader.LoadAsync(DataSource.FromStream(H.Resources.file_sample_1MB_docx.AsStream())); 10 | 11 | documents.Should().NotBeEmpty(); 12 | 13 | // check text from paragraph 1 14 | documents.First().PageContent.Should().Contain("Lorem ipsum "); 15 | 16 | // check text from paragraph 2 17 | documents.Skip(1).First().PageContent.Should().Contain("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac faucibus odio. "); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Utilities/Sql/src/LangChain.Utilities.Sql.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA1845;CA1865 6 | 7 | 8 | 9 | LangChain Utilities SqlDatabase. 10 | $(PackageTags);sqldatabase 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Extensions/Docker/src/LangChain.Extensions.Docker.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;netstandard2.1;net8.0;net9.0 5 | $(NoWarn);CA1307 6 | 7 | 8 | 9 | Docker extension 10 | $(PackageTags);docker 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Serve/src/LangChain.Serve.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0;net9.0 5 | enable 6 | enable 7 | $(NoWarn);CA1002;CA1822 8 | 9 | 10 | 11 | LangChain Serve 12 | $(PackageTags);serve 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Cli/src/Commands/DoCommand.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | 3 | namespace LangChain.Cli.Commands; 4 | 5 | internal sealed class DoCommand : Command 6 | { 7 | public DoCommand() : base(name: "do", description: "Generates text using a prompt.") 8 | { 9 | var handler = new DoCommandHandler(); 10 | 11 | AddOption(handler.InputOption); 12 | AddOption(handler.InputFileOption); 13 | AddOption(handler.OutputFileOption); 14 | AddOption(handler.ToolsOption); 15 | AddOption(handler.DirectoriesOption); 16 | AddOption(handler.FormatOption); 17 | AddOption(handler.DebugOption); 18 | AddOption(handler.ModelOption); 19 | AddOption(handler.ProviderOption); 20 | 21 | Handler = handler; 22 | } 23 | } -------------------------------------------------------------------------------- /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | on: 3 | push: 4 | branches: 5 | - main 6 | tags: 7 | - v** 8 | 9 | jobs: 10 | publish: 11 | name: Publish 12 | uses: HavenDV/workflows/.github/workflows/dotnet_build-test-publish.yml@main 13 | with: 14 | generate-build-number: false 15 | conventional-commits-publish-conditions: false 16 | additional-test-arguments: '--logger GitHubActions' 17 | secrets: 18 | nuget-key: ${{ secrets.NUGET_KEY }} 19 | 20 | todo-to-issue: 21 | name: Run TODO to Issue 22 | if: github.event.ref == 'refs/heads/main' 23 | runs-on: "ubuntu-latest" 24 | steps: 25 | - uses: "actions/checkout@v4" 26 | - name: "TODO to Issue" 27 | uses: "alstr/todo-to-issue-action@v4" 28 | -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/DocumentLookupExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | public static class DocumentLookupExtensions 4 | { 5 | /// 6 | /// Lookup a term in the page, imitating cmd-F functionality. 7 | /// 8 | public static IEnumerable Lookup(this Document document, string searchString) 9 | { 10 | document = document ?? throw new ArgumentNullException(nameof(document)); 11 | searchString = searchString ?? throw new ArgumentNullException(nameof(searchString)); 12 | 13 | foreach (var lookup in document.Paragraphs() 14 | .Where(p => p.Contains(searchString, StringComparison.OrdinalIgnoreCase))) 15 | { 16 | yield return lookup; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Utilities/Postgres/test/LangChain.Utilities.Postgres.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | LangChain.Utilities.PostresDatabases.IntegrationTests 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Core/src/Prompts/Base/BaseStringPromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Schema; 2 | 3 | namespace LangChain.Prompts.Base; 4 | 5 | /// 6 | public abstract class BaseStringPromptTemplate : BasePromptTemplate 7 | { 8 | /// 9 | public override async Task FormatPromptValueAsync( 10 | InputValues values, 11 | CancellationToken cancellationToken = default) 12 | { 13 | var formattedPrompt = await FormatAsync(values, cancellationToken).ConfigureAwait(false); 14 | 15 | return new StringPromptValue() 16 | { 17 | Value = formattedPrompt 18 | }; 19 | } 20 | 21 | /// 22 | protected BaseStringPromptTemplate(IBasePromptTemplateInput input) : base(input) 23 | { 24 | } 25 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Extensions.DependencyInjection; 2 | 3 | var builder = WebApplication.CreateBuilder(args); 4 | 5 | // Add services to the container. 6 | 7 | builder.Services.AddControllers(); 8 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 9 | builder.Services.AddEndpointsApiExplorer(); 10 | builder.Services.AddSwaggerGen(); 11 | 12 | builder.Services.AddOpenAi(); 13 | builder.Services.AddAnthropic(); 14 | 15 | var app = builder.Build(); 16 | 17 | // Configure the HTTP request pipeline. 18 | if (app.Environment.IsDevelopment()) 19 | { 20 | app.UseSwagger(); 21 | app.UseSwaggerUI(); 22 | } 23 | 24 | app.UseHttpsRedirection(); 25 | 26 | app.UseAuthorization(); 27 | 28 | app.MapControllers(); 29 | 30 | app.Run(); -------------------------------------------------------------------------------- /src/Core/src/Base/Tracers/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base.Tracers; 2 | 3 | /// 4 | /// 5 | /// 6 | public static class StringExtensions 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | public static string Capitalize(this string word) 14 | { 15 | word = word ?? throw new ArgumentNullException(nameof(word)); 16 | 17 | if (word.Length == 1) 18 | { 19 | return word.ToUpper(System.Globalization.CultureInfo.CurrentCulture); 20 | } 21 | 22 | return word.Substring(0, 1).ToUpper(System.Globalization.CultureInfo.CurrentCulture) 23 | + word.Substring(1).ToLower(System.Globalization.CultureInfo.CurrentCulture); 24 | } 25 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Tools/AgentToolLambda.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.StackableChains.Agents.Tools; 2 | 3 | /// 4 | /// 5 | /// 6 | public class AgentToolLambda : AgentTool 7 | { 8 | private readonly Func> _func; 9 | 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | public AgentToolLambda(string name, string description, Func> func) : base(name, description) 17 | { 18 | _func = func; 19 | } 20 | 21 | /// 22 | public override Task ToolTask(string input, CancellationToken cancellationToken = default) 23 | { 24 | return _func(input); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/PromptTemplateInput.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Prompts; 2 | 3 | /// 4 | public class PromptTemplateInput( 5 | string template, 6 | IReadOnlyList inputVariables, 7 | Dictionary? partialVariables = null) 8 | : IPromptTemplateInput 9 | { 10 | /// 11 | public string Template { get; private set; } = template; 12 | 13 | /// 14 | public TemplateFormatOptions? TemplateFormat { get; set; } 15 | 16 | /// 17 | public bool? ValidateTemplate { get; set; } 18 | 19 | /// 20 | public IReadOnlyList InputVariables { get; private set; } = inputVariables; 21 | 22 | /// 23 | public Dictionary PartialVariables { get; private set; } = partialVariables ?? new(); 24 | } -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/LangChain.Splitters.Abstractions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1307;CA1822 6 | 7 | 8 | 9 | LangChain Splitter abstractions. 10 | $(PackageTags);abstractions 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Utilities/Sql/src/StringHelperer.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Utilities.Sql; 2 | 3 | internal static class StringHelperer 4 | { 5 | /// 6 | /// Truncate a string to a certain number of words, based on the max string length. 7 | /// 8 | public static string? TruncateWord(object content, int length, string suffix = "...") 9 | { 10 | if (length > 0 && content is string contentString) 11 | { 12 | if (contentString.Length <= length) 13 | { 14 | return contentString; 15 | } 16 | 17 | var substring = contentString.Substring(0, length - suffix.Length); 18 | 19 | return substring.Substring(0, substring.LastIndexOf(" ", StringComparison.Ordinal)) + suffix; 20 | } 21 | 22 | return content.ToString(); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Core/src/Base/IBaseCallbackHandlerInput.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Base; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IBaseCallbackHandlerInput 7 | { 8 | /// Whether to ignore LLM callbacks. 9 | bool IgnoreLlm { get; set; } 10 | 11 | /// Whether to ignore retry callbacks. 12 | bool IgnoreRetry { get; set; } 13 | 14 | /// Whether to ignore chain callbacks. 15 | bool IgnoreChain { get; set; } 16 | 17 | /// Whether to ignore agent callbacks. 18 | bool IgnoreAgent { get; set; } 19 | 20 | /// Whether to ignore retriever callbacks. 21 | bool IgnoreRetriever { get; set; } 22 | 23 | /// Whether to ignore chat model callbacks. 24 | bool IgnoreChatModel { get; set; } 25 | } -------------------------------------------------------------------------------- /src/Core/src/Schema/OutputParserException.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Schema; 2 | 3 | /// 4 | [Serializable] 5 | public class OutputParserException : Exception 6 | { 7 | /// 8 | /// 9 | /// 10 | public string Output { get; } = string.Empty; 11 | 12 | /// 13 | public OutputParserException(string message, string? output = null) : base(message) 14 | { 15 | Output = output ?? string.Empty; 16 | } 17 | 18 | /// 19 | public OutputParserException() 20 | { 21 | } 22 | 23 | /// 24 | public OutputParserException(string message) : base(message) 25 | { 26 | } 27 | 28 | /// 29 | public OutputParserException(string message, Exception innerException) : base(message, innerException) 30 | { 31 | } 32 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Crew/Tools/CrewAgentToolLambda.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.StackableChains.Agents.Crew.Tools; 2 | 3 | /// 4 | /// 5 | /// 6 | public class CrewAgentToolLambda : CrewAgentTool 7 | { 8 | private readonly Func> _func; 9 | 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | public CrewAgentToolLambda(string name, string description, Func> func) : base(name, description) 17 | { 18 | _func = func; 19 | } 20 | 21 | /// 22 | public override Task ToolTask(string input, CancellationToken cancellationToken = default) 23 | { 24 | return _func(input); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Serve/OpenAI/ServeOptions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | 3 | namespace LangChain.Serve.OpenAI; 4 | 5 | public class ServeOptions 6 | { 7 | private readonly Dictionary _models = new(); 8 | 9 | public ServeOptions RegisterModel(ChatModel chatModel, string? overrideId = null) 10 | { 11 | chatModel = chatModel ?? throw new ArgumentNullException(nameof(chatModel)); 12 | 13 | _models[overrideId ?? chatModel.Id] = chatModel; 14 | return this; 15 | } 16 | 17 | public ChatModel GetModel(string modelName) 18 | { 19 | return _models[modelName]; 20 | } 21 | 22 | public List ListModels() 23 | { 24 | return _models.Keys.ToList(); 25 | } 26 | 27 | public bool ModelExists(string modelName) 28 | { 29 | return _models.ContainsKey(modelName); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Extensions/Docker/src/Chain.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Extensions.Docker; 2 | 3 | /// 4 | /// 5 | /// 6 | public static class Chain 7 | { 8 | /// 9 | /// Executes code in a docker container 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static DockerChain RunCodeInDocker( 18 | string image = "python:3.10", 19 | string arguments = "main.py", 20 | string command = "python", 21 | string? attachVolume = null, 22 | string outputKey = "result") 23 | { 24 | return new DockerChain(image, arguments, command, attachVolume, outputKey); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Serve/src/ServeOptions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve; 4 | 5 | public class ServeOptions 6 | { 7 | private readonly Dictionary, Task>> _models = new(); 8 | 9 | public ServeOptions RegisterModel(string name, Func, Task> messageProcessor) 10 | { 11 | _models[name] = messageProcessor; 12 | return this; 13 | } 14 | 15 | public Func, Task> GetModel(string modelName) 16 | { 17 | return _models[modelName]; 18 | } 19 | 20 | public List ListModels() 21 | { 22 | return _models.Keys.ToList(); 23 | } 24 | 25 | public bool ModelExists(string modelName) 26 | { 27 | return _models.ContainsKey(modelName); 28 | } 29 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Word/src/LangChain.DocumentLoaders.Word.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA2016 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | LangChain Word document loader. 14 | $(PackageTags);word 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.LocalRAG/LangChain.Samples.LocalRAG.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/DocumentLoaders/WebBase/src/LangChain.DocumentLoaders.Html.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA1056;CA1054;CA1822 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | LangChain web document loader. 14 | $(PackageTags);pdf 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Core/src/Chains/LLM/ILlmChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Chains.Base; 2 | using LangChain.Abstractions.Schema; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Chains.LLM; 6 | 7 | /// 8 | /// 9 | /// 10 | public interface ILlmChain : IChain, ILlmChainInput 11 | { 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | Task PredictAsync(ChainValues values, CancellationToken cancellationToken = default); 19 | 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | Task> ApplyAsync(IReadOnlyList inputs, CancellationToken cancellationToken = default); 27 | } -------------------------------------------------------------------------------- /src/Serve/OpenAI/LangChain.Serve.OpenAI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0;net9.0 5 | enable 6 | enable 7 | $(NoWarn);CA1002;CA1822;CS3003 8 | 9 | 10 | 11 | LangChain Serve as OpenAI sdk compatible API 12 | $(PackageTags);serve;openai;api;aspnet;proxy;wrapper 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Meta/test/DatabaseTestEnvironment.cs: -------------------------------------------------------------------------------- 1 | using DotNet.Testcontainers.Containers; 2 | using LangChain.Providers; 3 | 4 | namespace LangChain.Databases.IntegrationTests; 5 | 6 | public sealed class DatabaseTestEnvironment : IAsyncDisposable 7 | { 8 | public required IVectorDatabase VectorDatabase { get; set; } 9 | public IEmbeddingModel? EmbeddingModel { get; set; } 10 | public int Port { get; set; } 11 | public string CollectionName { get; set; } = "test" + Guid.NewGuid().ToString("N"); 12 | public int Dimensions { get; set; } = 1536; 13 | public IContainer? Container { get; set; } 14 | 15 | public async ValueTask DisposeAsync() 16 | { 17 | if (Container != null) 18 | { 19 | await Container.DisposeAsync(); 20 | } 21 | if (VectorDatabase is IDisposable disposable) 22 | { 23 | disposable.Dispose(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/RetrievalQA/BaseRetrievalQaChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | using LangChain.Chains.CombineDocuments; 3 | 4 | namespace LangChain.Chains.RetrievalQA; 5 | 6 | /// 7 | /// 8 | /// 9 | /// 10 | public class BaseRetrievalQaChainInput(BaseCombineDocumentsChain combineDocumentsChain) : ChainInputs 11 | { 12 | /// Chain to use to combine the documents. 13 | public BaseCombineDocumentsChain CombineDocumentsChain { get; } = combineDocumentsChain; 14 | 15 | /// Return the source documents or not. 16 | public bool ReturnSourceDocuments { get; set; } 17 | 18 | /// 19 | /// 20 | /// 21 | public string InputKey { get; set; } = "question"; 22 | 23 | /// 24 | /// 25 | /// 26 | public string OutputKey { get; set; } = "output_text"; 27 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/IntegrationTests/Tests.Pdf.cs: -------------------------------------------------------------------------------- 1 | // namespace LangChain.DocumentLoaders.IntegrationTests; 2 | // 3 | // public partial class Tests 4 | // { 5 | // [Test] 6 | // public Task Pdf() 7 | // { 8 | // return Task.CompletedTask; 9 | // // CICD exception UglyToad.PdfPig.Core.PdfDocumentFormatException : Expected name as dictionary key, instead got: 0 10 | // // var loader = new PdfPigPdfLoader(); 11 | // // var documents = await loader.LoadAsync(DataSource.FromStream(H.Resources.sample_pdf.AsStream())); 12 | // // 13 | // // documents.Should().NotBeEmpty(); 14 | // // 15 | // // // check text from page 1 16 | // // documents.First().PageContent.Should().Contain("A Simple PDF File"); 17 | // // 18 | // // // check text from page 2 19 | // // documents.Skip(1).First().PageContent.Should().Contain("Simple PDF File 2"); 20 | // } 21 | // } -------------------------------------------------------------------------------- /src/Meta/test/LangChain.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | $(NoWarn);NETSDK1206 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:26462", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5000", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "swagger", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/SetLambdaChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | 3 | namespace LangChain.Chains.HelperChains; 4 | 5 | /// 6 | public class SetLambdaChain : BaseStackableChain 7 | { 8 | /// 9 | public SetLambdaChain(Func queryGetter, string outputKey = "query") 10 | { 11 | OutputKeys = new[] { outputKey }; 12 | QueryGetter = queryGetter; 13 | } 14 | 15 | /// 16 | /// 17 | /// 18 | public Func QueryGetter { get; set; } 19 | 20 | /// 21 | protected override Task InternalCallAsync( 22 | IChainValues values, 23 | CancellationToken cancellationToken = default) 24 | { 25 | values = values ?? throw new ArgumentNullException(nameof(values)); 26 | 27 | values.Value[OutputKeys[0]] = QueryGetter(); 28 | return Task.FromResult(values); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/Tools/GoogleCustomSearchToolTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.StackableChains.Agents.Tools.BuiltIn; 2 | 3 | namespace LangChain.Core.UnitTests.Tools; 4 | 5 | [TestFixture, Explicit] 6 | public class GoogleCustomSearchToolTests 7 | { 8 | [Test] 9 | public async Task SearchCat() 10 | { 11 | var apiKey = 12 | Environment.GetEnvironmentVariable("GOOGLE_SEARCH_API_KEY") ?? 13 | throw new InvalidOperationException("GOOGLE_SEARCH_API_KEY is not set"); 14 | var cx = 15 | Environment.GetEnvironmentVariable("GOOGLE_SEARCH_CX") ?? 16 | throw new InvalidOperationException("GOOGLE_SEARCH_CX is not set"); 17 | var tool = new GoogleCustomSearchTool(apiKey, cx, useCache: false, resultsLimit: 3); 18 | 19 | var result = await tool.ToolTask("find me a cat"); 20 | 21 | Console.WriteLine(result); 22 | 23 | result.Should().NotBeNullOrEmpty(); 24 | } 25 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve.OpenAI/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:26462", 8 | "sslPort": 0 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5000", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "swagger", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Cli/README.md: -------------------------------------------------------------------------------- 1 | # LangChain CLI 2 | 3 | This is a console utility that will help you use our library for such tasks: 4 | - Summarize text 5 | - Generate release notes 6 | - Generate changelog 7 | - Generate documentation 8 | - Generate code snippets 9 | - Generate code samples 10 | - Generate code documentation 11 | 12 | ## Usage: 13 | ``` 14 | dotnet tool install --global langchain.cli --prerelease 15 | langchain auth openai OPENAI_API_KEY # Default model - gpt-3.5-turbo, you can specify another model using --model parameter 16 | langchain summarize --input-file README.md --output-file SUMMARY.md 17 | langchain generate --input "Give me random word" # It will output a random word to console 18 | 19 | # Smart task 20 | langchain model gpt-4-turbo 21 | langchain generate --input "Give me a solution for the next problem: $PROBLEM" 22 | ``` 23 | 24 | ## Samples 25 | - Auto-labeling: https://github.com/tryAGI/LangChain/blob/main/.github/workflows/auto-labeling.yml 26 | -------------------------------------------------------------------------------- /src/Serve/src/Classes/DTO/MessageDTO.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve.Classes.DTO; 4 | 5 | public class MessageDto 6 | { 7 | public string Content { get; set; } = string.Empty; 8 | 9 | public string Author { get; set; } = string.Empty; 10 | 11 | public Guid ConversationId { get; set; } 12 | 13 | public Guid MessageId { get; set; } 14 | 15 | public static MessageDto FromStoredMessage(StoredMessage message, string modelName) 16 | { 17 | message = message ?? throw new ArgumentNullException(nameof(message)); 18 | 19 | return new MessageDto 20 | { 21 | ConversationId = message.ConversationId, 22 | Author = message.Author == MessageAuthor.User 23 | ? "You" 24 | : modelName, 25 | Content = message.Content, 26 | MessageId = message.MessageId 27 | }; 28 | } 29 | 30 | 31 | 32 | 33 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Hooks/StackableChainHook.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.HelperChains; 2 | 3 | namespace LangChain.Chains.StackableChains.Context; 4 | 5 | /// 6 | /// 7 | /// 8 | public class StackableChainHook 9 | { 10 | /// 11 | /// 12 | /// 13 | /// 14 | public virtual void ChainStart(StackableChainValues values) 15 | { 16 | } 17 | 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | public virtual void LinkEnter(BaseStackableChain chain, StackableChainValues values) 24 | { 25 | } 26 | 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public virtual void LinkExit(BaseStackableChain chain, StackableChainValues values) 33 | { 34 | } 35 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/SetChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Chains.Base; 2 | using LangChain.Abstractions.Schema; 3 | using LangChain.Callback; 4 | 5 | namespace LangChain.Chains.HelperChains; 6 | 7 | /// 8 | public class SetChain : BaseStackableChain 9 | { 10 | /// 11 | public SetChain(object value, string outputKey = "query") 12 | { 13 | OutputKeys = new[] { outputKey }; 14 | Value = value; 15 | } 16 | 17 | /// 18 | /// 19 | /// 20 | public object Value { get; set; } 21 | 22 | /// 23 | protected override Task InternalCallAsync( 24 | IChainValues values, 25 | CancellationToken cancellationToken = default) 26 | { 27 | values = values ?? throw new ArgumentNullException(nameof(values)); 28 | 29 | values.Value[OutputKeys[0]] = Value; 30 | return Task.FromResult(values); 31 | } 32 | } -------------------------------------------------------------------------------- /src/Core/src/Common/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Common; 2 | 3 | /// 4 | /// 5 | /// 6 | public static class DictionaryExtensions 7 | { 8 | /// 9 | /// Adds key values of additional to target dictionary if key is not yet present in target 10 | /// 11 | /// target dictionary 12 | public static void TryAddKeyValues( 13 | this Dictionary target, 14 | IReadOnlyDictionary additional) 15 | where TKey : notnull 16 | { 17 | target = target ?? throw new ArgumentNullException(nameof(target)); 18 | additional = additional ?? throw new ArgumentNullException(nameof(additional)); 19 | 20 | foreach (var kv in additional) 21 | { 22 | if (!target.ContainsKey(kv.Key)) 23 | { 24 | target.Add(kv.Key, kv.Value); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Meta/test/CalculatorTool.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using LangChain.Chains.StackableChains.Agents.Crew.Tools; 3 | 4 | namespace LangChain.IntegrationTests; 5 | 6 | public class CalculatorTool() 7 | : CrewAgentTool("calculate", "Useful to perform any math calculation like sum, minus, multiplication, division, etc." + 8 | "The input to this tool should be mathematical expression. " + 9 | "For example: '2 + 2' or '3 * 4'.)" 10 | ) 11 | { 12 | public override Task ToolTask(string operation, CancellationToken token = default) 13 | { 14 | try 15 | { 16 | var dt = new DataTable(); 17 | var compute = dt.Compute(operation, ""); 18 | 19 | return Task.FromResult(compute.ToString()!); 20 | } 21 | catch (SyntaxErrorException e) 22 | { 23 | Console.WriteLine(e); 24 | throw; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Core/src/Base/BaseLanguageModel.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Schema; 2 | 3 | namespace LangChain.Base; 4 | 5 | /// 6 | public abstract class BaseLanguageModel : BaseLangChain 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | protected BaseLanguageModel(IBaseLanguageModelParams parameters) : base(parameters) 13 | { 14 | } 15 | 16 | /// 17 | /// 18 | /// 19 | public abstract string ModelType { get; set; } 20 | 21 | /// 22 | /// 23 | /// 24 | public abstract string LlmType { get; set; } 25 | 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public abstract Task GeneratePrompt(BasePromptValue[] promptValues, IReadOnlyCollection? stopSequences = null); 33 | } -------------------------------------------------------------------------------- /.github/workflows/github-releases-to-discord.yml: -------------------------------------------------------------------------------- 1 | name: GitHub Releases To Discord 2 | on: 3 | release: 4 | types: [published] 5 | 6 | jobs: 7 | github-releases-to-discord: 8 | name: GitHub Releases To Discord 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | - name: Github Releases To Discord 14 | uses: SethCohen/github-releases-to-discord@v1.13.1 15 | with: 16 | webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }} 17 | color: "2105893" 18 | username: "Release Changelog" 19 | avatar_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png" 20 | content: "New release: ${{ github.event.release.tag_name }}" 21 | footer_title: "Changelog" 22 | footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png" 23 | footer_timestamp: true 24 | -------------------------------------------------------------------------------- /src/Core/src/Retrievers/WebSearchRetriever.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Callback; 2 | using LangChain.DocumentLoaders; 3 | using LangChain.Utilities; 4 | 5 | namespace LangChain.Retrievers; 6 | 7 | /// 8 | public sealed class WebSearchRetriever( 9 | IWebSearch webSearch, 10 | int k = 10) 11 | : BaseRetriever 12 | { 13 | /// 14 | protected override async Task> GetRelevantDocumentsCoreAsync( 15 | string query, 16 | CallbackManagerForRetrieverRun? runManager = null, 17 | CancellationToken cancellationToken = default) 18 | { 19 | var searchResult = await webSearch.ResultsAsync(query, k, cancellationToken).ConfigureAwait(false); 20 | 21 | return searchResult.Select(v => new Document( 22 | v.Body, 23 | new Dictionary 24 | { 25 | ["title"] = v.Title, 26 | ["link"] = v.Link 27 | })); 28 | } 29 | } -------------------------------------------------------------------------------- /LangChain.sln.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True -------------------------------------------------------------------------------- /src/Utilities/Postgres/src/LangChain.Utilities.Postgres.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0;net9.0 5 | $(NoWarn);CA1031;CA2100;CA1305 6 | 7 | 8 | 9 | LangChain Utilities PostgresDatabase. 10 | $(PackageTags);sqldatabase;postgres 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:36862", 8 | "sslPort": 44397 9 | } 10 | }, 11 | "profiles": { 12 | "LangChain.Samples.AspNet": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "https://localhost:7289;http://localhost:5289", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "IIS Express": { 23 | "commandName": "IISExpress", 24 | "launchBrowser": true, 25 | "launchUrl": "swagger", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve.OpenAI/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers.OpenAI; 2 | using LangChain.Providers.OpenAI.Predefined; 3 | using LangChain.Serve.OpenAI; 4 | 5 | var builder = WebApplication.CreateBuilder(); 6 | 7 | // 1. Add LangChainServe 8 | builder.Services.AddLangChainServeOpenAi(); 9 | 10 | // 2. Create a model 11 | var provider = new OpenAiProvider(Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? ""); 12 | var model = new OpenAiLatestSmartChatModel(provider); 13 | 14 | // 4. Optional. Add swagger to be able to test the API 15 | builder.Services.AddEndpointsApiExplorer(); 16 | builder.Services.AddSwaggerGen(); 17 | 18 | var app = builder.Build(); 19 | 20 | // 5. Configure LangChainServe 21 | app.UseLangChainServeOpenAi(options => 22 | { 23 | options.RegisterModel(model); 24 | }); 25 | 26 | // 6. Optional. Add swagger middleware 27 | app.UseSwagger(); 28 | app.UseSwaggerUI(c => 29 | { 30 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "My OpenAI API V1"); 31 | }); 32 | app.Run(); -------------------------------------------------------------------------------- /src/DocumentLoaders/Word/src/ExcelLoader.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | /// 4 | /// 5 | /// 6 | public sealed class ExcelLoader(bool firstRowIsHeader = true) : IDocumentLoader 7 | { 8 | /// 9 | public async Task> LoadAsync( 10 | DataSource dataSource, 11 | DocumentLoaderSettings? settings = null, 12 | CancellationToken cancellationToken = default) 13 | { 14 | dataSource = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); 15 | 16 | using var stream = await dataSource.GetStreamAsync(cancellationToken).ConfigureAwait(false); 17 | 18 | var markdowns = ExcelToMarkdown.Convert(stream, firstRowIsHeader); 19 | 20 | var metadata = settings.CollectMetadataIfRequired(dataSource); 21 | 22 | return markdowns 23 | .Select(x => new Document(x.Value, metadata: metadata?.With("Worksheet", x.Key))) 24 | .ToArray(); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/DocumentLoaderTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.DocumentLoaders; 2 | 3 | namespace LangChain.Core.UnitTests; 4 | 5 | [TestFixture] 6 | public class DocumentLoaderTests 7 | { 8 | [Test] 9 | public async Task TextLoaderTest() 10 | { 11 | var filepath = Path.Combine(@"Resources", "state_of_the_union.txt"); 12 | var loader = new FileLoader(); 13 | var documents = await loader.LoadAsync(DataSource.FromPath(filepath)); 14 | 15 | documents.Count.Should().Be(1); 16 | documents.First().PageContent.Should().NotBeNullOrEmpty(); 17 | documents.First().Metadata.Should().NotBeNull(); 18 | // documents.First().Metadata.Should().ContainKey("source"); 19 | // documents.First().Metadata["source"].Should().Be(filepath); 20 | documents.First().Paragraphs().Should().NotBeEmpty(); 21 | documents.First().Paragraphs().First().Should().NotBeNullOrWhiteSpace(); 22 | documents.First().Paragraphs().Should().HaveCount(359); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Splitters/Abstractions/src/Text/CharacterTextSplitter.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Splitters.Text; 2 | 3 | /// 4 | /// Implementation of splitting text that looks at characters 5 | /// 6 | public class CharacterTextSplitter( 7 | string? separator = "\n\n", 8 | int chunkSize = 4000, 9 | int chunkOverlap = 200, 10 | Func? lengthFunction = null) 11 | : TextSplitter(chunkSize, chunkOverlap, lengthFunction) 12 | { 13 | /// 14 | public override IReadOnlyList SplitText(string text) 15 | { 16 | text = text ?? throw new ArgumentNullException(nameof(text)); 17 | 18 | List splits; 19 | if (separator != null) 20 | { 21 | splits = text.Split(new[] { separator }, StringSplitOptions.None).ToList(); 22 | } 23 | else 24 | { 25 | splits = new List { text }; 26 | } 27 | 28 | return this.MergeSplits(splits, separator ?? string.Empty); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Core/src/Retrievers/VectorStoreRetrieverExtensions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Retrievers; 3 | 4 | namespace LangChain.Databases; 5 | 6 | /// 7 | /// 8 | /// 9 | public static class VectorStoreRetrieverExtensions 10 | { 11 | /// 12 | /// Return vector collection as retriever 13 | /// 14 | /// vector store 15 | /// 16 | /// search type 17 | /// score threshold 18 | /// 19 | public static VectorStoreRetriever AsRetriever( 20 | this IVectorCollection vectorCollection, 21 | IEmbeddingModel embeddingModel, 22 | VectorSearchType searchType = VectorSearchType.Similarity, 23 | float? scoreThreshold = null) 24 | { 25 | return new VectorStoreRetriever(vectorCollection, embeddingModel, searchType, scoreThreshold); 26 | } 27 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/Controllers/AnthropicSampleController.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Providers.Anthropic; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace LangChain.Samples.AspNet.Controllers; 6 | 7 | [ApiController] 8 | [Route("[controller]")] 9 | public class AnthropicSampleController : ControllerBase 10 | { 11 | private readonly AnthropicChatModel _anthropicModel; 12 | private readonly ILogger _logger; 13 | 14 | public AnthropicSampleController( 15 | AnthropicChatModel anthropicModel, 16 | ILogger logger) 17 | { 18 | _anthropicModel = anthropicModel; 19 | _logger = logger; 20 | } 21 | 22 | [HttpGet(Name = "GetAnthropicResponse")] 23 | public async Task Get() 24 | { 25 | var response = await _anthropicModel.GenerateAsync("What is a good name for a company that sells colourful socks?"); 26 | 27 | return response.LastMessageContent; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/AIMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public class AiMessagePromptTemplate : BaseMessageStringPromptTemplate 9 | { 10 | /// 11 | public AiMessagePromptTemplate(BaseStringPromptTemplate prompt) : base(prompt) { } 12 | 13 | /// 14 | public override async Task FormatAsync( 15 | InputValues values, 16 | CancellationToken cancellationToken = default) 17 | { 18 | return (await Prompt.FormatAsync(values, cancellationToken).ConfigureAwait(false)).AsAiMessage(); 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | public static AiMessagePromptTemplate FromTemplate(string template) 27 | { 28 | return new AiMessagePromptTemplate(PromptTemplate.FromTemplate(template)); 29 | } 30 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Pdf/src/AsposePdfSource.cs: -------------------------------------------------------------------------------- 1 | using Aspose.Pdf.Text; 2 | 3 | namespace LangChain.DocumentLoaders; 4 | 5 | /// 6 | /// 7 | /// 8 | public sealed class AsposePdfLoader : IDocumentLoader 9 | { 10 | /// 11 | public async Task> LoadAsync( 12 | DataSource dataSource, 13 | DocumentLoaderSettings? settings = null, 14 | CancellationToken cancellationToken = default) 15 | { 16 | dataSource = dataSource ?? throw new ArgumentNullException(paramName: nameof(dataSource)); 17 | 18 | using var stream = await dataSource.GetStreamAsync(cancellationToken).ConfigureAwait(false); 19 | using var pdfDocument = new Aspose.Pdf.Document(stream); 20 | var textAbsorber = new TextAbsorber(); 21 | pdfDocument.Pages.Accept(textAbsorber); 22 | 23 | var metadata = settings.CollectMetadataIfRequired(dataSource); 24 | 25 | return [new Document(textAbsorber.Text, metadata: metadata)]; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Cli/test/LangChain.Cli.IntegrationTests/TestExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using System.CommandLine.IO; 3 | 4 | namespace LangChain.Cli.IntegrationTests; 5 | 6 | public static class TestExtensions 7 | { 8 | public static async Task ShouldWork(this string arguments) where T : Command, new() 9 | { 10 | // Arrange 11 | var console = new TestConsole(); 12 | var rootCommand = new RootCommand 13 | { 14 | new T(), 15 | }; 16 | 17 | //var test = rootCommand.Parse(arguments); 18 | //test.Errors.Should().BeEmpty(); 19 | 20 | // Act 21 | var result = await rootCommand.InvokeAsync(arguments, console); 22 | 23 | Console.WriteLine(console.Error.ToString()); 24 | Console.WriteLine(console.Out.ToString()); 25 | 26 | // Assert 27 | result.Should().Be(0); 28 | console.Error.ToString()?.Trim().Should().Be(string.Empty); 29 | console.Out.ToString()?.Trim().Should().NotBeNullOrEmpty(); 30 | } 31 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve/LangChain.Samples.Serve.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Tools/AgentTool.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.StackableChains.Agents.Tools; 2 | 3 | /// 4 | /// 5 | /// 6 | public abstract class AgentTool 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | protected AgentTool( 14 | string name, 15 | string? description = null) 16 | { 17 | Name = name; 18 | Description = description ?? string.Empty; 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | public string Name { get; set; } 25 | 26 | /// 27 | /// 28 | /// 29 | public string Description { get; set; } 30 | 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | public abstract Task ToolTask(string input, CancellationToken token = default); 38 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/HumanMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public class HumanMessagePromptTemplate : BaseMessageStringPromptTemplate 9 | { 10 | /// 11 | public HumanMessagePromptTemplate(BaseStringPromptTemplate prompt) : base(prompt) { } 12 | 13 | /// 14 | public override async Task FormatAsync( 15 | InputValues values, 16 | CancellationToken cancellationToken = default) 17 | { 18 | return (await Prompt.FormatAsync(values, cancellationToken).ConfigureAwait(false)).AsHumanMessage(); 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | public static HumanMessagePromptTemplate FromTemplate(string template) 27 | { 28 | return new HumanMessagePromptTemplate(PromptTemplate.FromTemplate(template)); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/RetrievalQA/RetrievalQaChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Callback; 2 | using LangChain.DocumentLoaders; 3 | using LangChain.Retrievers; 4 | 5 | namespace LangChain.Chains.RetrievalQA; 6 | 7 | /// 8 | /// Chain for question-answering against an index. 9 | /// 10 | /// 11 | public class RetrievalQaChain(RetrievalQaChainInput fields) : BaseRetrievalQaChain(fields) 12 | { 13 | private readonly BaseRetriever _retriever = fields.Retriever; 14 | 15 | /// 16 | public override string ChainType() => "retrieval_qa"; 17 | 18 | /// 19 | public override async Task> GetDocsAsync(string question, CallbackManagerForChainRun runManager) 20 | { 21 | runManager = runManager ?? throw new ArgumentNullException(nameof(runManager)); 22 | 23 | return await _retriever.GetRelevantDocumentsAsync( 24 | question, 25 | callbacks: new ManagerCallbacks(runManager.GetChild())).ConfigureAwait(false); 26 | } 27 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/SystemMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public class SystemMessagePromptTemplate : BaseMessageStringPromptTemplate 9 | { 10 | /// 11 | public SystemMessagePromptTemplate(BaseStringPromptTemplate prompt) : base(prompt) { } 12 | 13 | /// 14 | public override async Task FormatAsync( 15 | InputValues values, 16 | CancellationToken cancellationToken = default) 17 | { 18 | return (await Prompt.FormatAsync(values, cancellationToken).ConfigureAwait(false)).AsSystemMessage(); 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | public static SystemMessagePromptTemplate FromTemplate(string template) 27 | { 28 | return new SystemMessagePromptTemplate(PromptTemplate.FromTemplate(template)); 29 | } 30 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.AspNet/Controllers/OpenAiSampleController.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Providers.OpenAI; 3 | using Microsoft.AspNetCore.Mvc; 4 | using tryAGI.OpenAI; 5 | 6 | namespace LangChain.Samples.AspNet.Controllers; 7 | 8 | [ApiController] 9 | [Route("[controller]")] 10 | public class OpenAiSampleController : ControllerBase 11 | { 12 | private readonly OpenAiProvider _openAi; 13 | private readonly ILogger _logger; 14 | 15 | public OpenAiSampleController( 16 | OpenAiProvider openAi, 17 | ILogger logger) 18 | { 19 | _openAi = openAi; 20 | _logger = logger; 21 | } 22 | 23 | [HttpGet(Name = "GetOpenAiResponse")] 24 | public async Task Get() 25 | { 26 | var llm = new OpenAiChatModel(_openAi, id: ChatClient.LatestFastModel); 27 | var response = await llm.GenerateAsync("What is a good name for a company that sells colourful socks?"); 28 | 29 | return response.LastMessageContent; 30 | } 31 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Serve.OpenAI/LangChain.Samples.Serve.OpenAI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Crew/Tools/CrewAgentTool.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.StackableChains.Agents.Crew.Tools; 2 | 3 | /// 4 | /// 5 | /// 6 | public abstract class CrewAgentTool 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | protected CrewAgentTool( 14 | string name, 15 | string? description = null) 16 | { 17 | Name = name; 18 | Description = description ?? string.Empty; 19 | } 20 | 21 | /// 22 | /// 23 | /// 24 | public string Name { get; set; } 25 | 26 | /// 27 | /// 28 | /// 29 | public string Description { get; set; } 30 | 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | public abstract Task ToolTask(string input, CancellationToken token = default); 38 | } -------------------------------------------------------------------------------- /src/Core/src/Callback/ICallbacks.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | 3 | namespace LangChain.Callback; 4 | 5 | /// 6 | /// 7 | /// 8 | public interface ICallbacks; 9 | 10 | /// 11 | /// 12 | /// 13 | public static class ManagerCallbacksExtensions 14 | { 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | public static ManagerCallbacks ToCallbacks(this ParentRunManager source) 22 | { 23 | source = source ?? throw new ArgumentNullException(nameof(source)); 24 | 25 | return new ManagerCallbacks(source.GetChild()); 26 | } 27 | } 28 | 29 | /// 30 | /// 31 | /// 32 | /// 33 | public record ManagerCallbacks(CallbackManager Value) : ICallbacks; 34 | 35 | /// 36 | /// 37 | /// 38 | /// 39 | public record HandlersCallbacks(List Value) : ICallbacks; -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/DoChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | 4 | namespace LangChain.Chains.StackableChains; 5 | 6 | /// 7 | /// 8 | /// 9 | public class DoChain : BaseStackableChain 10 | { 11 | private readonly Action> _func; 12 | 13 | /// 14 | /// 15 | /// 16 | /// 17 | public DoChain(Action> func) 18 | { 19 | _func = func; 20 | } 21 | 22 | /// 23 | /// 24 | /// 25 | /// 26 | /// 27 | /// 28 | protected override Task InternalCallAsync( 29 | IChainValues values, 30 | CancellationToken cancellationToken = default) 31 | { 32 | values = values ?? throw new ArgumentNullException(nameof(values)); 33 | 34 | _func(values.Value); 35 | 36 | return Task.FromResult(values); 37 | } 38 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Pdf/src/LangChain.DocumentLoaders.Pdf.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA2016 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | LangChain PDF document loader. 15 | $(PackageTags);pdf 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/Core/src/Chains/CombineDocuments/ReduceDocumentsChainInput.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Chains.CombineDocuments; 2 | 3 | /// 4 | public class ReduceDocumentsChainInput : BaseCombineDocumentsChainInput 5 | { 6 | /// 7 | /// Final chain to call to combine documents. 8 | /// This is typically a StuffDocumentsChain. 9 | /// 10 | public required BaseCombineDocumentsChain CombineDocumentsChain { get; set; } 11 | 12 | /// 13 | /// Chain to use to collapse documents if needed until they can all fit. 14 | /// If null, will use the combine_documents_chain. 15 | /// This is typically a StuffDocumentsChain. 16 | /// 17 | public required BaseCombineDocumentsChain CollapseDocumentsChain { get; set; } 18 | 19 | /// 20 | /// The maximum number of tokens to group documents into. For example, if 21 | /// set to 3000 then documents will be grouped into chunks of no greater than 22 | /// 3000 tokens before trying to combine them into a smaller chunk. 23 | /// 24 | public int TokenMax { get; set; } = 3_000; 25 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Crew/Crew.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.StackableChains.Agents.Crew.Tools; 2 | 3 | namespace LangChain.Chains.StackableChains.Agents.Crew; 4 | 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | public class Crew( 11 | IEnumerable agents, 12 | IEnumerable tasks) 13 | { 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | public async Task RunAsync(CancellationToken cancellationToken = default) 20 | { 21 | string? context = null; 22 | 23 | foreach (var task in tasks) 24 | { 25 | task.Tools.Add(new AskQuestionTool(agents.Except(new[] { task.Agent }))); 26 | task.Tools.Add(new DelegateWorkTool(agents.Except(new[] { task.Agent }))); 27 | var res = await task.ExecuteAsync(context, cancellationToken).ConfigureAwait(false); 28 | context = res; 29 | } 30 | 31 | return context ?? string.Empty; 32 | } 33 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/PromptTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts; 2 | using LangChain.Schema; 3 | 4 | namespace LangChain.UnitTest; 5 | 6 | [TestFixture] 7 | public class PromptTests 8 | { 9 | [Test] 10 | public async Task TestPartials_WhenUsingPartial_ShouldFormat() 11 | { 12 | var message = new PromptTemplate(new PromptTemplateInput("{foo}{bar}", new List(2) { "foo" }, 13 | new Dictionary(1) { { "bar", "baz" } })); 14 | 15 | var formatted = await message.FormatAsync(new InputValues(new Dictionary(1) { { "foo", "foo" } })); 16 | 17 | formatted.Should().Be("foobaz"); 18 | } 19 | 20 | [Test] 21 | public async Task TestPartials_WhenUsingFullPartial_ShouldFormat() 22 | { 23 | var message = new PromptTemplate(new PromptTemplateInput("{foo}{bar}", new List(), 24 | new Dictionary(1) { { "bar", "baz" }, { "foo", "foo" } })); 25 | 26 | var formatted = await message.FormatAsync(new InputValues(new Dictionary(0))); 27 | 28 | formatted.Should().Be("foobaz"); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Core/src/Utilities/IWebSearch.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Utilities; 2 | 3 | /// 4 | /// 5 | /// 6 | public interface IWebSearch 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | Task RunAsync( 15 | string query, 16 | CancellationToken cancellationToken = default); 17 | 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | Task> ResultsAsync( 26 | string query, 27 | int numResults, 28 | CancellationToken cancellationToken = default); 29 | } 30 | 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | public readonly record struct WebSearchResult( 38 | string Title, 39 | string Body, 40 | string Link); -------------------------------------------------------------------------------- /src/DocumentLoaders/Pdf/src/PdfPigPdfSource.cs: -------------------------------------------------------------------------------- 1 | using UglyToad.PdfPig; 2 | 3 | namespace LangChain.DocumentLoaders; 4 | 5 | /// 6 | /// 7 | /// 8 | public sealed class PdfPigPdfLoader : IDocumentLoader 9 | { 10 | /// 11 | public async Task> LoadAsync( 12 | DataSource dataSource, 13 | DocumentLoaderSettings? settings = null, 14 | CancellationToken cancellationToken = default) 15 | { 16 | dataSource = dataSource ?? throw new ArgumentNullException(paramName: nameof(dataSource)); 17 | 18 | using var stream = await dataSource.GetStreamAsync(cancellationToken).ConfigureAwait(false); 19 | using var document = PdfDocument.Open(stream, new ParsingOptions()); 20 | 21 | var metadata = settings.CollectMetadataIfRequired(dataSource); 22 | 23 | return document 24 | .GetPages() 25 | .Select(page => new Document(page.Text, metadata?.With(new Dictionary 26 | { 27 | { "page", page.Number }, 28 | }))) 29 | .ToArray(); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Splitters/Abstractions/test/Tests.RecursiveCharacter.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Extensions; 2 | using LangChain.Splitters.Text; 3 | 4 | namespace LangChain.Splitters; 5 | 6 | public partial class Tests 7 | { 8 | [Test] 9 | public void RecursiveCharacterTextSplitterTest() 10 | { 11 | // based on https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/recursive_text_splitter 12 | 13 | var text = H.Resources.state_of_the_union_txt.AsString(); 14 | var textSplitter = new RecursiveCharacterTextSplitter(chunkSize: 100, chunkOverlap: 20); 15 | 16 | 17 | var texts = textSplitter.CreateDocuments(new List() { text }); 18 | 19 | 20 | var expected1 = 21 | "Madam Speaker, Madam Vice President, our First Lady and Second Gentleman. Members of Congress and"; 22 | var actual1 = texts[0].PageContent; 23 | actual1.Should().Be(expected1); 24 | 25 | var expected2 = "of Congress and the Cabinet. Justices of the Supreme Court. My fellow Americans."; 26 | var actual2 = texts[1].PageContent; 27 | actual2.Should().Be(expected2); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/ConversationalRetrieval/ChatTurnTypeHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using LangChain.Providers; 3 | 4 | namespace LangChain.Chains.ConversationalRetrieval; 5 | 6 | /// 7 | /// 8 | /// 9 | public static class ChatTurnTypeHelper 10 | { 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static string GetChatHistory(IReadOnlyList chatHistory) 18 | { 19 | chatHistory = chatHistory ?? throw new ArgumentNullException(nameof(chatHistory)); 20 | 21 | var buffer = new StringBuilder(); 22 | 23 | foreach (var message in chatHistory) 24 | { 25 | var rolePrefix = message.Role switch 26 | { 27 | MessageRole.Human => "Human: ", 28 | MessageRole.Ai => "Assistant: ", 29 | _ => $"{message.Role}: " 30 | }; 31 | 32 | buffer.AppendLine($"{rolePrefix}{message.Content}"); 33 | } 34 | 35 | return buffer.ToString(); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/ChatMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public class ChatMessagePromptTemplate( 9 | BaseStringPromptTemplate prompt, 10 | string role) 11 | : BaseMessageStringPromptTemplate(prompt) 12 | { 13 | /// 14 | /// 15 | /// 16 | public string Role { get; set; } = role; 17 | 18 | /// 19 | public override async Task FormatAsync( 20 | InputValues values, 21 | CancellationToken cancellationToken = default) 22 | { 23 | return (await Prompt.FormatAsync(values, cancellationToken).ConfigureAwait(false)).AsChatMessage(); 24 | } 25 | 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public static ChatMessagePromptTemplate FromTemplate(string template, string role) 33 | { 34 | return new ChatMessagePromptTemplate(PromptTemplate.FromTemplate(template), role); 35 | } 36 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/ConversationalRetrieval/ConversationalRetrievalChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.CombineDocuments; 2 | using LangChain.Chains.LLM; 3 | using LangChain.Retrievers; 4 | 5 | namespace LangChain.Chains.ConversationalRetrieval; 6 | 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | public class ConversationalRetrievalChainInput( 14 | BaseRetriever retriever, 15 | BaseCombineDocumentsChain combineDocsChain, 16 | ILlmChain questionGenerator) 17 | : BaseConversationalRetrievalChainInput(combineDocsChain, questionGenerator) 18 | { 19 | /// 20 | /// Retriever to use to fetch documents. 21 | /// 22 | public BaseRetriever Retriever { get; } = retriever; 23 | 24 | /// 25 | /// If set, enforces that the documents returned are less than this limit. 26 | /// This is only enforced if is of type . 27 | /// 28 | public int? MaxTokensLimit { get; set; } 29 | } -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | preview 5 | enable 6 | enable 7 | true 8 | 9 | 10 | 11 | true 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | true 21 | true 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Core/src/Chains/LLM/LLMChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | using LangChain.Memory; 3 | using LangChain.Prompts.Base; 4 | using LangChain.Providers; 5 | 6 | namespace LangChain.Chains.LLM; 7 | 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | public class LlmChainInput( 15 | IChatModel llm, 16 | BasePromptTemplate prompt, 17 | BaseMemory? memory = null) 18 | : ChainInputs, ILlmChainInput 19 | { 20 | /// 21 | public BasePromptTemplate Prompt { get; set; } = prompt; 22 | 23 | /// 24 | public IChatModel Llm { get; set; } = llm; 25 | 26 | /// 27 | public string OutputKey { get; set; } = "text"; 28 | 29 | /// 30 | /// 31 | /// 32 | public BaseMemory? Memory { get; set; } = memory; 33 | 34 | /// 35 | /// Whether to return only the final parsed result. Defaults to True. 36 | /// If false, will return a bunch of extra information about the generation. 37 | /// 38 | public bool ReturnFinalOnly { get; set; } = true; 39 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/CombineDocuments/MapReduceDocumentsChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.LLM; 2 | 3 | namespace LangChain.Chains.CombineDocuments; 4 | 5 | /// 6 | public class MapReduceDocumentsChainInput : BaseCombineDocumentsChainInput 7 | { 8 | /// 9 | /// Chain to apply to each document individually. 10 | /// 11 | public required ILlmChain LlmChain { get; set; } 12 | 13 | /// 14 | /// Chain to use to reduce the results of applying `llm_chain` to each doc. 15 | /// This typically either a ReduceDocumentChain or StuffDocumentChain. 16 | /// 17 | public required BaseCombineDocumentsChain ReduceDocumentsChain { get; set; } 18 | 19 | /// 20 | /// The variable name in the llm_chain to put the documents in. 21 | /// If only one variable in the llm_chain, this need not be provided. 22 | /// 23 | /// 24 | public string DocumentVariableName { get; set; } = string.Empty; 25 | 26 | /// 27 | /// Return the results of the map steps in the output. 28 | /// 29 | public bool ReturnIntermediateSteps { get; set; } 30 | } -------------------------------------------------------------------------------- /src/Testing.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/LangChain.Samples.HuggingFace/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Providers.HuggingFace; 3 | using LangChain.Providers.HuggingFace.Predefined; 4 | 5 | using var client = new HttpClient(); 6 | var provider = new HuggingFaceProvider(apiKey: string.Empty, client); 7 | var gpt2Model = new Gpt2Model(provider); 8 | 9 | var gp2ModelResponse = await gpt2Model.GenerateAsync("What would be a good company name be for name a company that makes colorful socks?"); 10 | 11 | Console.WriteLine("### GP2 Response"); 12 | Console.WriteLine(gp2ModelResponse); 13 | 14 | const string imageToTextModel = "Salesforce/blip-image-captioning-base"; 15 | var model = new HuggingFaceImageToTextModel(provider, imageToTextModel); 16 | 17 | var path = Path.Combine(Path.GetTempPath(), "solar_system.png"); 18 | var imageData = await File.ReadAllBytesAsync(path); 19 | var binaryData = new BinaryData(imageData, "image/jpg"); 20 | 21 | var imageToTextResponse = await model.GenerateTextFromImageAsync(new ImageToTextRequest 22 | { 23 | Image = binaryData 24 | }); 25 | 26 | Console.WriteLine("\n\n### ImageToText Response"); 27 | Console.WriteLine(imageToTextResponse.Text); 28 | 29 | Console.ReadLine(); 30 | -------------------------------------------------------------------------------- /src/Extensions/DependencyInjection/src/LangChain.Extensions.DependencyInjection.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | false 6 | 7 | 8 | 9 | Extensions using Microsoft.Extensions. 10 | $(PackageTags);di 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/PromptedAgent.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.HelperChains; 2 | using LangChain.Providers; 3 | 4 | namespace LangChain.Chains.StackableChains.Agents; 5 | 6 | /// 7 | /// 8 | /// 9 | public class PromptedAgent : AgentExecutorChain 10 | { 11 | /// 12 | /// 13 | /// 14 | public const string Template = 15 | @"{system} 16 | {history}"; 17 | 18 | private static BaseStackableChain MakeChain(string name, string system, IChatModel model, string outputKey) 19 | { 20 | return Chain.Set(system, "system") 21 | | Chain.Template(Template) 22 | | Chain.LLM(model, outputKey: outputKey); 23 | } 24 | 25 | /// 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | /// 32 | public PromptedAgent( 33 | string name, 34 | string prompt, 35 | IChatModel model, 36 | string outputKey = "final_answer") 37 | : base(MakeChain(name, prompt, model, outputKey), name, "history", outputKey) 38 | { 39 | 40 | } 41 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/LangChain.DocumentLoaders.Abstractions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | $(NoWarn);CA1031;CA1054 6 | 7 | 8 | 9 | LangChain documents loader abstractions. 10 | $(PackageTags);abstractions 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Core/src/Prompts/BaseMessageStringPromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public abstract class BaseMessageStringPromptTemplate( 9 | BaseStringPromptTemplate prompt) 10 | : BaseMessagePromptTemplate 11 | { 12 | /// 13 | /// 14 | /// 15 | public BaseStringPromptTemplate Prompt { get; set; } = prompt; 16 | 17 | /// 18 | public override IReadOnlyList InputVariables => this.Prompt.InputVariables; 19 | 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// 26 | public abstract Task FormatAsync( 27 | InputValues values, 28 | CancellationToken cancellationToken = default); 29 | 30 | /// 31 | public override async Task> FormatMessagesAsync( 32 | InputValues values, 33 | CancellationToken cancellationToken = default) 34 | { 35 | return [await FormatAsync(values, cancellationToken).ConfigureAwait(false)]; 36 | } 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-2024 tryAGI, HavenDV, TesAnti, Khoroshev Evgeniy, SiegDuch, James Eastha, Uros Biberdzicand, @CrazyBaran, scule and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/Helpers/TrimmingHelper/TrimmingHelper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | win-x64 23 | osx-arm64 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Cli/src/CommonOptions.cs: -------------------------------------------------------------------------------- 1 | using System.CommandLine; 2 | using LangChain.Cli.Models; 3 | 4 | namespace LangChain.Cli; 5 | 6 | internal static class CommonOptions 7 | { 8 | public static Option Input => new( 9 | aliases: ["--input", "-i"], 10 | getDefaultValue: () => string.Empty, 11 | description: "Input text"); 12 | 13 | public static Option InputFile => new( 14 | aliases: ["--input-file"], 15 | getDefaultValue: () => null, 16 | description: "Input file path"); 17 | 18 | public static Option OutputFile => new( 19 | aliases: ["--output-file"], 20 | getDefaultValue: () => null, 21 | description: "Output file path"); 22 | 23 | public static Option Debug => new( 24 | aliases: ["--debug"], 25 | getDefaultValue: () => false, 26 | description: "Show Debug Information"); 27 | 28 | public static Option Model => new( 29 | aliases: ["--model"], 30 | getDefaultValue: () => "o3-mini", 31 | description: "Model to use for commands."); 32 | 33 | public static Option Provider => new( 34 | aliases: ["--provider"], 35 | getDefaultValue: () => default, 36 | description: $"Provider to use for commands."); 37 | } -------------------------------------------------------------------------------- /src/Meta/src/LangChain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net4.6.2;netstandard2.0;net8.0;net9.0 5 | 6 | 7 | 8 | LangChain meta-package with the most used things. 9 | langchain;meta;llms 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/UpdateMemoryChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | using LangChain.Memory; 4 | using LangChain.Schema; 5 | 6 | namespace LangChain.Chains.StackableChains; 7 | 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | public class UpdateMemoryChain( 15 | BaseChatMemory memory, 16 | string requestKey = "query", 17 | string responseKey = "text") 18 | : BaseStackableChain 19 | { 20 | /// 21 | protected override async Task InternalCallAsync( 22 | IChainValues values, 23 | CancellationToken cancellationToken = default) 24 | { 25 | values = values ?? throw new ArgumentNullException(nameof(values)); 26 | 27 | await memory.SaveContext(new InputValues( 28 | new Dictionary 29 | { 30 | [requestKey] = values.Value[requestKey], 31 | }), 32 | new OutputValues(new Dictionary 33 | { 34 | [responseKey] = values.Value[responseKey], 35 | })).ConfigureAwait(false); 36 | 37 | return values; 38 | } 39 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/Utilities/DuckDuckGoSearchTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Retrievers; 2 | using LangChain.Utilities; 3 | 4 | namespace LangChain.Core.UnitTests.Utilities; 5 | 6 | [TestFixture] 7 | [Explicit] 8 | public class DuckDuckGoSearchTests 9 | { 10 | [Test] 11 | public async Task Run_Ok() 12 | { 13 | var search = new DuckDuckGoSearchApiWrapper(); 14 | 15 | var result = await search.RunAsync("wikipedia"); 16 | 17 | result.Should().NotBeEmpty(); 18 | //result.Should().Contain("encyclopedia"); 19 | } 20 | 21 | [Test] 22 | public async Task GetSnippets_Ok() 23 | { 24 | var search = new DuckDuckGoSearchApiWrapper(); 25 | 26 | var result = await search.GetSnippetsAsync("wikipedia"); 27 | 28 | result.Should().NotBeEmpty(); 29 | //result.Should().Contain(v => v.Contains("encyclopedia")); 30 | } 31 | 32 | [Test] 33 | public async Task Retriever_Ok() 34 | { 35 | var search = new DuckDuckGoSearchApiWrapper(); 36 | var retriever = new WebSearchRetriever(search); 37 | 38 | var result = await retriever.GetRelevantDocumentsAsync("wikipedia"); 39 | 40 | result.Should().NotBeEmpty(); 41 | //result.Should().Contain(d => d.PageContent.Contains("encyclopedia")); 42 | } 43 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/CombineDocuments/StuffDocumentsChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.LLM; 2 | using LangChain.Prompts; 3 | using LangChain.Prompts.Base; 4 | 5 | namespace LangChain.Chains.CombineDocuments; 6 | 7 | /// 8 | public class StuffDocumentsChainInput(ILlmChain llmChain) : BaseCombineDocumentsChainInput 9 | { 10 | /// 11 | /// LLM chain which is called with the formatted document string, along with any other inputs. 12 | /// 13 | public ILlmChain LlmChain { get; } = llmChain; 14 | 15 | /// 16 | /// Template to use to format each document, gets passed to `format_document`. 17 | /// 18 | public BasePromptTemplate DocumentPrompt { get; set; } = new PromptTemplate( 19 | new PromptTemplateInput( 20 | "{page_content}", 21 | new List(1) { "page_content" })); 22 | 23 | /// 24 | /// The variable name in the LlmChain to put the documents in. 25 | /// If only one variable in the llm_chain, this need not be provided. 26 | /// 27 | public string? DocumentVariableName { get; set; } 28 | 29 | /// 30 | /// The string with which to join the formatted documents 31 | /// 32 | public string DocumentSeparator { get; set; } = "\n\n"; 33 | } -------------------------------------------------------------------------------- /src/Core/test/UnitTests/MemoryTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Memory; 2 | using LangChain.Providers; 3 | 4 | namespace LangChain.UnitTest; 5 | 6 | [TestFixture] 7 | public class MemoryTests 8 | { 9 | [Test] 10 | public void TestInMemoryHistory_WhenAddingMessages_ShouldStoreInMememory() 11 | { 12 | ChatMessageHistory inMemoryHistory = CreateInMemoryHistoryExample(); 13 | 14 | inMemoryHistory.Messages.Should().HaveCount(2); 15 | 16 | inMemoryHistory.Messages.FirstOrDefault(x => x.Content == "hi!").Role.Should().Be(MessageRole.Human); 17 | inMemoryHistory.Messages.FirstOrDefault(x => x.Content == "whats up?").Role.Should().Be(MessageRole.Ai); 18 | } 19 | 20 | [Test] 21 | public void TestInMemoryHistory_WhenCleanMethodIsCalled_ShouldCleanHistory() 22 | { 23 | ChatMessageHistory inMemoryHistory = CreateInMemoryHistoryExample(); 24 | 25 | inMemoryHistory.Clear(); 26 | 27 | inMemoryHistory.Messages.Should().HaveCount(0); 28 | } 29 | 30 | private static ChatMessageHistory CreateInMemoryHistoryExample() 31 | { 32 | var inMemoryHistory = new ChatMessageHistory(); 33 | 34 | inMemoryHistory.AddUserMessage("hi!"); 35 | 36 | inMemoryHistory.AddAiMessage("whats up?"); 37 | return inMemoryHistory; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/LoadMemoryChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | using LangChain.Memory; 4 | using LangChain.Schema; 5 | 6 | namespace LangChain.Chains.StackableChains; 7 | 8 | public class LoadMemoryChain : BaseStackableChain 9 | { 10 | private readonly BaseChatMemory _chatMemory; 11 | private readonly string _outputKey; 12 | 13 | public LoadMemoryChain(BaseChatMemory chatMemory, string outputKey) 14 | { 15 | _chatMemory = chatMemory; 16 | _outputKey = outputKey; 17 | 18 | OutputKeys = new[] { _outputKey }; 19 | } 20 | 21 | protected override Task InternalCallAsync( 22 | IChainValues values, 23 | CancellationToken cancellationToken = default) 24 | { 25 | values = values ?? throw new ArgumentNullException(nameof(values)); 26 | 27 | var memoryVariableName = _chatMemory.MemoryVariables.FirstOrDefault(); 28 | if (memoryVariableName == null) 29 | { 30 | throw new InvalidOperationException("Missing memory variable name"); 31 | } 32 | 33 | OutputValues outputValues = _chatMemory.LoadMemoryVariables(null); 34 | values.Value[_outputKey] = outputValues.Value[memoryVariableName]; 35 | return Task.FromResult(values); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Serve/OpenAI/ServeController.cs: -------------------------------------------------------------------------------- 1 | // using System.Text.Json.Serialization; 2 | // using tryAGI.OpenAI; 3 | // 4 | // namespace LangChain.Serve.OpenAI; 5 | // 6 | // public class ServeController( 7 | // ServeOptions options) 8 | // { 9 | // public ModelsList GetModel() 10 | // { 11 | // return new ModelsList 12 | // { 13 | // Models = options.ListModels().Select(static x => new Model12 14 | // { 15 | // Object = ModelObject.Model, 16 | // Created = DateTimeOffset.UtcNow, 17 | // Id = x, 18 | // OwnedBy = "OpenAI", 19 | // }).ToList() 20 | // }; 21 | // } 22 | // 23 | // public ModelsList ListModels() 24 | // { 25 | // return new ModelsList 26 | // { 27 | // Models = options.ListModels().Select(static x => new Model12 28 | // { 29 | // Object = ModelObject.Model, 30 | // Created = DateTimeOffset.UtcNow, 31 | // Id = x, 32 | // OwnedBy = "OpenAI", 33 | // }).ToList() 34 | // }; 35 | // } 36 | // } 37 | // 38 | // public sealed class ModelsList 39 | // { 40 | // [JsonInclude] 41 | // [JsonPropertyName("data")] 42 | // public IReadOnlyCollection Models { get; set; } = []; 43 | // } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/StringExtensions.Replace.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | 4 | namespace System; 5 | 6 | public static partial class PolyfillStringExtensions 7 | { 8 | public static string Replace(this string text, string from, string to, StringComparison comparisonType) 9 | { 10 | text = text ?? throw new ArgumentNullException(nameof(text)); 11 | from = from ?? throw new ArgumentNullException(nameof(from)); 12 | to = to ?? throw new ArgumentNullException(nameof(to)); 13 | 14 | switch (comparisonType) 15 | { 16 | case StringComparison.CurrentCulture: 17 | case StringComparison.InvariantCulture: 18 | case StringComparison.Ordinal: 19 | return text.Replace(from, to); 20 | 21 | case StringComparison.InvariantCultureIgnoreCase: 22 | case StringComparison.OrdinalIgnoreCase: 23 | case StringComparison.CurrentCultureIgnoreCase: 24 | return text 25 | .Replace(from.ToLowerInvariant(), to) 26 | .Replace(from.ToUpperInvariant(), to) 27 | .Replace(from, to); 28 | default: 29 | throw new ArgumentOutOfRangeException(nameof(comparisonType), comparisonType, null); 30 | } 31 | } 32 | } 33 | #endif -------------------------------------------------------------------------------- /src/Extensions/DependencyInjection/src/ServiceCollectionExtensions.OpenAi.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using LangChain.Providers.OpenAI; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace LangChain.Extensions.DependencyInjection; 7 | 8 | /// 9 | /// 10 | /// 11 | public static partial class ServiceCollectionExtensions 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | [RequiresDynamicCode("Requires dynamic code.")] 20 | [RequiresUnreferencedCode("Requires unreferenced code.")] 21 | public static IServiceCollection AddOpenAi( 22 | this IServiceCollection services) 23 | { 24 | services = services ?? throw new ArgumentNullException(nameof(services)); 25 | 26 | _ = services 27 | .AddOptions() 28 | .BindConfiguration(configSectionPath: OpenAiConfiguration.SectionName); 29 | _ = services 30 | .AddHttpClient(); 31 | _ = services 32 | .AddScoped(static services => new OpenAiProvider( 33 | services.GetRequiredService>().Value)); 34 | 35 | return services; 36 | } 37 | } -------------------------------------------------------------------------------- /src/Core/src/Callback/CallbackManagerForToolRun.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | using LangChain.Schema; 3 | 4 | namespace LangChain.Callback; 5 | 6 | /// 7 | public class CallbackManagerForToolRun : ParentRunManager 8 | { 9 | /// 10 | public CallbackManagerForToolRun(string runId, List handlers, List inheritableHandlers, string? parentRunId = null) 11 | : base(runId, handlers, inheritableHandlers, parentRunId) 12 | { 13 | } 14 | 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | public Task HandleToolErrorAsync(Exception err, string runId, string? parentRunId = null) 24 | { 25 | throw new NotImplementedException(); 26 | } 27 | 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | public Task HandleToolEndAsync(string output, string runId, string? parentRunId = null) 37 | { 38 | throw new NotImplementedException(); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Core/src/Extensions/SourceExtensions.cs: -------------------------------------------------------------------------------- 1 | using LangChain.DocumentLoaders; 2 | using LangChain.Splitters.Text; 3 | 4 | namespace LangChain.Extensions; 5 | 6 | public static class SourceExtensions 7 | { 8 | /// 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static async Task> LoadAndSplit( 18 | this IDocumentLoader documentLoader, 19 | DataSource dataSource, 20 | ITextSplitter? textSplitter = null, 21 | DocumentLoaderSettings? loaderSettings = null, 22 | CancellationToken cancellationToken = default) 23 | { 24 | documentLoader = documentLoader ?? throw new ArgumentNullException(nameof(documentLoader)); 25 | dataSource = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); 26 | textSplitter ??= new RecursiveCharacterTextSplitter(); 27 | 28 | var documents = await documentLoader.LoadAsync( 29 | dataSource: dataSource, 30 | settings: loaderSettings, 31 | cancellationToken: cancellationToken).ConfigureAwait(false); 32 | 33 | return textSplitter.SplitDocuments(documents); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Serve/src/Classes/DTO/ConversationDTO.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Serve.Abstractions.Repository; 2 | 3 | namespace LangChain.Serve.Classes.DTO; 4 | 5 | public class ConversationDto 6 | { 7 | public Guid ConversationId { get; set; } 8 | public string ModelName { get; set; } = string.Empty; 9 | public string? ConversationName { get; set; } 10 | public DateTime CreatedAt { get; set; } 11 | 12 | public static ConversationDto FromStoredConversation(StoredConversation conversation) 13 | { 14 | conversation = conversation ?? throw new ArgumentNullException(nameof(conversation)); 15 | 16 | return new ConversationDto 17 | { 18 | ConversationId = conversation.ConversationId, 19 | ModelName = conversation.ModelName, 20 | ConversationName = conversation.ConversationName, 21 | CreatedAt = conversation.CreatedAt 22 | }; 23 | } 24 | 25 | public static StoredConversation ToStoredConversation(ConversationDto conversation) 26 | { 27 | conversation = conversation ?? throw new ArgumentNullException(nameof(conversation)); 28 | 29 | return new StoredConversation 30 | { 31 | ConversationId = conversation.ConversationId, 32 | ModelName = conversation.ModelName, 33 | ConversationName = conversation.ConversationName, 34 | CreatedAt = conversation.CreatedAt 35 | }; 36 | } 37 | } -------------------------------------------------------------------------------- /src/Core/src/Prompts/BaseChatPromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Prompts.Base; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | public abstract class BaseChatPromptTemplate : BasePromptTemplate 9 | { 10 | /// 11 | protected BaseChatPromptTemplate(IBasePromptTemplateInput input) : base(input) { } 12 | 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | public abstract Task> FormatMessagesAsync( 20 | InputValues values, 21 | CancellationToken cancellationToken = default); 22 | 23 | /// 24 | public override async Task FormatAsync( 25 | InputValues values, 26 | CancellationToken cancellationToken = default) 27 | { 28 | return (await FormatPromptValueAsync(values, cancellationToken).ConfigureAwait(false)).ToString(); 29 | } 30 | 31 | /// 32 | public override async Task FormatPromptValueAsync( 33 | InputValues values, 34 | CancellationToken cancellationToken = default) 35 | { 36 | var resultMessages = await FormatMessagesAsync(values, cancellationToken).ConfigureAwait(false); 37 | return new ChatPromptValue(resultMessages); 38 | } 39 | } -------------------------------------------------------------------------------- /src/Extensions/DependencyInjection/src/ServiceCollectionExtensions.Anyscale.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using LangChain.Providers.Anyscale; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace LangChain.Extensions.DependencyInjection; 7 | 8 | /// 9 | /// 10 | /// 11 | public static partial class ServiceCollectionExtensions 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | [RequiresDynamicCode("Requires dynamic code.")] 20 | [RequiresUnreferencedCode("Requires unreferenced code.")] 21 | public static IServiceCollection AddAnyscale( 22 | this IServiceCollection services) 23 | { 24 | services = services ?? throw new ArgumentNullException(nameof(services)); 25 | 26 | _ = services 27 | .AddOptions() 28 | .BindConfiguration(configSectionPath: AnyscaleConfiguration.SectionName); 29 | _ = services 30 | .AddHttpClient(); 31 | _ = services 32 | .AddScoped(static services => new AnyscaleProvider( 33 | configuration: services.GetRequiredService>().Value)); 34 | 35 | return services; 36 | } 37 | } -------------------------------------------------------------------------------- /src/Core/src/Memory/ConversationBufferMemory.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers; 2 | using LangChain.Schema; 3 | 4 | namespace LangChain.Memory; 5 | 6 | /// 7 | /// Buffer for storing conversation memory. 8 | /// 9 | /// NOTE: LangChain's buffer property is not implemented here 10 | /// 11 | public class ConversationBufferMemory : BaseChatMemory 12 | { 13 | public MessageFormatter Formatter { get; set; } = new MessageFormatter(); 14 | 15 | public string MemoryKey { get; set; } = "history"; 16 | 17 | /// 18 | public override List MemoryVariables => new List { MemoryKey }; 19 | 20 | /// 21 | /// Initializes new buffered memory instance 22 | /// 23 | public ConversationBufferMemory() 24 | : base() 25 | { 26 | } 27 | 28 | /// 29 | /// Initializes new buffered memory instance with provided history store 30 | /// 31 | /// History backing store 32 | public ConversationBufferMemory(BaseChatMessageHistory chatHistory) 33 | : base(chatHistory) 34 | { 35 | } 36 | 37 | /// 38 | public override OutputValues LoadMemoryVariables(InputValues? inputValues) 39 | { 40 | string bufferText = Formatter.Format(ChatHistory.Messages); 41 | return new OutputValues(new Dictionary { { MemoryKey, bufferText } }); 42 | } 43 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/WebBase/src/HtmlLoader.cs: -------------------------------------------------------------------------------- 1 | using AngleSharp; 2 | 3 | namespace LangChain.DocumentLoaders; 4 | 5 | /// 6 | /// 7 | /// 8 | public class HtmlLoader : IDocumentLoader 9 | { 10 | /// 11 | public async Task> LoadAsync( 12 | DataSource dataSource, 13 | DocumentLoaderSettings? settings = null, 14 | CancellationToken cancellationToken = default) 15 | { 16 | dataSource = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); 17 | 18 | if (dataSource.Type != DataSourceType.Uri) 19 | { 20 | throw new NotSupportedException("Only Uri is supported"); 21 | } 22 | 23 | var config = Configuration.Default.WithDefaultLoader(); 24 | var context = BrowsingContext.New(config); 25 | var document = await context.OpenAsync(dataSource.Value!, cancellation: cancellationToken).ConfigureAwait(false); 26 | 27 | foreach (var element in document.QuerySelectorAll("script, style, meta, link")) 28 | { 29 | element.Remove(); 30 | } 31 | 32 | var html = 33 | document.QuerySelector("html") ?? 34 | throw new NotSupportedException("Not supported for pages without tag"); 35 | 36 | var metadata = settings.CollectMetadataIfRequired(dataSource); 37 | 38 | return [new Document(html.TextContent, metadata: metadata)]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/Extensions/DependencyInjection/src/ServiceCollectionExtensions.Anthropic.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using LangChain.Providers.Anthropic; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace LangChain.Extensions.DependencyInjection; 7 | 8 | /// 9 | /// 10 | /// 11 | public static partial class ServiceCollectionExtensions 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | [RequiresDynamicCode("Requires dynamic code.")] 20 | [RequiresUnreferencedCode("Requires unreferenced code.")] 21 | public static IServiceCollection AddAnthropic( 22 | this IServiceCollection services) 23 | { 24 | services = services ?? throw new ArgumentNullException(nameof(services)); 25 | 26 | _ = services 27 | .AddOptions() 28 | .BindConfiguration(configSectionPath: AnthropicConfiguration.SectionName); 29 | _ = services 30 | .AddHttpClient(); 31 | _ = services 32 | .AddScoped(static services => AnthropicProvider.FromConfiguration( 33 | configuration: services.GetRequiredService>().Value)); 34 | 35 | return services; 36 | } 37 | } -------------------------------------------------------------------------------- /src/Meta/test/AzureOpenAiTests.cs: -------------------------------------------------------------------------------- 1 | /* 2 | using LangChain.Chains.LLM; 3 | using LangChain.LLMS.AzureOpenAi; 4 | using LangChain.Prompts; 5 | using LangChain.Schema; 6 | 7 | Temporarily disabled Azure tests as there is no API key. 8 | namespace LangChain.IntegrationTests 9 | { 10 | public class AzureOpenAiTests 11 | { 12 | [Fact] 13 | public async Task TestOpenAi_WithValidInput_ShouldReturnResponse() 14 | { 15 | var model = new AzureOpenAi(); 16 | 17 | var result = await model.Call("What is a good name for a company that sells colourful socks?"); 18 | 19 | result.Should().NotBeEmpty(); 20 | } 21 | 22 | [Fact] 23 | public async Task TestOpenAi_WithChain_ShouldReturnResponse() 24 | { 25 | var llm = new AzureOpenAi(); 26 | 27 | var template = "What is a good name for a company that makes {product}?"; 28 | var prompt = new PromptTemplate(new PromptTemplateInput(template, new List(1) { "product" })); 29 | 30 | var chain = new LlmChain(new LlmChainInput(llm, prompt)); 31 | 32 | var result = await chain.Call(new ChainValues(new Dictionary(1) 33 | { 34 | { "product", "colourful socks" } 35 | })); 36 | 37 | // The result is an object with a `text` property. 38 | (result.Value["text"] as string).Should().NotBeEmpty(); 39 | } 40 | } 41 | } 42 | */ -------------------------------------------------------------------------------- /src/Core/src/Prompts/BaseMessagePromptTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json; 2 | using LangChain.Providers; 3 | using LangChain.Schema; 4 | 5 | namespace LangChain.Prompts; 6 | 7 | /// 8 | /// 9 | /// 10 | public abstract class BaseMessagePromptTemplate 11 | { 12 | /// 13 | /// 14 | /// 15 | public abstract IReadOnlyList InputVariables { get; } 16 | 17 | /// 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | public abstract Task> FormatMessagesAsync( 24 | InputValues values, 25 | CancellationToken cancellationToken = default); 26 | 27 | /// 28 | /// 29 | /// 30 | /// 31 | public SerializedMessagePromptTemplate Serialize() 32 | { 33 | var serialized = new SerializedMessagePromptTemplate 34 | { 35 | Type = this.GetType().Name, 36 | // You need to serialize 'this' to a JSON string, then deserialize it back to a dictionary 37 | // to mimic the JavaScript `JSON.parse(JSON.stringify(this))` behavior. 38 | AdditionalProperties = JsonSerializer.Deserialize>( 39 | JsonSerializer.Serialize(this)) ?? new Dictionary(), 40 | }; 41 | return serialized; 42 | } 43 | } -------------------------------------------------------------------------------- /src/Utilities/Pollyfils/src/StringExtensions.Contains.cs: -------------------------------------------------------------------------------- 1 | #if !NET6_0_OR_GREATER 2 | // ReSharper disable once CheckNamespace 3 | 4 | namespace System; 5 | 6 | public static partial class PolyfillStringExtensions 7 | { 8 | public static bool Contains(this string text, string value, StringComparison comparisonType) 9 | { 10 | text = text ?? throw new ArgumentNullException(nameof(text)); 11 | 12 | switch (comparisonType) 13 | { 14 | case StringComparison.CurrentCulture: 15 | return text.IndexOf(value, StringComparison.CurrentCulture) >= 0; 16 | case StringComparison.CurrentCultureIgnoreCase: 17 | return text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) >= 0; 18 | case StringComparison.InvariantCulture: 19 | return text.IndexOf(value, StringComparison.InvariantCulture) >= 0; 20 | case StringComparison.InvariantCultureIgnoreCase: 21 | return text.IndexOf(value, StringComparison.InvariantCultureIgnoreCase) >= 0; 22 | case StringComparison.Ordinal: 23 | return text.IndexOf(value, StringComparison.Ordinal) >= 0; 24 | case StringComparison.OrdinalIgnoreCase: 25 | return text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0; 26 | default: 27 | throw new ArgumentOutOfRangeException(nameof(comparisonType), comparisonType, null); 28 | } 29 | } 30 | } 31 | #endif -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/ImageToTextGeneration/ImageToTextGenerationChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | using LangChain.Providers; 4 | 5 | namespace LangChain.Chains.StackableChains.ImageToTextGeneration; 6 | 7 | /// 8 | /// 9 | /// 10 | public class ImageToTextGenerationChain : BaseStackableChain 11 | { 12 | private readonly IImageToTextModel _model; 13 | private readonly BinaryData _image; 14 | 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | public ImageToTextGenerationChain( 22 | IImageToTextModel model, 23 | BinaryData image, 24 | string outputKey = "text") 25 | { 26 | _model = model; 27 | _image = image; 28 | OutputKeys = new[] { outputKey }; 29 | } 30 | 31 | /// 32 | protected override async Task InternalCallAsync( 33 | IChainValues values, 34 | CancellationToken cancellationToken = default) 35 | { 36 | values = values ?? throw new ArgumentNullException(nameof(values)); 37 | 38 | var text = await _model.GenerateTextFromImageAsync(new ImageToTextRequest { Image = _image }, cancellationToken: cancellationToken).ConfigureAwait(false); 39 | values.Value[OutputKeys[0]] = text; 40 | return values; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Splitters/Abstractions/test/Tests.MarkdownHeader.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Splitters.Text; 2 | 3 | namespace LangChain.Splitters; 4 | 5 | [TestFixture] 6 | public partial class Tests 7 | { 8 | [Test] 9 | public void TestMarkdown1() 10 | { 11 | var md = @" 12 | ## Header 1 13 | some text 14 | 15 | 16 | # Header 2 17 | some text 18 | "; 19 | var splitter = new MarkdownHeaderTextSplitter(); 20 | var res = splitter.SplitText(md); 21 | res.Count.Should().Be(2); 22 | res[0].Split("\n")[0].Should().Be("Header 1"); 23 | res[1].Split("\n")[0].Should().Be("Header 2"); 24 | } 25 | 26 | [Test] 27 | public void TestMarkdown2() 28 | { 29 | var md = @" 30 | # Header 1 31 | some text 32 | 33 | 34 | ## Header 2 35 | some text 36 | "; 37 | var splitter = new MarkdownHeaderTextSplitter(); 38 | var res = splitter.SplitText(md); 39 | res.Count.Should().Be(2); 40 | res[0].Split("\n")[0].Should().Be("Header 1"); 41 | 42 | 43 | } 44 | 45 | [Test] 46 | public void TestMarkdown3() 47 | { 48 | var md = @"# Foo 49 | 50 | ## Bar 51 | 52 | Hi this is Jim 53 | Hi this is Joe 54 | 55 | ## Baz 56 | 57 | Hi this is Molly"; 58 | 59 | var splitter = new MarkdownHeaderTextSplitter(includeHeaders: false); 60 | var res = splitter.SplitText(md); 61 | res[0].Should().Be("Hi this is Jim\nHi this is Joe"); 62 | res[1].Should().Be("Hi this is Molly"); 63 | } 64 | } -------------------------------------------------------------------------------- /src/Core/src/Base/IChainInputs.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Callback; 2 | 3 | namespace LangChain.Base; 4 | 5 | /// 6 | public interface IChainInputs : IBaseLangChainParams 7 | { 8 | /// 9 | /// Optional list of callback handlers (or callback manager). Defaults to None. 10 | /// Callback handlers are called throughout the lifecycle of a call to a chain, 11 | /// starting with on_chain_start, ending with on_chain_end or on_chain_error. 12 | /// Each custom chain can optionally call additional callback methods, see Callback docs 13 | /// for full details. 14 | /// 15 | public ICallbacks? Callbacks { get; set; } 16 | 17 | /// 18 | /// Optional list of tags associated with the chain. Defaults to None. 19 | /// These tags will be associated with each call to this chain, 20 | /// and passed as arguments to the handlers defined in `callbacks`. 21 | /// You can use these to eg identify a specific instance of a chain with its use case. 22 | /// 23 | public List Tags { get; set; } 24 | 25 | /// 26 | /// Optional metadata associated with the chain. Defaults to None. 27 | /// This metadata will be associated with each call to this chain, 28 | /// and passed as arguments to the handlers defined in `callbacks`. 29 | /// You can use these to eg identify a specific instance of a chain with its use case. 30 | /// 31 | public Dictionary Metadata { get; set; } 32 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.SequentialChain/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Chains.Base; 2 | using LangChain.Chains.LLM; 3 | using LangChain.Chains.Sequentials; 4 | using LangChain.Prompts; 5 | using LangChain.Providers.OpenAI.Predefined; 6 | using LangChain.Schema; 7 | 8 | using var httpClient = new HttpClient(); 9 | var llm = new OpenAiLatestFastChatModel("api-key"); 10 | 11 | var firstTemplate = "What is a good name for a company that makes {product}?"; 12 | var firstPrompt = new PromptTemplate(new PromptTemplateInput(firstTemplate, new List(1) { "product" })); 13 | 14 | var chainOne = new LlmChain(new LlmChainInput(llm, firstPrompt) 15 | { 16 | Verbose = true, 17 | OutputKey = "company_name" 18 | }); 19 | 20 | var secondTemplate = "Write a 20 words description for the following company:{company_name}"; 21 | var secondPrompt = new PromptTemplate(new PromptTemplateInput(secondTemplate, new List(1) { "company_name" })); 22 | 23 | var chainTwo = new LlmChain(new LlmChainInput(llm, secondPrompt)); 24 | 25 | var overallChain = new SequentialChain(new SequentialChainInput( 26 | new IChain[] 27 | { 28 | chainOne, 29 | chainTwo 30 | }, 31 | new[] { "product" }, 32 | new[] { "company_name", "text" } 33 | )); 34 | 35 | var result = await overallChain.CallAsync(new ChainValues(new Dictionary(1) 36 | { 37 | { "product", "colourful socks" } 38 | })); 39 | 40 | Console.WriteLine(result.Value["text"]); 41 | Console.WriteLine("SequentialChain sample finished."); -------------------------------------------------------------------------------- /src/Core/src/Extensions/VectorStoreIndexWrapper.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.CombineDocuments; 2 | using LangChain.Chains.RetrievalQA; 3 | using LangChain.Databases; 4 | using LangChain.Providers; 5 | 6 | namespace LangChain.Extensions; 7 | 8 | /// 9 | /// 10 | /// 11 | public static class VectorStoreIndexWrapper 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | /// 24 | public static Task QueryAsync( 25 | this IVectorCollection vectorCollection, 26 | IEmbeddingModel embeddingModel, 27 | string question, 28 | BaseCombineDocumentsChain llm, 29 | string inputKey = "question", 30 | string outputKey = "output_text", 31 | CancellationToken cancellationToken = default) 32 | { 33 | var chain = new RetrievalQaChain( 34 | new RetrievalQaChainInput( 35 | llm, 36 | vectorCollection.AsRetriever(embeddingModel)) 37 | { 38 | InputKey = inputKey, 39 | OutputKey = outputKey, 40 | } 41 | ); 42 | 43 | return chain.RunAsync(question, cancellationToken: cancellationToken); 44 | } 45 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Agents/Crew/AgentTask.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.StackableChains.Agents.Crew.Tools; 2 | 3 | namespace LangChain.Chains.StackableChains.Agents.Crew; 4 | 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | public class AgentTask( 12 | CrewAgent agent, 13 | string description, 14 | List? tools = null) 15 | { 16 | /// 17 | /// 18 | /// 19 | public CrewAgent Agent { get; set; } = agent; 20 | 21 | /// 22 | /// 23 | /// 24 | public List Tools { get; set; } = tools ?? new List(); 25 | 26 | /// 27 | /// 28 | /// 29 | public string Description { get; set; } = description; 30 | 31 | /// 32 | /// 33 | /// 34 | /// 35 | /// 36 | /// 37 | public async Task ExecuteAsync( 38 | string? context = null, 39 | CancellationToken cancellationToken = default) 40 | { 41 | Agent.AddTools(Tools); 42 | Agent.Context = context; 43 | var chain = Chain.Set(Description, "task") 44 | | Agent; 45 | var res = await chain.RunAsync("result", cancellationToken: cancellationToken).ConfigureAwait(false) ?? string.Empty; 46 | return res; 47 | } 48 | } -------------------------------------------------------------------------------- /src/Extensions/DependencyInjection/src/ServiceCollectionExtensions.HuggingFace.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using LangChain.Providers.HuggingFace; 3 | using Microsoft.Extensions.DependencyInjection; 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace LangChain.Extensions.DependencyInjection; 7 | 8 | /// 9 | /// 10 | /// 11 | public static partial class ServiceCollectionExtensions 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | [RequiresDynamicCode("Requires dynamic code.")] 20 | [RequiresUnreferencedCode("Requires unreferenced code.")] 21 | public static IServiceCollection AddHuggingFace( 22 | this IServiceCollection services) 23 | { 24 | services = services ?? throw new ArgumentNullException(nameof(services)); 25 | 26 | _ = services 27 | .AddOptions() 28 | .BindConfiguration(configSectionPath: HuggingFaceConfiguration.SectionName); 29 | _ = services 30 | .AddHttpClient(); 31 | _ = services 32 | .AddScoped(static services => new HuggingFaceProvider( 33 | configuration: services.GetRequiredService>().Value, 34 | httpClient: services.GetRequiredService())); 35 | 36 | return services; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Meta/test/OpenAiTests.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Providers.OpenAI.Predefined; 2 | using tryAGI.OpenAI; 3 | using static LangChain.Chains.Chain; 4 | 5 | namespace LangChain.IntegrationTests; 6 | 7 | [TestFixture] 8 | [Explicit] 9 | public class OpenAiTests 10 | { 11 | [Test] 12 | public void CountTokens() 13 | { 14 | var text = H.Resources.SocketIoClient_cs.AsString(); 15 | 16 | Tiktoken.ModelToEncoder.For(CreateChatCompletionRequestModel.Gpt4.ToValueString()).CountTokens(text).Should().Be(4300); 17 | new Gpt4OmniMiniModel("sk-random").CountTokens(text).Should().Be(4300); 18 | new Gpt4Model("sk-random").CountTokens(text).Should().Be(4300); 19 | } 20 | 21 | [Test] 22 | public async Task TestAudio() 23 | { 24 | var apiKey = 25 | Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? 26 | throw new InconclusiveException("OPENAI_API_KEY environment variable is not found."); 27 | var tts = new Tts1Model(apiKey); 28 | var stt = new Whisper1Model(apiKey); 29 | 30 | const string messageText = "My name is Jimmy."; 31 | var chain = 32 | Set(messageText, "message") 33 | | TTS(tts, inputKey: "message", outputKey: "audio").UseCache() 34 | | STT(stt, inputKey: "audio", outputKey: "text").UseCache(); 35 | 36 | var result = await chain.RunAsync(); 37 | var text = result.Value["text"].ToString() ?? string.Empty; 38 | 39 | messageText.ToLowerInvariant().Should().Be(text.ToLowerInvariant()); 40 | } 41 | } -------------------------------------------------------------------------------- /sweep.yaml: -------------------------------------------------------------------------------- 1 | # Sweep AI turns bugs & feature requests into code changes (https://sweep.dev) 2 | # For details on our config file, check out our docs at https://docs.sweep.dev/usage/config 3 | 4 | # This setting contains a list of rules that Sweep will check for. If any of these rules are broken in a new commit, Sweep will create an pull request to fix the broken rule. 5 | rules: 6 | - "All new business logic should have corresponding unit tests." 7 | - "Refactor large functions to be more modular." 8 | - "Add docstrings to all functions and file headers." 9 | 10 | # This is the branch that Sweep will develop from and make pull requests to. Most people use 'main' or 'master' but some users also use 'dev' or 'staging'. 11 | branch: 'main' 12 | 13 | # By default Sweep will read the logs and outputs from your existing Github Actions. To disable this, set this to false. 14 | gha_enabled: True 15 | 16 | # This is the description of your project. It will be used by sweep when creating PRs. You can tell Sweep what's unique about your project, what frameworks you use, or anything else you want. 17 | # 18 | # Example: 19 | # 20 | # description: sweepai/sweep is a python project. The main api endpoints are in sweepai/api.py. Write code that adheres to PEP8. 21 | description: '' 22 | 23 | # This sets whether to create pull requests as drafts. If this is set to True, then all pull requests will be created as drafts and GitHub Actions will not be triggered. 24 | draft: False 25 | 26 | # This is a list of directories that Sweep will not be able to edit. 27 | blocked_dirs: [] 28 | -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/ImageGeneration/ImageGenerationChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | using LangChain.Providers; 4 | 5 | namespace LangChain.Chains.StackableChains.ImageGeneration; 6 | 7 | /// 8 | /// 9 | /// 10 | public class ImageGenerationChain : BaseStackableChain 11 | { 12 | private readonly ITextToImageModel _model; 13 | 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | public ImageGenerationChain( 21 | ITextToImageModel model, 22 | string inputKey = "prompt", 23 | string outputKey = "image") 24 | { 25 | _model = model; 26 | InputKeys = new[] { inputKey }; 27 | OutputKeys = new[] { outputKey }; 28 | } 29 | 30 | /// 31 | protected override async Task InternalCallAsync( 32 | IChainValues values, 33 | CancellationToken cancellationToken = default) 34 | { 35 | values = values ?? throw new ArgumentNullException(nameof(values)); 36 | 37 | var prompt = 38 | values.Value[InputKeys[0]].ToString() ?? 39 | throw new InvalidOperationException("Input key is null"); 40 | byte[] image = await _model.GenerateImageAsync(prompt, cancellationToken: cancellationToken).ConfigureAwait(false); 41 | values.Value[OutputKeys[0]] = image; 42 | return values; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Core/src/Memory/BaseMemory.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Schema; 2 | 3 | namespace LangChain.Memory; 4 | 5 | /// 6 | /// Abstract base class for memory in Chains. 7 | /// 8 | /// Memory refers to state in Chains. Memory can be used to store information about 9 | /// past executions of a Chain and inject that information into the inputs of 10 | /// future executions of the Chain. For example, for conversational Chains Memory 11 | /// can be used to store conversations and automatically add them to future model 12 | /// prompts so that the model has the necessary context to respond coherently to 13 | /// the latest input. 14 | /// 15 | public abstract class BaseMemory 16 | { 17 | /// 18 | /// Return key-value pairs given the text input to the chain. 19 | /// 20 | public abstract List MemoryVariables { get; } 21 | 22 | /// 23 | /// The string keys this memory class will add to chain inputs. 24 | /// 25 | /// 26 | /// 27 | public abstract OutputValues LoadMemoryVariables(InputValues? inputValues); 28 | 29 | /// 30 | /// Save the context of this chain run to memory. 31 | /// 32 | /// 33 | /// 34 | public abstract Task SaveContext(InputValues inputValues, OutputValues outputValues); 35 | 36 | /// 37 | /// Clear memory contents. 38 | /// 39 | public abstract Task Clear(); 40 | 41 | } -------------------------------------------------------------------------------- /src/Core/src/Callback/ParentRunManager.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Base; 2 | 3 | namespace LangChain.Callback; 4 | 5 | /// 6 | /// Sync Parent Run Manager. 7 | /// 8 | public class ParentRunManager : BaseRunManager 9 | { 10 | /// 11 | public ParentRunManager() 12 | { 13 | 14 | } 15 | 16 | /// 17 | public ParentRunManager( 18 | string runId, 19 | List handlers, 20 | List inheritableHandlers, 21 | string? parentRunId = null, 22 | List? tags = null, 23 | List? inheritableTags = null, 24 | Dictionary? metadata = null, 25 | Dictionary? inheritableMetadata = null) 26 | : base(runId, handlers, inheritableHandlers, parentRunId, tags, inheritableTags, metadata, inheritableMetadata) 27 | { 28 | } 29 | 30 | /// 31 | /// Get a child callback manager. 32 | /// 33 | /// The tag for the child callback manager. 34 | /// The child callback manager. 35 | public CallbackManager GetChild(string? tag = null) 36 | { 37 | var manager = new CallbackManager(parentRunId: RunId); 38 | 39 | manager.SetHandlers(InheritableHandlers); 40 | 41 | manager.AddTags(InheritableTags); 42 | manager.AddMetadata(InheritableMetadata); 43 | 44 | if (tag != null) 45 | manager.AddTags(new List { tag }, inherit: false); 46 | 47 | return manager; 48 | } 49 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/Files/SaveIntoFileChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Chains.HelperChains; 3 | 4 | namespace LangChain.Chains.StackableChains.Files; 5 | 6 | /// 7 | /// 8 | /// 9 | public class SaveIntoFileChain : BaseStackableChain 10 | { 11 | private readonly string _filename; 12 | 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | public SaveIntoFileChain(string filename, string inputKey = "data") 19 | { 20 | _filename = filename; 21 | InputKeys = new[] { inputKey }; 22 | OutputKeys = Array.Empty(); 23 | } 24 | 25 | /// 26 | protected override async Task InternalCallAsync( 27 | IChainValues values, 28 | CancellationToken cancellationToken = default) 29 | { 30 | values = values ?? throw new ArgumentNullException(nameof(values)); 31 | 32 | if (values.Value[InputKeys[0]] is byte[] data) 33 | { 34 | await File2.WriteAllBytesAsync(_filename, data, cancellationToken).ConfigureAwait(false); 35 | } 36 | else if (values.Value[InputKeys[0]] is string text) 37 | { 38 | await File2.WriteAllTextAsync(_filename, text, cancellationToken).ConfigureAwait(false); 39 | } 40 | else 41 | { 42 | throw new InvalidOperationException($"Input key {InputKeys[0]} must be byte[] or string"); 43 | } 44 | 45 | return values; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Cli/src/Models/Tool.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.Cli.Models; 2 | 3 | internal enum Tool 4 | { 5 | Filesystem, 6 | Fetch, 7 | GitHub, 8 | Git, 9 | Puppeteer, 10 | SequentialThinking, 11 | Slack, 12 | Figma, 13 | DocumentConversion, 14 | } 15 | 16 | // Extension class to handle tool parsing with optional toolsets 17 | internal static class ToolExtensions 18 | { 19 | // Parse a string into a Tool with optional toolset 20 | public static (Tool Tool, string[]? Toolsets) ParseTool(string input) 21 | { 22 | // Check if the input contains a toolset in square brackets 23 | int openBracketIndex = input.IndexOf('[', StringComparison.Ordinal); 24 | if (openBracketIndex > 0 && input.EndsWith(']')) 25 | { 26 | string toolName = input.Substring(0, openBracketIndex); 27 | string toolsetsString = input.Substring(openBracketIndex + 1, input.Length - openBracketIndex - 2); 28 | 29 | // Split by comma to handle multiple toolsets 30 | string[] toolsets = toolsetsString.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); 31 | 32 | if (Enum.TryParse(toolName, true, out var tool)) 33 | { 34 | return (tool, toolsets); 35 | } 36 | } 37 | 38 | // No toolset specified, just parse the tool name 39 | if (Enum.TryParse(input, ignoreCase: true, out var simpleTool)) 40 | { 41 | return (simpleTool, null); 42 | } 43 | 44 | throw new ArgumentException($"Unknown tool: {input}"); 45 | } 46 | } -------------------------------------------------------------------------------- /src/Cli/src/LangChain.Cli.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net8.0;net9.0 6 | enable 7 | enable 8 | $(NoWarn);CA1724;CA1303;IL3050;IL2026 9 | false 10 | 11 | 12 | 13 | true 14 | langchain 15 | Command Line Interface to run some LangChain tasks. 16 | $(PackageTags);cli 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/DocumentLoaders/Word/src/WordLoader.cs: -------------------------------------------------------------------------------- 1 | using DocumentFormat.OpenXml.Packaging; 2 | using DocumentFormat.OpenXml.Wordprocessing; 3 | using System.Text; 4 | 5 | namespace LangChain.DocumentLoaders; 6 | 7 | /// 8 | /// 9 | /// 10 | public sealed class WordLoader : IDocumentLoader 11 | { 12 | /// 13 | public async Task> LoadAsync( 14 | DataSource dataSource, 15 | DocumentLoaderSettings? settings = null, 16 | CancellationToken cancellationToken = default) 17 | { 18 | dataSource = dataSource ?? throw new ArgumentNullException(nameof(dataSource)); 19 | 20 | using var stream = await dataSource.GetStreamAsync(cancellationToken).ConfigureAwait(false); 21 | using var wordDocument = WordprocessingDocument.Open(stream, isEditable: false); 22 | 23 | var documents = new List(); 24 | foreach (var paragraph in wordDocument.MainDocumentPart?.Document.Body?.Elements() ?? []) 25 | { 26 | var paragraphText = new StringBuilder(); 27 | foreach (var run in paragraph.Elements()) 28 | { 29 | paragraphText.Append(run.InnerText); 30 | } 31 | 32 | if (paragraphText.Length > 0) 33 | { 34 | documents.Add(paragraphText.ToString()); 35 | } 36 | } 37 | 38 | var metadata = settings.CollectMetadataIfRequired(dataSource); 39 | 40 | return documents 41 | .Select(text => new Document(text, metadata: metadata)) 42 | .ToList(); 43 | } 44 | } -------------------------------------------------------------------------------- /src/DocumentLoaders/Abstractions/src/FileLoader.cs: -------------------------------------------------------------------------------- 1 | namespace LangChain.DocumentLoaders; 2 | 3 | /// 4 | /// 5 | /// 6 | public class FileLoader : IDocumentLoader 7 | { 8 | /// 9 | public async Task> LoadAsync( 10 | DataSource dataSource, 11 | DocumentLoaderSettings? settings = null, 12 | CancellationToken cancellationToken = default) 13 | { 14 | dataSource = dataSource ?? throw new ArgumentNullException(paramName: nameof(dataSource)); 15 | 16 | var content = await File2.ReadAllTextAsync(dataSource.Value!, dataSource.Encoding, cancellationToken).ConfigureAwait(false); 17 | 18 | // It makes sense for agents, but we need tests for this 19 | // if (AutoDetectEncoding) 20 | // { 21 | // // todo: change this to a more robust solution 22 | // // bruteforce encoding detection 23 | // var encodings = new[] { Encoding.UTF8, Encoding.ASCII, Encoding.Unicode }; 24 | // foreach (var encoding in encodings) 25 | // { 26 | // try 27 | // { 28 | // content = await File2.ReadAllTextAsync(FilePath, encoding, cancellationToken).ConfigureAwait(false); 29 | // break; 30 | // } 31 | // catch (DecoderFallbackException) 32 | // { 33 | // continue; 34 | // } 35 | // } 36 | // } 37 | 38 | var metadata = settings.CollectMetadataIfRequired(dataSource); 39 | 40 | return [new Document(content, metadata: metadata)]; 41 | } 42 | } -------------------------------------------------------------------------------- /src/Core/src/Chains/StackableChains/RetreiveDocumentsChain.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Schema; 2 | using LangChain.Databases; 3 | using LangChain.Extensions; 4 | using LangChain.Providers; 5 | 6 | namespace LangChain.Chains.HelperChains; 7 | 8 | /// 9 | public class RetrieveDocumentsChain : BaseStackableChain 10 | { 11 | private readonly IVectorCollection _vectorCollection; 12 | private readonly IEmbeddingModel _embeddingModel; 13 | private readonly int _amount; 14 | 15 | /// 16 | public RetrieveDocumentsChain( 17 | IVectorCollection vectorCollection, 18 | IEmbeddingModel embeddingModel, 19 | string inputKey = "query", 20 | string outputKey = "documents", 21 | int amount = 4) 22 | { 23 | _vectorCollection = vectorCollection; 24 | _embeddingModel = embeddingModel; 25 | _amount = amount; 26 | InputKeys = new[] { inputKey }; 27 | OutputKeys = new[] { outputKey }; 28 | } 29 | 30 | /// 31 | protected override async Task InternalCallAsync( 32 | IChainValues values, 33 | CancellationToken cancellationToken = default) 34 | { 35 | values = values ?? throw new ArgumentNullException(nameof(values)); 36 | 37 | var query = values.Value[InputKeys[0]].ToString() ?? string.Empty; 38 | var results = await _vectorCollection.GetSimilarDocuments( 39 | _embeddingModel, 40 | query, 41 | amount: _amount, 42 | cancellationToken: cancellationToken).ConfigureAwait(false); 43 | values.Value[OutputKeys[0]] = results.ToList(); 44 | return values; 45 | } 46 | } -------------------------------------------------------------------------------- /examples/LangChain.Samples.Prompts/Program.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Chains.LLM; 2 | using LangChain.Prompts; 3 | using LangChain.Providers.OpenAI.Predefined; 4 | using LangChain.Schema; 5 | 6 | var llm = new OpenAiLatestFastChatModel(Environment.GetEnvironmentVariable("OPENAI_API_KEY")!); 7 | 8 | var prompt = new PromptTemplate(new PromptTemplateInput( 9 | template: "What is a good name for a company that makes {product}?", 10 | inputVariables: ["product"])); 11 | 12 | var chain = new LlmChain(new LlmChainInput(llm, prompt)); 13 | 14 | var result = await chain.CallAsync(new ChainValues(new Dictionary 15 | { 16 | { "product", "colourful socks" } 17 | })); 18 | 19 | // The result is an object with a `text` property. 20 | Console.WriteLine(result.Value["text"]); 21 | 22 | // Since the LLMChain is a single-input, single-output chain, we can also call it with `run`. 23 | // This takes in a string and returns the `text` property. 24 | var result2 = await chain.RunAsync("colourful socks"); 25 | 26 | Console.WriteLine(result2); 27 | 28 | var chatPrompt = ChatPromptTemplate.FromPromptMessages([ 29 | SystemMessagePromptTemplate.FromTemplate( 30 | "You are a helpful assistant that translates {input_language} to {output_language}."), 31 | HumanMessagePromptTemplate.FromTemplate("{text}") 32 | ]); 33 | 34 | var chainB = new LlmChain(new LlmChainInput(llm, chatPrompt) 35 | { 36 | Verbose = true 37 | }); 38 | 39 | var resultB = await chainB.CallAsync(new ChainValues(new Dictionary(3) 40 | { 41 | {"input_language", "English"}, 42 | {"output_language", "French"}, 43 | {"text", "I love programming"}, 44 | })); 45 | 46 | Console.WriteLine(resultB.Value["text"]); -------------------------------------------------------------------------------- /src/Core/src/Chains/Sequentials/SequentialChainInput.cs: -------------------------------------------------------------------------------- 1 | using LangChain.Abstractions.Chains.Base; 2 | using LangChain.Base; 3 | using LangChain.Callback; 4 | 5 | namespace LangChain.Chains.Sequentials; 6 | 7 | /// 8 | /// 9 | /// 10 | public class SequentialChainInput : IChainInputs 11 | { 12 | /// 13 | /// 14 | /// 15 | public IReadOnlyList Chains { get; } 16 | 17 | /// 18 | /// 19 | /// 20 | public IReadOnlyList InputVariables { get; } 21 | 22 | /// 23 | /// 24 | /// 25 | public IReadOnlyList? OutputVariables { get; } 26 | 27 | /// 28 | /// 29 | /// 30 | public bool ReturnAll { get; } 31 | 32 | /// 33 | public bool Verbose { get; set; } 34 | 35 | /// 36 | public ICallbacks? Callbacks { get; set; } 37 | 38 | /// 39 | public List Tags { get; set; } = new(); 40 | 41 | /// 42 | public Dictionary Metadata { get; set; } = new(); 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | public SequentialChainInput(IChain[] chains, 52 | string[] inputVariables, 53 | string[]? outputVariables = null, 54 | bool returnAll = false) 55 | { 56 | Chains = chains; 57 | InputVariables = inputVariables; 58 | OutputVariables = outputVariables; 59 | ReturnAll = returnAll; 60 | } 61 | } --------------------------------------------------------------------------------