Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MemoryBanks and updated gh-flow sample #80

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/Microsoft.AI.Agents.Orleans/MemoryBank.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using Microsoft.AI.Agents.Abstractions;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Orleans.Runtime;
using Orleans.Streams;

namespace Microsoft.AI.Agents.Orleans;

public abstract class MemoryBank : Grain, IGrainWithStringKey, IMemoryBank
{
protected virtual string Namespace { get; set; }
protected readonly Kernel _kernel;
public MemoryBank(
[PersistentState("memoryBanks", "memoryBanks")] IPersistentState<MemoryBankState> memory,
Kernel kernel)
{
Memory = memory;
_kernel = kernel;
}
public string Name { get; set; }
public IPersistentState<MemoryBankState> Memory { get; set; }
public abstract Task<string> ConsolidateMemory();

public abstract Task<MemoryItem> ExtractMemory(Event item);

public async Task HandleEvent(Event item)
{
await ProcessEvent(item);
}

public async Task ProcessEvent(Event item)
{
var memory = await ExtractMemory(item);
if (memory != default)
{
if (Memory.State.Events == null) Memory.State.Events = new List<Event>();
if (Memory.State.Memories == null) Memory.State.Memories = new List<MemoryItem>();
Memory.State.Events.Add(item);
Memory.State.Memories.Add(memory);
var summary = await ConsolidateMemory();
Memory.State.Summary = summary;
await Memory.WriteStateAsync();
}
}

public async Task PublishEvent(string ns, string id, Event item)
{
var streamProvider = this.GetStreamProvider("StreamProvider");
var streamId = StreamId.Create(ns, id);
var stream = streamProvider.GetStream<Event>(streamId);
await stream.OnNextAsync(item);
}
private async Task HandleEvent(Event item, StreamSequenceToken? token)
{
await HandleEvent(item);
}

public async override Task OnActivateAsync(CancellationToken cancellationToken)
{
var streamProvider = this.GetStreamProvider("StreamProvider");
var streamId = StreamId.Create(Namespace, this.GetPrimaryKeyString());
var stream = streamProvider.GetStream<Event>(streamId);
await stream.SubscribeAsync(HandleEvent);
}

protected async Task<string> CallFunction(string template, KernelArguments arguments, OpenAIPromptExecutionSettings? settings = null)
{
var propmptSettings = settings ?? new OpenAIPromptExecutionSettings { MaxTokens = 4096, Temperature = 0.5, TopP = 0.8 };
var function = _kernel.CreateFunctionFromPrompt(template, propmptSettings);
var result = (await _kernel.InvokeAsync(function, arguments)).ToString();
return result;
}

public virtual Task<string> Recall()
{
return Task.FromResult(Memory.State.Summary);
}
public Task<MemoryBankState> IntrospectMemory()
{
return Task.FromResult(Memory.State);
}
}
34 changes: 34 additions & 0 deletions src/Microsoft.AI.Agents.Orleans/MemorySurrogate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Microsoft.AI.Agents.Abstractions;

namespace Microsoft.AI.Agents.Orleans;


[GenerateSerializer]
public struct MemoryItemSurrogate
{
[Id(0)]
public Guid Id { get; set; }
[Id(1)]
public string Memory { get; set; }
[Id(2)]
public List<string> Tags { get; set; }
}

[RegisterConverter]
public sealed class MemoryItemSurrogateConverter :
IConverter<MemoryItem, MemoryItemSurrogate>
{
public MemoryItem ConvertFromSurrogate(
in MemoryItemSurrogate surrogate) => new MemoryItem {
Id = surrogate.Id,
Memory = surrogate.Memory,
Tags = surrogate.Tags
};

public MemoryItemSurrogate ConvertToSurrogate(in MemoryItem value) =>
new MemoryItemSurrogate {
Id = value.Id,
Memory = value.Memory,
Tags = value.Tags
};
}
11 changes: 11 additions & 0 deletions src/Microsoft.AI.Agents/Abstractions/IMemoryBank.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Microsoft.AI.Agents.Abstractions;

public interface IMemoryBank : IAgent
{
public Task ProcessEvent(Event item);
public Task<MemoryItem> ExtractMemory(Event item);
public Task<string> ConsolidateMemory();
public Task<string> Recall();
public Task<MemoryBankState> IntrospectMemory();

}
8 changes: 8 additions & 0 deletions src/Microsoft.AI.Agents/Abstractions/MemoryBankState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.AI.Agents.Abstractions;

public class MemoryBankState
{
public List<MemoryItem> Memories { get; set; }
public List<Event> Events { get; set; }
public string Summary { get; set; }
}
8 changes: 8 additions & 0 deletions src/Microsoft.AI.Agents/Abstractions/MemoryItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.AI.Agents.Abstractions;

public class MemoryItem
{
public Guid Id { get; set; }
public string Memory { get; set; }
public List<string> Tags { get; set; }
}