optimize AgentHook,IInstructHook
This commit is contained in:
parent
6fa8950f79
commit
b748ce3d9f
|
|
@ -9,6 +9,8 @@ public interface IAgentHook
|
|||
/// </summary>
|
||||
string SelfId { get; }
|
||||
Agent Agent { get; }
|
||||
|
||||
bool IsMatch(string id) => string.IsNullOrEmpty(SelfId) || SelfId == id;
|
||||
void SetAgent(Agent agent);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace BotSharp.Abstraction.Instructs;
|
|||
public interface IInstructHook
|
||||
{
|
||||
string SelfId { get; }
|
||||
bool IsMatch(string id) => string.IsNullOrEmpty(SelfId) || SelfId == id;
|
||||
Task BeforeCompletion(Agent agent, RoleDialogModel message);
|
||||
Task AfterCompletion(Agent agent, InstructResult result);
|
||||
Task OnResponseGenerated(InstructResponseModel response);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Infrastructures;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
|
|
@ -10,29 +11,16 @@ public partial class AgentService
|
|||
// [SharpCache(10, perInstanceCache: true)]
|
||||
public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id) || id == Guid.Empty.ToString())
|
||||
if (string.IsNullOrEmpty(id) || id == Guid.Empty.ToString()) return null;
|
||||
|
||||
var emitOptions = new HookEmitOption<IAgentHook>
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var hooks = _services.GetServices<IAgentHook>();
|
||||
|
||||
// Before agent is loaded.
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hook.OnAgentLoading(ref id);
|
||||
}
|
||||
ShouldExecute = hook => hook.IsMatch(id)
|
||||
};
|
||||
HookEmitter.Emit<IAgentHook>(_services, hook => hook.OnAgentLoading(ref id), emitOptions);
|
||||
|
||||
var agent = await GetAgent(id);
|
||||
if (agent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (agent == null) return null;
|
||||
|
||||
await InheritAgent(agent);
|
||||
OverrideInstructionByChannel(agent);
|
||||
|
|
@ -43,13 +31,7 @@ public partial class AgentService
|
|||
PopulateState(agent.TemplateDict);
|
||||
|
||||
// After agent is loaded
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
HookEmitter.Emit<IAgentHook>(_services, hook => {
|
||||
hook.SetAgent(agent);
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
|
|
@ -72,13 +54,14 @@ public partial class AgentService
|
|||
hook.OnAgentUtilityLoaded(agent);
|
||||
}
|
||||
|
||||
if(!agent.McpTools.IsNullOrEmpty())
|
||||
if (!agent.McpTools.IsNullOrEmpty())
|
||||
{
|
||||
hook.OnAgentMcpToolLoaded(agent);
|
||||
}
|
||||
|
||||
|
||||
hook.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
}, emitOptions);
|
||||
|
||||
_logger.LogInformation($"Loaded agent {agent}.");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using BotSharp.Abstraction.Instructs.Models;
|
||||
using BotSharp.Abstraction.Instructs;
|
||||
using System.IO;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
namespace BotSharp.Core.Files.Services;
|
||||
|
||||
|
|
@ -24,14 +25,11 @@ public partial class FileInstructService
|
|||
}
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -41,8 +39,7 @@ public partial class FileInstructService
|
|||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message.Content;
|
||||
}
|
||||
|
|
@ -59,14 +56,11 @@ public partial class FileInstructService
|
|||
Instruction = instruction
|
||||
}, new RoleDialogModel(AgentRole.User, instruction ?? text));
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -76,8 +70,7 @@ public partial class FileInstructService
|
|||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
|
@ -104,14 +97,11 @@ public partial class FileInstructService
|
|||
|
||||
stream.Close();
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -119,8 +109,7 @@ public partial class FileInstructService
|
|||
Model = completion.Model,
|
||||
UserMessage = string.Empty,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
|
@ -150,13 +139,11 @@ public partial class FileInstructService
|
|||
stream.Close();
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -166,8 +153,7 @@ public partial class FileInstructService
|
|||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
|
@ -205,14 +191,11 @@ public partial class FileInstructService
|
|||
imageStream.Close();
|
||||
maskStream.Close();
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -222,8 +205,7 @@ public partial class FileInstructService
|
|||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using BotSharp.Abstraction.Files.Converters;
|
||||
using BotSharp.Abstraction.Instructs.Models;
|
||||
using BotSharp.Abstraction.Instructs;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
|
||||
namespace BotSharp.Core.Files.Services;
|
||||
|
||||
|
|
@ -42,14 +43,11 @@ public partial class FileInstructService
|
|||
}
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != innerAgentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(innerAgentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = innerAgentId,
|
||||
|
|
@ -59,8 +57,7 @@ public partial class FileInstructService
|
|||
UserMessage = text,
|
||||
SystemInstruction = instruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message.Content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
using BotSharp.Abstraction.Instructs;
|
||||
using BotSharp.Abstraction.Instructs.Models;
|
||||
|
||||
|
|
@ -60,14 +61,11 @@ public class ExecuteTemplateFn : IFunctionCallback
|
|||
new(AgentRole.User, text)
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agent.Id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(agent.Id)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = agent.Id,
|
||||
|
|
@ -76,8 +74,7 @@ public class ExecuteTemplateFn : IFunctionCallback
|
|||
Model = completion.Model,
|
||||
UserMessage = text,
|
||||
CompletionText = response.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return response.Content;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,14 +23,9 @@ public partial class InstructService
|
|||
}
|
||||
|
||||
// Trigger before completion hooks
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
var hooks = _services.GetServices<IInstructHook>().Where(p => p.IsMatch(agentId));
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await hook.BeforeCompletion(agent, message);
|
||||
|
||||
// Interrupted by hook
|
||||
|
|
@ -99,11 +94,6 @@ public partial class InstructService
|
|||
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await hook.AfterCompletion(agent, response);
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using BotSharp.Abstraction.Infrastructures;
|
||||
using BotSharp.Abstraction.Instructs;
|
||||
using BotSharp.Abstraction.Instructs.Models;
|
||||
using BotSharp.Core.Infrastructures;
|
||||
|
|
@ -58,14 +59,11 @@ public class InstructModeController : ControllerBase
|
|||
var textCompletion = CompletionProvider.GetTextCompletion(_services);
|
||||
var response = await textCompletion.GetCompletion(input.Text, agentId, Guid.NewGuid().ToString());
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(agentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = agentId,
|
||||
|
|
@ -74,8 +72,8 @@ public class InstructModeController : ControllerBase
|
|||
TemplateName = input.Template,
|
||||
UserMessage = input.Text,
|
||||
CompletionText = response
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
@ -103,14 +101,11 @@ public class InstructModeController : ControllerBase
|
|||
}
|
||||
});
|
||||
|
||||
var hooks = _services.GetServices<IInstructHook>();
|
||||
foreach (var hook in hooks)
|
||||
var emitOptions = new HookEmitOption<IInstructHook>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != agentId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ShouldExecute = hook => hook.IsMatch(agentId)
|
||||
};
|
||||
await HookEmitter.Emit<IInstructHook>(_services, async hook =>
|
||||
await hook.OnResponseGenerated(new InstructResponseModel
|
||||
{
|
||||
AgentId = agentId,
|
||||
|
|
@ -120,8 +115,8 @@ public class InstructModeController : ControllerBase
|
|||
UserMessage = input.Text,
|
||||
SystemInstruction = message.RenderedInstruction,
|
||||
CompletionText = message.Content
|
||||
});
|
||||
}
|
||||
}), emitOptions);
|
||||
|
||||
return message.Content;
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
Loading…
Reference in a new issue