-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Small fixes and agents support (#99)
* Ollama bug fix * standartized key names to data type. this allows to use chains in small scenarious without using key names * agents support
- Loading branch information
Showing
13 changed files
with
493 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/AgentTask.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using LangChain.Abstractions.Chains.Base; | ||
using LangChain.Chains.StackableChains.Agents.Crew.Tools; | ||
using LangChain.Chains.StackableChains.ReAct; | ||
|
||
namespace LangChain.Chains.StackableChains.Agents.Crew; | ||
|
||
public class AgentTask(CrewAgent agent, string description, List<CrewAgentTool>? tools=null) | ||
{ | ||
public CrewAgent Agent { get; set; } = agent; | ||
public List<CrewAgentTool> Tools { get; set; } = tools??new List<CrewAgentTool>(); | ||
public string Description { get; set; } = description; | ||
|
||
public string Execute(string context=null) | ||
{ | ||
Agent.AddTools(Tools); | ||
Agent.Context = context; | ||
var chain = Chain.Set(Description, "task") | ||
| Agent; | ||
var res = chain.Run("result").Result; | ||
return res; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/Crew.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using LangChain.Chains.StackableChains.Agents.Crew.Tools; | ||
|
||
namespace LangChain.Chains.StackableChains.Agents.Crew; | ||
|
||
public class Crew(IEnumerable<CrewAgent> agents, IEnumerable<AgentTask> tasks) | ||
{ | ||
|
||
public string Run() | ||
{ | ||
string? context = null; | ||
|
||
foreach (var task in tasks) | ||
{ | ||
task.Tools.Add(new AskQuestionTool(agents.Except(new []{task.Agent}))); | ||
task.Tools.Add(new DelegateWorkTool(agents.Except(new[] { task.Agent }))); | ||
var res = task.Execute(context); | ||
Check warning on line 16 in src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/Crew.cs GitHub Actions / Build, test and publish / Build, test and publish
|
||
context = res; | ||
} | ||
|
||
return context; | ||
|
||
} | ||
|
||
|
||
|
||
} |
172 changes: 172 additions & 0 deletions
172
src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/CrewAgent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
using LangChain.Abstractions.Schema; | ||
using LangChain.Chains.HelperChains; | ||
using LangChain.Chains.LLM; | ||
using LangChain.Chains.StackableChains.Agents.Crew.Tools; | ||
using LangChain.Chains.StackableChains.ReAct; | ||
using LangChain.Memory; | ||
using LangChain.Providers; | ||
using static LangChain.Chains.Chain; | ||
|
||
namespace LangChain.Chains.StackableChains.Agents.Crew; | ||
|
||
public class CrewAgent : BaseStackableChain | ||
{ | ||
public event Action<string> ReceivedTask=delegate{}; | ||
public event Action<string,string> CalledAction = delegate { }; | ||
public event Action<string> ActionResult = delegate { }; | ||
public event Action<string> Answered = delegate { }; | ||
|
||
public string Role { get; } | ||
public string Goal { get; } | ||
public string? Backstory { get; } | ||
private readonly IChatModel _model; | ||
private readonly List<string> _actionsHistory; | ||
public bool UseMemory { get; set; }=false; | ||
public bool UseCache { get; set; } | ||
private IChainValues _currentValues; | ||
private Dictionary<string, CrewAgentTool> _tools=new Dictionary<string, CrewAgentTool>(); | ||
|
||
private StackChain? _chain=null; | ||
private readonly List<string> _memory; | ||
private int _maxActions=5; | ||
|
||
public CrewAgent(IChatModel model, string role, string goal, string? backstory = "") | ||
Check warning on line 33 in src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/CrewAgent.cs GitHub Actions / Build, test and publish / Build, test and publish
|
||
{ | ||
Role = role; | ||
Goal = goal; | ||
Backstory = backstory; | ||
_model = model; | ||
|
||
InputKeys = new[] {"task"}; | ||
OutputKeys = new[] {"result"}; | ||
|
||
_actionsHistory = new List<string>(); | ||
_memory = new List<string>(); | ||
} | ||
|
||
public void AddTools(IEnumerable<CrewAgentTool> tools) | ||
{ | ||
_tools = tools | ||
.Where(x => !_tools.ContainsKey(x.Name)) | ||
.ToDictionary(x => x.Name, x => x); | ||
InitializeChain(); | ||
} | ||
|
||
public string? Context { get; set; } = null; | ||
|
||
public int MaxActions | ||
{ | ||
get => _maxActions; | ||
set => _maxActions = value; | ||
} | ||
|
||
private string GenerateToolsDescriptions() | ||
{ | ||
if (_tools.Count==0) return ""; | ||
return string.Join("\n", _tools.Select(x => $"- {x.Value.Name}, {x.Value.Description}\n")); | ||
} | ||
|
||
private string GenerateToolsNamesList() | ||
{ | ||
if (_tools.Count == 0) return ""; | ||
return string.Join(", ", _tools.Select(x => x.Key)); | ||
} | ||
|
||
private void InitializeChain() | ||
{ | ||
string prompt; | ||
if (UseMemory) | ||
{ | ||
prompt = Prompts.TaskExecutionWithMemory; | ||
} | ||
else | ||
{ | ||
prompt = Prompts.TaskExecutionWithoutMemory; | ||
} | ||
|
||
|
||
var chain = Set(GenerateToolsDescriptions, "tools") | ||
| Set(GenerateToolsNamesList, "tool_names") | ||
| Set(Role, "role") | ||
| Set(Goal, "goal") | ||
| Set(Backstory, "backstory") | ||
Check warning on line 92 in src/libs/LangChain.Core/Chains/StackableChains/Agents/Crew/CrewAgent.cs GitHub Actions / Build, test and publish / Build, test and publish
|
||
| Set(() => string.Join("\n", _memory), "memory") | ||
| Set(() => string.Join("\n", _actionsHistory), "actions_history") | ||
| Template(prompt) | ||
| Chain.LLM(_model).UseCache(UseCache) | ||
| Do(x => _actionsHistory.Add((x["text"] as string))) | ||
| ReActParser(inputKey: "text", outputKey: OutputKeys[0]) | ||
| Do(AddToMemory); | ||
|
||
|
||
_chain = chain; | ||
} | ||
|
||
private void AddToMemory(Dictionary<string, object> obj) | ||
{ | ||
if (!UseMemory) return; | ||
var res = obj[OutputKeys[0]]; | ||
if (res is AgentFinish a) | ||
{ | ||
_memory.Add(a.Output); | ||
} | ||
} | ||
|
||
|
||
protected override async Task<IChainValues> InternalCall(IChainValues values) | ||
{ | ||
var task = values.Value[InputKeys[0]] as string; | ||
_actionsHistory.Clear(); | ||
|
||
ReceivedTask(task); | ||
|
||
if (Context!=null) | ||
{ | ||
task += "\n" + "This is the context you are working with:\n"+Context; | ||
} | ||
|
||
if (_chain == null) | ||
{ | ||
InitializeChain(); | ||
} | ||
var chain = | ||
Set(task, "task") | ||
| _chain!; | ||
for (int i = 0; i < _maxActions; i++) | ||
{ | ||
|
||
var res = await chain!.Run<object>(OutputKeys[0]); | ||
if (res is AgentAction action) | ||
{ | ||
CalledAction(action.Action, action.ActionInput); | ||
|
||
if (!_tools.ContainsKey(action.Action)) | ||
{ | ||
ActionResult("You don't have this tool"); | ||
_actionsHistory.Add("Observation: You don't have this tool"); | ||
_actionsHistory.Add("Thought:"); | ||
continue; | ||
} | ||
|
||
var tool = _tools[action.Action]; | ||
var toolRes = tool.ToolAction(action.ActionInput); | ||
ActionResult(toolRes); | ||
_actionsHistory.Add("Observation: " + toolRes); | ||
_actionsHistory.Add("Thought:"); | ||
|
||
continue; | ||
} | ||
else if (res is AgentFinish finish) | ||
{ | ||
values.Value.Add(OutputKeys[0], finish.Output); | ||
if(UseMemory) | ||
_memory.Add(finish.Output); | ||
|
||
Answered(finish.Output); | ||
return values; | ||
} | ||
} | ||
|
||
throw new Exception($"Max actions exceeded({_maxActions})"); | ||
} | ||
} |
Oops, something went wrong.