From 5f4d1dd35ea19fdb0aee56415716b9d75492b0cb Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 17 Dec 2024 13:49:15 -0800 Subject: [PATCH 001/110] wip --- dotnet/AutoGen.sln | 14 ++ dotnet/Directory.Packages.props | 3 +- .../Microsoft.AutoGen/Core/AgentsMetadata.cs | 85 +++++++++ .../TopicSubscriptionAttribute.cs | 0 .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 3 +- .../Services/Grpc/GrpcGatewayService.cs | 2 +- .../GrpcGatewayServiceTests.cs | 171 ++++++++++++++++++ .../Helpers/Grpc/TestAsyncStreamReader.cs | 69 +++++++ .../Helpers/Grpc/TestGrpcClient.cs | 36 ++++ .../Helpers/Grpc/TestServerCallContext.cs | 73 ++++++++ .../Helpers/Grpc/TestServerStreamWriter.cs | 86 +++++++++ .../Helpers/Orleans/ClusterCollection.cs | 10 + .../Helpers/Orleans/ClusterFixture.cs | 21 +++ .../Orleans/SiloBuilderConfigurator.cs | 21 +++ ...icrosoft.AutoGen.Runtime.Grpc.Tests.csproj | 25 +++ .../TestAgent.cs | 46 +++++ .../Microsoft.Autogen.Tests.Shared.csproj | 26 +++ .../Protos/messages.proto | 43 +++++ 18 files changed, 730 insertions(+), 4 deletions(-) create mode 100644 dotnet/src/Microsoft.AutoGen/Core/AgentsMetadata.cs rename dotnet/src/Microsoft.AutoGen/{Contracts => Core}/TopicSubscriptionAttribute.cs (100%) create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestAsyncStreamReader.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerCallContext.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerStreamWriter.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterCollection.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterFixture.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj create mode 100644 dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs create mode 100644 dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj create mode 100644 dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index d0707a89a7fd..aaeb45125ac4 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -142,6 +142,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Agents", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.AgentHost", "src\Microsoft.AutoGen\AgentHost\Microsoft.Autogen.AgentHost.csproj", "{4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.Grpc.Tests", "test\Microsoft.AutoGen.Runtime.Grpc.Tests\Microsoft.AutoGen.Runtime.Grpc.Tests.csproj", "{0E7983BB-2602-421E-8B37-332E52870A10}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.Tests.Shared", "test\Microsoft.Autogen.Tests.Shared\Microsoft.Autogen.Tests.Shared.csproj", "{6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -372,6 +376,14 @@ Global {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}.Debug|Any CPU.Build.0 = Debug|Any CPU {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}.Release|Any CPU.ActiveCfg = Release|Any CPU {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}.Release|Any CPU.Build.0 = Release|Any CPU + {0E7983BB-2602-421E-8B37-332E52870A10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E7983BB-2602-421E-8B37-332E52870A10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E7983BB-2602-421E-8B37-332E52870A10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E7983BB-2602-421E-8B37-332E52870A10}.Release|Any CPU.Build.0 = Release|Any CPU + {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -437,6 +449,8 @@ Global {8457B68C-CC86-4A3F-8559-C1AE199EC366} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {3892C83E-7F5D-41DF-A88C-4854EAD38856} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} + {0E7983BB-2602-421E-8B37-332E52870A10} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} + {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} diff --git a/dotnet/Directory.Packages.props b/dotnet/Directory.Packages.props index 1e84c0badb2f..d0131825aab4 100644 --- a/dotnet/Directory.Packages.props +++ b/dotnet/Directory.Packages.props @@ -45,6 +45,7 @@ + @@ -83,6 +84,7 @@ + @@ -125,7 +127,6 @@ - \ No newline at end of file diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentsMetadata.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentsMetadata.cs new file mode 100644 index 000000000000..b3812d2e47cc --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentsMetadata.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentsMetadata.cs + +using System.Collections.Concurrent; +using Google.Protobuf.Reflection; + +namespace Microsoft.AutoGen.Core; + +/// +/// Represents a collection of event types and their associated metadata. +/// +public sealed class AgentsMetadata +{ + /// + /// Initializes a new instance of the class. + /// + /// The type registry containing protobuf type information. + /// A dictionary mapping event names to their corresponding types. + /// A dictionary mapping types to a set of event names associated with those types. + public AgentsMetadata(TypeRegistry typeRegistry, Dictionary types, Dictionary> eventsMap, Dictionary> topicsMap) + { + TypeRegistry = typeRegistry; + _types = new(types); + _eventsMap = new(eventsMap); + _topicsMap = new(topicsMap); + } + + /// + /// Gets the type registry containing protobuf type information. + /// + public TypeRegistry TypeRegistry { get; } + + private ConcurrentDictionary _types; + + private ConcurrentDictionary> _eventsMap; + private ConcurrentDictionary> _topicsMap; + + /// + /// Checks if a given type handles a specific event name. + /// + /// The type to check. + /// The event name to check. + /// true if the type handles the event name; otherwise, false. + public bool CheckIfTypeHandles(Type type, string eventName) + { + if (_eventsMap.TryGetValue(type, out var events)) + { + return events.Contains(eventName); + } + return false; + } + + /// + /// Gets the event type by its name. + /// + /// The name of the event type. + /// The event type if found; otherwise, null. + public Type? GetEventTypeByName(string type) + { + if (_types.TryGetValue(type, out var eventType)) + { + return eventType; + } + return null; + } + + public HashSet? GetEventsForAgent(Type agent) + { + if (_eventsMap.TryGetValue(agent, out var events)) + { + return events; + } + return null; + } + + public HashSet? GetTopicsForAgent(Type agent) + { + if (_topicsMap.TryGetValue(agent, out var topics)) + { + return topics; + } + return null; + } +} + diff --git a/dotnet/src/Microsoft.AutoGen/Contracts/TopicSubscriptionAttribute.cs b/dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs similarity index 100% rename from dotnet/src/Microsoft.AutoGen/Contracts/TopicSubscriptionAttribute.cs rename to dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 2d63ab0870ca..30e316aa389b 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -28,8 +28,7 @@ public sealed class GrpcGateway : BackgroundService, IGateway private readonly ConcurrentDictionary<(string Type, string Key), GrpcWorkerConnection> _agentDirectory = new(); // RPC private readonly ConcurrentDictionary<(GrpcWorkerConnection, string), TaskCompletionSource> _pendingRequests = new(); - // InMemory Message Queue - + public int WorkersCount => _workers.Count; public GrpcGateway(IClusterClient clusterClient, ILogger logger) { _logger = logger; diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index ca4ffbb30c3e..a922f23c8e70 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -7,7 +7,7 @@ namespace Microsoft.AutoGen.Runtime.Grpc; // gRPC service which handles communication between the agent worker and the cluster. -internal sealed class GrpcGatewayService : AgentRpc.AgentRpcBase +public sealed class GrpcGatewayService : AgentRpc.AgentRpcBase { private readonly GrpcGateway Gateway; public GrpcGatewayService(GrpcGateway gateway) diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs new file mode 100644 index 000000000000..507809fc3e5a --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -0,0 +1,171 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// GrpcGatewayServiceTests.cs + +using FluentAssertions; +using Microsoft.AutoGen.Contracts; +using Microsoft.AutoGen.Core; +using Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; +using Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Orleans; +using Microsoft.Extensions.Logging; +using Moq; +using Tests.Events; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests; +[Collection(ClusterCollection.Name)] +public class GrpcGatewayServiceTests +{ + private readonly ClusterFixture _fixture; + + public GrpcGatewayServiceTests(ClusterFixture fixture) + { + _fixture = fixture; + } + // Test broadcast Event + [Fact] + public async Task Test_OpenChannel() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + using var client = new TestGrpcClient(); + + gateway.WorkersCount.Should().Be(0); + await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); + gateway.WorkersCount.Should().Be(1); + } + + [Fact] + public async Task Test_Message_Exchange_Through_Gateway() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + using var client = new TestGrpcClient(); + + var assembly = typeof(PBAgent).Assembly; + var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); + + await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); + var responseMessage = await client.ReadNext(); + + var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; + + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), connectionId), client.CallContext); + + var inputEvent = new NewMessageReceived { Message = $"Start-{connectionId}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); + + client.AddMessage(new Message { CloudEvent = inputEvent }); + var newMessageReceived = await client.ReadNext(); + newMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(NewMessageReceived))); + newMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); + + // Simulate an agent, by publishing a new message in the request stream + var helloEvent = new Hello { Message = $"Hello test-{connectionId}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); + client.AddMessage(new Message { CloudEvent = helloEvent }); + + var helloMessageReceived = await client.ReadNext(); + helloMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(Hello))); + helloMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); + } + + [Fact] + public async Task Test_Message_Goes_To_Right_Worker() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + using var client = new TestGrpcClient(); + + var assembly = typeof(PBAgent).Assembly; + var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); + + await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); + var responseMessage = await client.ReadNext(); + + var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; + + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), connectionId), client.CallContext); + + } + + [Fact] + public async Task Test_RegisterAgent_Should_Succeed() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + using var client = new TestGrpcClient(); + + var assembly = typeof(PBAgent).Assembly; + var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); + + await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); + var responseMessage = await client.ReadNext(); + + var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; + + var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); + response.Success.Should().BeTrue(); + } + + [Fact] + public async Task Test_RegisterAgent_Should_Fail_For_Wrong_ConnectionId() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + using var client = new TestGrpcClient(); + + var assembly = typeof(PBAgent).Assembly; + var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); + + var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), "faulty_connection_id"), client.CallContext); + response.Success.Should().BeFalse(); + } + + [Fact] + public async Task Test_SaveState() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + var callContext = TestServerCallContext.Create(); + + var response = await service.SaveState(new AgentState { AgentId = new AgentId { Key = "", Type = "" } }, callContext); + + response.Should().NotBeNull(); + } + + [Fact] + public async Task Test_GetState() + { + var logger = Mock.Of>(); + var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); + var service = new GrpcGatewayService(gateway); + var callContext = TestServerCallContext.Create(); + + var response = await service.GetState(new AgentId { Key = "", Type = "" }, callContext); + + response.Should().NotBeNull(); + } + + private RegisterAgentTypeRequest CreateRegistrationRequest(AgentsMetadata eventTypes, Type type, string requestId) + { + var registration = new RegisterAgentTypeRequest + { + Type = type.Name, + RequestId = requestId + }; + registration.Events.AddRange(eventTypes.GetEventsForAgent(type)?.ToList()); + registration.Topics.AddRange(eventTypes.GetTopicsForAgent(type)?.ToList()); + + return registration; + } + + private string GetFullName(Type type) + { + return ReflectionHelper.GetMessageDescriptor(type)!.FullName; + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestAsyncStreamReader.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestAsyncStreamReader.cs new file mode 100644 index 000000000000..4f26711d149f --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestAsyncStreamReader.cs @@ -0,0 +1,69 @@ +#pragma warning disable IDE0073 +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Threading.Channels; +using Grpc.Core; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; + +public class TestAsyncStreamReader : IDisposable, IAsyncStreamReader + where T : class +{ + private readonly Channel _channel; + private readonly ServerCallContext _serverCallContext; + + public T Current { get; private set; } = null!; + + public TestAsyncStreamReader(ServerCallContext serverCallContext) + { + _channel = Channel.CreateUnbounded(); + _serverCallContext = serverCallContext; + } + + public void AddMessage(T message) + { + if (!_channel.Writer.TryWrite(message)) + { + throw new InvalidOperationException("Unable to write message."); + } + } + + public void Complete() + { + _channel.Writer.Complete(); + } + + public async Task MoveNext(CancellationToken cancellationToken) + { + _serverCallContext.CancellationToken.ThrowIfCancellationRequested(); + + if (await _channel.Reader.WaitToReadAsync(cancellationToken) && + _channel.Reader.TryRead(out var message)) + { + Current = message; + return true; + } + else + { + Current = null!; + return false; + } + } + + public void Dispose() + { + Complete(); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs new file mode 100644 index 000000000000..78724a43bf45 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// TestGrpcClient.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; +internal sealed class TestGrpcClient: IDisposable +{ + public TestAsyncStreamReader RequestStream { get; } + public TestServerStreamWriter ResponseStream { get; } + public TestServerCallContext CallContext { get; } + + public TestGrpcClient() + { + CallContext = TestServerCallContext.Create(); + RequestStream = new TestAsyncStreamReader(CallContext); + ResponseStream = new TestServerStreamWriter(CallContext); + } + + public async Task ReadNext() + { + var response = await ResponseStream.ReadNextAsync(); + return response!; + } + + public void AddMessage(Message message) + { + RequestStream.AddMessage(message); + } + + public void Dispose() + { + RequestStream.Dispose(); + ResponseStream.Dispose(); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerCallContext.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerCallContext.cs new file mode 100644 index 000000000000..47f25155602d --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerCallContext.cs @@ -0,0 +1,73 @@ +#pragma warning disable IDE0073 +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Grpc.Core; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; + +public class TestServerCallContext : ServerCallContext +{ + private readonly Metadata _requestHeaders; + private readonly CancellationToken _cancellationToken; + private readonly Metadata _responseTrailers; + private readonly AuthContext _authContext; + private readonly Dictionary _userState; + private WriteOptions? _writeOptions; + + public Metadata? ResponseHeaders { get; private set; } + + private TestServerCallContext(Metadata requestHeaders, CancellationToken cancellationToken) + { + _requestHeaders = requestHeaders; + _cancellationToken = cancellationToken; + _responseTrailers = new Metadata(); + _authContext = new AuthContext(string.Empty, new Dictionary>()); + _userState = new Dictionary(); + } + + protected override string MethodCore => "MethodName"; + protected override string HostCore => "HostName"; + protected override string PeerCore => "PeerName"; + protected override DateTime DeadlineCore { get; } + protected override Metadata RequestHeadersCore => _requestHeaders; + protected override CancellationToken CancellationTokenCore => _cancellationToken; + protected override Metadata ResponseTrailersCore => _responseTrailers; + protected override Status StatusCore { get; set; } + protected override WriteOptions? WriteOptionsCore { get => _writeOptions; set { _writeOptions = value; } } + protected override AuthContext AuthContextCore => _authContext; + + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions? options) + { + throw new NotImplementedException(); + } + + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) + { + if (ResponseHeaders != null) + { + throw new InvalidOperationException("Response headers have already been written."); + } + + ResponseHeaders = responseHeaders; + return Task.CompletedTask; + } + + protected override IDictionary UserStateCore => _userState; + + public static TestServerCallContext Create(Metadata? requestHeaders = null, CancellationToken cancellationToken = default) + { + return new TestServerCallContext(requestHeaders ?? new Metadata(), cancellationToken); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerStreamWriter.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerStreamWriter.cs new file mode 100644 index 000000000000..ca2aeab2e410 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestServerStreamWriter.cs @@ -0,0 +1,86 @@ +#pragma warning disable IDE0073 +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Threading.Channels; +using Grpc.Core; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; + +public class TestServerStreamWriter : IDisposable, IServerStreamWriter where T : class +{ + private readonly ServerCallContext _serverCallContext; + private readonly Channel _channel; + + public WriteOptions? WriteOptions { get; set; } + + public TestServerStreamWriter(ServerCallContext serverCallContext) + { + _channel = Channel.CreateUnbounded(); + + _serverCallContext = serverCallContext; + } + + public void Complete() + { + _channel.Writer.Complete(); + } + + public IAsyncEnumerable ReadAllAsync() + { + return _channel.Reader.ReadAllAsync(); + } + + public async Task ReadNextAsync() + { + if (await _channel.Reader.WaitToReadAsync()) + { + _channel.Reader.TryRead(out var message); + return message; + } + else + { + return null; + } + } + + public Task WriteAsync(T message, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + if (_serverCallContext.CancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(_serverCallContext.CancellationToken); + } + + if (!_channel.Writer.TryWrite(message)) + { + throw new InvalidOperationException("Unable to write message."); + } + + return Task.CompletedTask; + } + + public Task WriteAsync(T message) + { + return WriteAsync(message, CancellationToken.None); + } + + public void Dispose() + { + Complete(); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterCollection.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterCollection.cs new file mode 100644 index 000000000000..d61dc7b21c50 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterCollection.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// ClusterCollection.cs + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Orleans; + +[CollectionDefinition(Name)] +public sealed class ClusterCollection : ICollectionFixture +{ + public const string Name = nameof(ClusterCollection); +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterFixture.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterFixture.cs new file mode 100644 index 000000000000..9db2f7f654d4 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/ClusterFixture.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// ClusterFixture.cs + +using Orleans.TestingHost; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Orleans; + +public sealed class ClusterFixture : IDisposable +{ + public ClusterFixture() + { + var builder = new TestClusterBuilder(); + builder.AddSiloBuilderConfigurator(); + Cluster = builder.Build(); + Cluster.Deploy(); + + } + public TestCluster Cluster { get; } + + void IDisposable.Dispose() => Cluster.StopAllSilos(); +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs new file mode 100644 index 000000000000..fb345777a82b --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SiloBuilderConfigurator.cs + +using Orleans.Serialization; +using Orleans.TestingHost; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Orleans; + +public class SiloBuilderConfigurator : ISiloConfigurator +{ + public void Configure(ISiloBuilder siloBuilder) + { + siloBuilder.ConfigureServices(services => + { + services.AddSerializer(a => a.AddProtobufSerializer()); + }); + siloBuilder.AddMemoryStreams("StreamProvider") + .AddMemoryGrainStorage("PubSubStore") + .AddMemoryGrainStorage("AgentStateStore"); + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj new file mode 100644 index 000000000000..1cdeb3f295e8 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + True + + + + + + + + + + + + + + + + + + diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs new file mode 100644 index 000000000000..fc8260f51d8b --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// TestAgent.cs + +using System.Collections.Concurrent; +using Microsoft.AutoGen.Core; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Tests.Events; + +namespace Microsoft.AutoGen.Runtime.Grpc.Tests; + +[TopicSubscription("gh-gh-gh")] +public class PBAgent([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes, ILogger? logger = null) + : Agent(eventTypes, logger) + , IHandle + , IHandle +{ + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) + { + ReceivedMessages[AgentId.Key] = item.Message; + var hello = new Hello { Message = item.Message }; + await PublishEventAsync(hello); + } + public Task Handle(GoodBye item, CancellationToken cancellationToken) + { + _logger.LogInformation($"Received GoodBye message {item.Message}"); + return Task.CompletedTask; + } + + public static ConcurrentDictionary ReceivedMessages { get; private set; } = new(); +} + +[TopicSubscription("gh-gh-gh")] +public class GMAgent([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes, ILogger? logger = null) + : Agent(eventTypes, logger) + , IHandle +{ + public async Task Handle(Hello item, CancellationToken cancellationToken) + { + _logger.LogInformation($"Received Hello message {item.Message}"); + ReceivedMessages[AgentId.Key] = item.Message; + await PublishEventAsync(new GoodBye { Message = "" }); + } + + public static ConcurrentDictionary ReceivedMessages { get; private set; } = new(); +} diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj b/dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj new file mode 100644 index 000000000000..45b3dcc45309 --- /dev/null +++ b/dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto b/dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto new file mode 100644 index 000000000000..cb68d45e7550 --- /dev/null +++ b/dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto @@ -0,0 +1,43 @@ +syntax = "proto3"; + +package tests; + +option csharp_namespace = "Tests.Events"; +message TextMessage { + string message = 1; + string source = 2; +} +message Hello { + string message = 1; +} +message InputProcessed { + string route = 1; +} +message Output { + string message = 1; +} +message OutputWritten { + string route = 1; +} +message IOError { + string message = 1; +} +message NewMessageReceived { + string message = 1; +} +message ResponseGenerated { + string response = 1; +} +message GoodBye { + string message = 1; +} +message MessageStored { + string message = 1; +} +message ConversationClosed { + string user_id = 1; + string user_message = 2; +} +message Shutdown { + string message = 1; +} From 56e47cffa88c6a25f69548cf6f184ebe556f0c91 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 17 Dec 2024 14:48:45 -0800 Subject: [PATCH 002/110] wip working on grpcgateway --- .../Runtime.Grpc/Abstractions/IAgentGrain.cs | 10 + .../Runtime.Grpc/Abstractions/IGateway.cs | 16 ++ .../Runtime.Grpc/Abstractions/IRegistry.cs | 85 +++++++ .../Abstractions/IRegistryGrain.cs | 10 + .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 111 +++++---- .../Runtime.Grpc/Services/IGateway.cs | 14 -- .../Services/Orleans/AgentsRegistry.cs | 225 ++++++++++++++++++ .../Services/Orleans/AgentsRegistryState.cs | 12 + .../Services/Orleans/IRegistryGrain.cs | 15 -- .../AddSubscriptionRequestSurrogate.cs | 39 +++ .../AddSubscriptionResponseSurrogate.cs | 41 ++++ .../Orleans/Surrogates/AgentIdSurrogate.cs | 38 +++ .../Orleans/Surrogates/AgentStateSurrogate.cs | 56 +++++ .../Orleans/Surrogates/CloudEventSurrogate.cs | 46 ++++ .../RegisterAgentTypeRequestSurrogate.cs | 48 ++++ .../RegisterAgentTypeResponseSurrogate.cs | 41 ++++ .../Orleans/Surrogates/RpcRequestSurrogate.cs | 54 +++++ .../Surrogates/RpcResponseSurrogate.cs | 46 ++++ .../Surrogates/TypePrefixSubscription.cs | 36 +++ .../Orleans/Surrogates/TypeSubscription.cs | 36 +++ 20 files changed, 905 insertions(+), 74 deletions(-) create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IAgentGrain.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs delete mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/IGateway.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs delete mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/IRegistryGrain.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentIdSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/CloudEventSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeResponseSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcRequestSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcResponseSurrogate.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IAgentGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IAgentGrain.cs new file mode 100644 index 000000000000..947b6b0cbc0a --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IAgentGrain.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// IAgentGrain.cs + +namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; + +internal interface IAgentGrain : IGrainWithStringKey +{ + ValueTask ReadStateAsync(); + ValueTask WriteStateAsync(Contracts.AgentState state, string eTag); +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs new file mode 100644 index 000000000000..dd7263729378 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// IGateway.cs +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; + +public interface IGateway : IGrainObserver +{ + ValueTask InvokeRequest(RpcRequest request); + ValueTask BroadcastEvent(CloudEvent evt); + ValueTask StoreAsync(Contracts.AgentState value); + ValueTask ReadAsync(AgentId agentId); + ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request); + ValueTask AddSubscriptionAsync(AddSubscriptionRequest request); + Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs new file mode 100644 index 000000000000..ffb053956ffc --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// IRegistry.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; + +/// +/// Interface for managing agent registration, placement, and subscriptions. +/// +public interface IRegistry +{ + /// + /// Gets or places an agent based on the provided agent ID. + /// + /// The ID of the agent. + /// A tuple containing the worker and a boolean indicating if it's a new placement. + ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId); + + /// + /// Removes a worker from the registry. + /// + /// The worker to remove. + /// A task representing the asynchronous operation. + ValueTask RemoveWorker(IGateway worker); + + /// + /// Registers a new agent type with the specified worker. + /// + /// The request containing agent type details. + /// The worker to register the agent type with. + /// A task representing the asynchronous operation. + ValueTask RegisterAgentType(RegisterAgentTypeRequest request, IGateway worker); + + /// + /// Adds a new worker to the registry. + /// + /// The worker to add. + /// A task representing the asynchronous operation. + ValueTask AddWorker(IGateway worker); + + /// + /// Unregisters an agent type from the specified worker. + /// + /// The type of the agent to unregister. + /// The worker to unregister the agent type from. + /// A task representing the asynchronous operation. + ValueTask UnregisterAgentType(string type, IGateway worker); + + /// + /// Gets a compatible worker for the specified agent type. + /// + /// The type of the agent. + /// A task representing the asynchronous operation, with the compatible worker as the result. + ValueTask GetCompatibleWorker(string type); + + /// + /// Gets a list of agents subscribed to and handling the specified topic and event type. + /// + /// The topic to check subscriptions for. + /// The event type to check subscriptions for. + /// A task representing the asynchronous operation, with the list of agent IDs as the result. + ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType); + + /// + /// Subscribes an agent to a topic. + /// + /// The subscription request. + /// A task representing the asynchronous operation. + ValueTask SubscribeAsync(AddSubscriptionRequest request); + + /// + /// Unsubscribes an agent from a topic. + /// + /// The unsubscription request. + /// A task representing the asynchronous operation. + ValueTask UnsubscribeAsync(AddSubscriptionRequest request); // TODO: This should have its own request type. + + /// + /// Gets the subscriptions for a specified agent type. + /// + /// The type of the agent. + /// A task representing the asynchronous operation, with the subscriptions as the result. + ValueTask>> GetSubscriptions(string agentType); +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs new file mode 100644 index 000000000000..2f48b051b38b --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// IRegistryGrain.cs + +namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; + +/// +/// Orleans specific interface, needed to mark the key +/// +public interface IRegistryGrain : IRegistry, IGrainWithIntegerKey +{ } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 30e316aa389b..146e7a8e257d 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using Grpc.Core; using Microsoft.AutoGen.Contracts; +using Microsoft.AutoGen.Runtime.Grpc.Abstractions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -14,13 +15,13 @@ public sealed class GrpcGateway : BackgroundService, IGateway private static readonly TimeSpan s_agentResponseTimeout = TimeSpan.FromSeconds(30); private readonly ILogger _logger; private readonly IClusterClient _clusterClient; - private readonly ConcurrentDictionary _agentState = new(); + //private readonly ConcurrentDictionary _agentState = new(); private readonly IRegistryGrain _gatewayRegistry; - private readonly ISubscriptionsGrain _subscriptions; private readonly IGateway _reference; // The agents supported by each worker process. private readonly ConcurrentDictionary> _supportedAgentTypes = []; public readonly ConcurrentDictionary _workers = new(); + internal readonly ConcurrentDictionary _workersByConnection = new(); private readonly ConcurrentDictionary _subscriptionsByAgentType = new(); private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); @@ -35,7 +36,69 @@ public GrpcGateway(IClusterClient clusterClient, ILogger logger) _clusterClient = clusterClient; _reference = clusterClient.CreateObjectReference(this); _gatewayRegistry = clusterClient.GetGrain(0); - _subscriptions = clusterClient.GetGrain(0); + } + public async ValueTask InvokeRequest(RpcRequest request, CancellationToken cancellationToken = default) + { + var agentId = (request.Target.Type, request.Target.Key); + if (!_agentDirectory.TryGetValue(agentId, out var connection) || connection.Completion.IsCompleted == true) + { + // Activate the agent on a compatible worker process. + if (_supportedAgentTypes.TryGetValue(request.Target.Type, out var workers)) + { + connection = workers[Random.Shared.Next(workers.Count)]; + _agentDirectory[agentId] = connection; + } + else + { + return new(new RpcResponse { Error = "Agent not found." }); + } + } + // Proxy the request to the agent. + var originalRequestId = request.RequestId; + var newRequestId = Guid.NewGuid().ToString(); + var completion = _pendingRequests[(connection, newRequestId)] = new(TaskCreationOptions.RunContinuationsAsynchronously); + request.RequestId = newRequestId; + await connection.ResponseStream.WriteAsync(new Message { Request = request }, cancellationToken).ConfigureAwait(false); + // Wait for the response and send it back to the caller. + var response = await completion.Task.WaitAsync(s_agentResponseTimeout); + response.RequestId = originalRequestId; + return response; + } + public async ValueTask StoreAsync(AgentState value) + { + _ = value.AgentId ?? throw new ArgumentNullException(nameof(value.AgentId)); + var agentState = _clusterClient.GetGrain($"{value.AgentId.Type}:{value.AgentId.Key}"); + await agentState.WriteStateAsync(value, value.ETag); + } + public async ValueTask ReadAsync(AgentId agentId) + { + var agentState = _clusterClient.GetGrain($"{agentId.Type}:{agentId.Key}"); + return await agentState.ReadStateAsync(); + } + public async ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request) + { + try + { + var connection = _workersByConnection[request.RequestId]; + connection.AddSupportedType(request.Type); + _supportedAgentTypes.GetOrAdd(request.Type, _ => []).Add(connection); + + await _gatewayRegistry.RegisterAgentType(request, _reference).ConfigureAwait(true); + return new RegisterAgentTypeResponse + { + Success = true, + RequestId = request.RequestId + }; + } + catch (Exception ex) + { + return new RegisterAgentTypeResponse + { + Success = false, + RequestId = request.RequestId, + Error = ex.Message + }; + } } public async ValueTask BroadcastEvent(CloudEvent evt) { @@ -253,20 +316,6 @@ internal Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, _workers[workerProcess] = workerProcess; return workerProcess.Completion; } - public async ValueTask StoreAsync(AgentState value) - { - var agentId = value.AgentId ?? throw new ArgumentNullException(nameof(value.AgentId)); - _agentState[agentId.Key] = value; - } - - public async ValueTask ReadAsync(AgentId agentId) - { - if (_agentState.TryGetValue(agentId.Key, out var state)) - { - return state; - } - return new AgentState { AgentId = agentId }; - } internal void OnRemoveWorkerProcess(GrpcWorkerConnection workerProcess) { _workers.TryRemove(workerProcess, out _); @@ -287,34 +336,6 @@ internal void OnRemoveWorkerProcess(GrpcWorkerConnection workerProcess) } } } - public async ValueTask InvokeRequest(RpcRequest request, CancellationToken cancellationToken = default) - { - (string Type, string Key) agentId = (request.Target.Type, request.Target.Key); - if (!_agentDirectory.TryGetValue(agentId, out var connection) || connection.Completion.IsCompleted) - { - // Activate the agent on a compatible worker process. - if (_supportedAgentTypes.TryGetValue(request.Target.Type, out var workers)) - { - connection = workers[Random.Shared.Next(workers.Count)]; - _agentDirectory[agentId] = connection; - } - else - { - return new(new RpcResponse { Error = "Agent not found." }); - } - } - // Proxy the request to the agent. - var originalRequestId = request.RequestId; - var newRequestId = Guid.NewGuid().ToString(); - var completion = _pendingRequests[(connection, newRequestId)] = new(TaskCreationOptions.RunContinuationsAsynchronously); - request.RequestId = newRequestId; - await connection.ResponseStream.WriteAsync(new Message { Request = request }, cancellationToken).ConfigureAwait(false); - // Wait for the response and send it back to the caller. - var response = await completion.Task.WaitAsync(s_agentResponseTimeout); - response.RequestId = originalRequestId; - return response; - } - async ValueTask IGateway.InvokeRequest(RpcRequest request) { return await this.InvokeRequest(request).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/IGateway.cs deleted file mode 100644 index 463ae4e532af..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/IGateway.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// IGateway.cs -using Microsoft.AutoGen.Contracts; - -namespace Microsoft.AutoGen.Runtime.Grpc; - -public interface IGateway : IGrainObserver -{ - ValueTask InvokeRequest(RpcRequest request); - ValueTask BroadcastEvent(CloudEvent evt); - ValueTask StoreAsync(AgentState value); - ValueTask ReadAsync(AgentId agentId); - Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); -} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs new file mode 100644 index 000000000000..30cd40ad35a4 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs @@ -0,0 +1,225 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentsRegistry.cs + +using Microsoft.AutoGen.Contracts; +using Microsoft.AutoGen.Runtime.Grpc.Abstractions; + +namespace Microsoft.AutoGen.Runtime.Grpc; +internal sealed class AgentsRegistry([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IGrainRegistry +{ + // TODO: use persistent state for some of these or (better) extend Orleans to implement some of this natively. + private readonly Dictionary _workerStates = new(); + private readonly Dictionary> _supportedAgentTypes = []; + private readonly Dictionary<(string Type, string Key), IGateway> _agentDirectory = []; + private readonly TimeSpan _agentTimeout = TimeSpan.FromMinutes(1); + + public override Task OnActivateAsync(CancellationToken cancellationToken) + { + this.RegisterGrainTimer(static state => state.PurgeInactiveWorkers(), this, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); + return base.OnActivateAsync(cancellationToken); + } + + public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) + { + // get all agent types that are subscribed to the topic + var subscribedAgents = state.State.TopicToAgentTypesMap[topic]; + // get all agent types that are handling the event + var handlingAgents = state.State.EventsToAgentTypesMap[eventType]; + // return the intersection of the two sets + return new(subscribedAgents.Intersect(handlingAgents).ToList()); + } + public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) + { + // TODO: Clarify the logic + bool isNewPlacement; + if (!_agentDirectory.TryGetValue((agentId.Type, agentId.Key), out var worker) || !_workerStates.ContainsKey(worker)) + { + worker = GetCompatibleWorkerCore(agentId.Type); + if (worker is not null) + { + // New activation. + _agentDirectory[(agentId.Type, agentId.Key)] = worker; + isNewPlacement = true; + } + else + { + // No activation, and failed to place. + isNewPlacement = false; + } + } + else + { + // Existing activation. + isNewPlacement = false; + } + return new((worker, isNewPlacement)); + } + public ValueTask RemoveWorker(IGateway worker) + { + if (_workerStates.Remove(worker, out var state)) + { + foreach (var type in state.SupportedTypes) + { + if (_supportedAgentTypes.TryGetValue(type, out var workers)) + { + workers.Remove(worker); + } + } + } + return ValueTask.CompletedTask; + } + public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, IGateway worker) + { + if (!_supportedAgentTypes.TryGetValue(registration.Type, out var supportedAgentTypes)) + { + supportedAgentTypes = _supportedAgentTypes[registration.Type] = []; + } + + if (!supportedAgentTypes.Contains(worker)) + { + supportedAgentTypes.Add(worker); + } + + var workerState = GetOrAddWorker(worker); + workerState.SupportedTypes.Add(registration.Type); + state.State.AgentsToEventsMap[registration.Type] = new HashSet(registration.Events); + state.State.AgentsToTopicsMap[registration.Type] = new HashSet(registration.Topics); + + // construct the inverse map for topics and agent types + foreach (var topic in registration.Topics) + { + if (!state.State.TopicToAgentTypesMap.TryGetValue(topic, out var topicSet)) + { + topicSet = new HashSet(); + state.State.TopicToAgentTypesMap[topic] = topicSet; + } + + topicSet.Add(registration.Type); + } + + // construct the inverse map for events and agent types + foreach (var evt in registration.Events) + { + if (!state.State.EventsToAgentTypesMap.TryGetValue(evt, out var eventSet)) + { + eventSet = new HashSet(); + state.State.EventsToAgentTypesMap[evt] = eventSet; + } + + eventSet.Add(registration.Type); + } + await state.WriteStateAsync().ConfigureAwait(false); + } + public ValueTask AddWorker(IGateway worker) + { + GetOrAddWorker(worker); + return ValueTask.CompletedTask; + } + public ValueTask UnregisterAgentType(string type, IGateway worker) + { + if (_workerStates.TryGetValue(worker, out var state)) + { + state.SupportedTypes.Remove(type); + } + + if (_supportedAgentTypes.TryGetValue(type, out var workers)) + { + workers.Remove(worker); + } + return ValueTask.CompletedTask; + } + private Task PurgeInactiveWorkers() + { + foreach (var (worker, state) in _workerStates) + { + if (DateTimeOffset.UtcNow - state.LastSeen > _agentTimeout) + { + _workerStates.Remove(worker); + foreach (var type in state.SupportedTypes) + { + if (_supportedAgentTypes.TryGetValue(type, out var workers)) + { + workers.Remove(worker); + } + } + } + } + + return Task.CompletedTask; + } + + private WorkerState GetOrAddWorker(IGateway worker) + { + if (!_workerStates.TryGetValue(worker, out var workerState)) + { + workerState = _workerStates[worker] = new(); + } + + workerState.LastSeen = DateTimeOffset.UtcNow; + return workerState; + } + + public ValueTask GetCompatibleWorker(string type) => new(GetCompatibleWorkerCore(type)); + + private IGateway? GetCompatibleWorkerCore(string type) + { + if (_supportedAgentTypes.TryGetValue(type, out var workers)) + { + // Return a random compatible worker. + return workers[Random.Shared.Next(workers.Count)]; + } + + return null; + } + + public async ValueTask SubscribeAsync(AddSubscriptionRequest sub) + { + switch (sub.Subscription.SubscriptionCase) + { + case Subscription.SubscriptionOneofCase.TypePrefixSubscription: + break; + case Subscription.SubscriptionOneofCase.TypeSubscription: + { + // add the topic to the set of topics for the agent type + state.State.AgentsToTopicsMap.TryGetValue(sub.Subscription.TypeSubscription.AgentType, out var topics); + if (topics is null) + { + topics = new HashSet(); + state.State.AgentsToTopicsMap[sub.Subscription.TypeSubscription.AgentType] = topics; + } + topics.Add(sub.Subscription.TypeSubscription.TopicType); + + // add the agent type to the set of agent types for the topic + state.State.TopicToAgentTypesMap.TryGetValue(sub.Subscription.TypeSubscription.TopicType, out var agents); + if (agents is null) + { + agents = new HashSet(); + state.State.TopicToAgentTypesMap[sub.Subscription.TypeSubscription.TopicType] = agents; + } + + agents.Add(sub.Subscription.TypeSubscription.AgentType); + + break; + } + default: + throw new InvalidOperationException("Invalid subscription type"); + } + await state.WriteStateAsync().ConfigureAwait(false); + } + public async ValueTask UnsubscribeAsync(AddSubscriptionRequest request) + { + throw new NotImplementedException(); + } + + public ValueTask>> GetSubscriptions(string agentType) + { + throw new NotImplementedException(); + } + + private sealed class WorkerState + { + public HashSet SupportedTypes { get; set; } = []; + public DateTimeOffset LastSeen { get; set; } + } +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs new file mode 100644 index 000000000000..122821270f65 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentsRegistryState.cs + +namespace Microsoft.AutoGen.Runtime.Grpc; + +public class AgentsRegistryState +{ + public Dictionary> AgentsToEventsMap { get; set; } = []; + public Dictionary> AgentsToTopicsMap { get; set; } = []; + public Dictionary> TopicToAgentTypesMap { get; set; } = []; + public Dictionary> EventsToAgentTypesMap { get; set; } = []; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/IRegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/IRegistryGrain.cs deleted file mode 100644 index 1c817add3074..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/IRegistryGrain.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// IRegistryGrain.cs -using Microsoft.AutoGen.Contracts; - -namespace Microsoft.AutoGen.Runtime.Grpc; - -public interface IRegistryGrain : IGrainWithIntegerKey -{ - ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId); - ValueTask RemoveWorker(IGateway worker); - ValueTask RegisterAgentType(string type, IGateway worker); - ValueTask AddWorker(IGateway worker); - ValueTask UnregisterAgentType(string type, IGateway worker); - ValueTask GetCompatibleWorker(string type); -} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs new file mode 100644 index 000000000000..e732c3ffc982 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AddSubscriptionRequestSurrogate.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct AddSubscriptionRequestSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public Subscription Subscription; +} + +[RegisterConverter] +public sealed class AddSubscriptionRequestSurrogateConverter : + IConverter +{ + public AddSubscriptionRequest ConvertFromSurrogate( + in AddSubscriptionRequestSurrogate surrogate) + { + var request = new AddSubscriptionRequest() + { + RequestId = surrogate.RequestId, + Subscription = surrogate.Subscription + }; + return request; + } + + public AddSubscriptionRequestSurrogate ConvertToSurrogate( + in AddSubscriptionRequest value) => + new AddSubscriptionRequestSurrogate + { + RequestId = value.RequestId, + Subscription = value.Subscription + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs new file mode 100644 index 000000000000..d35a3c5f6f89 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AddSubscriptionResponseSurrogate.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct AddSubscriptionResponseSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public bool Success; + [Id(2)] + public string Error; +} + +[RegisterConverter] +public sealed class AddSubscriptionResponseSurrogateConverter : + IConverter +{ + public AddSubscriptionResponse ConvertFromSurrogate( + in AddSubscriptionResponseSurrogate surrogate) => + new AddSubscriptionResponse + { + RequestId = surrogate.RequestId, + Success = surrogate.Success, + Error = surrogate.Error + }; + + public AddSubscriptionResponseSurrogate ConvertToSurrogate( + in AddSubscriptionResponse value) => + new AddSubscriptionResponseSurrogate + { + RequestId = value.RequestId, + Success = value.Success, + Error = value.Error + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentIdSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentIdSurrogate.cs new file mode 100644 index 000000000000..ddef9e997575 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentIdSurrogate.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentIdSurrogate.cs + +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentIdSurrogate.cs +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct AgentIdSurrogate +{ + [Id(0)] + public string Key; + [Id(1)] + public string Type; +} + +[RegisterConverter] +public sealed class AgentIdSurrogateConverter : + IConverter +{ + public AgentId ConvertFromSurrogate( + in AgentIdSurrogate surrogate) => + new AgentId + { + Key = surrogate.Key, + Type = surrogate.Type + }; + + public AgentIdSurrogate ConvertToSurrogate( + in AgentId value) => + new AgentIdSurrogate + { + Key = value.Key, + Type = value.Type + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs new file mode 100644 index 000000000000..1b1df59a91bc --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentStateSurrogate.cs + +using Google.Protobuf; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct AgentStateSurrogate +{ + [Id(0)] + public string Id; + [Id(1)] + public string TextData; + [Id(2)] + public ByteString BinaryData; + [Id(3)] + public AgentId AgentId; + [Id(4)] + public string Etag; + [Id(5)] + public ByteString ProtoData; +} + +[RegisterConverter] +public sealed class AgentStateSurrogateConverter : + IConverter +{ + public AgentState ConvertFromSurrogate( + in AgentStateSurrogate surrogate) + { + var agentState = new AgentState + { + AgentId = surrogate.AgentId, + BinaryData = surrogate.BinaryData, + TextData = surrogate.TextData, + ETag = surrogate.Etag + }; + //agentState.ProtoData = surrogate.ProtoData; + return agentState; + } + + + public AgentStateSurrogate ConvertToSurrogate( + in AgentState value) => + new AgentStateSurrogate + { + AgentId = value.AgentId, + BinaryData = value.BinaryData, + TextData = value.TextData, + Etag = value.ETag, + //ProtoData = value.ProtoData.Value + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/CloudEventSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/CloudEventSurrogate.cs new file mode 100644 index 000000000000..7572ec3c31a3 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/CloudEventSurrogate.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// CloudEventSurrogate.cs + +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +// TODO: Add the rest of the properties +[GenerateSerializer] +public struct CloudEventSurrogate +{ + [Id(0)] + public string Id; + [Id(1)] + public string TextData; + [Id(2)] + public ByteString BinaryData; + [Id(3)] + public Any ProtoData; +} + +[RegisterConverter] +public sealed class CloudEventSurrogateConverter : + IConverter +{ + public CloudEvent ConvertFromSurrogate( + in CloudEventSurrogate surrogate) => + new CloudEvent + { + TextData = surrogate.TextData, + BinaryData = surrogate.BinaryData, + Id = surrogate.Id + }; + + public CloudEventSurrogate ConvertToSurrogate( + in CloudEvent value) => + new CloudEventSurrogate + { + TextData = value.TextData, + BinaryData = value.BinaryData, + Id = value.Id, + ProtoData = value.ProtoData + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs new file mode 100644 index 000000000000..5d8b6fd25a03 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RegisterAgentTypeRequestSurrogate.cs + +using Google.Protobuf.Collections; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RegisterAgentTypeRequestSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public string Type; + [Id(2)] + public RepeatedField Events; + [Id(3)] + public RepeatedField Topics; +} + +[RegisterConverter] +public sealed class RegisterAgentTypeRequestSurrogateConverter : + IConverter +{ + public RegisterAgentTypeRequest ConvertFromSurrogate( + in RegisterAgentTypeRequestSurrogate surrogate) + { + var request = new RegisterAgentTypeRequest() + { + RequestId = surrogate.RequestId, + Type = surrogate.Type + }; + request.Events.Add(surrogate.Events); + request.Topics.Add(surrogate.Topics); + return request; + } + + public RegisterAgentTypeRequestSurrogate ConvertToSurrogate( + in RegisterAgentTypeRequest value) => + new RegisterAgentTypeRequestSurrogate + { + RequestId = value.RequestId, + Type = value.Type, + Events = value.Events, + Topics = value.Topics + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeResponseSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeResponseSurrogate.cs new file mode 100644 index 000000000000..6fa73e5e8c3e --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeResponseSurrogate.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RegisterAgentTypeResponseSurrogate.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RegisterAgentTypeResponseSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public bool Success; + [Id(2)] + public string Error; +} + +[RegisterConverter] +public sealed class RegisterAgentTypeResponseSurrogateConverter : + IConverter +{ + public RegisterAgentTypeResponse ConvertFromSurrogate( + in RegisterAgentTypeResponseSurrogate surrogate) => + new RegisterAgentTypeResponse + { + RequestId = surrogate.RequestId, + Success = surrogate.Success, + Error = surrogate.Error + }; + + public RegisterAgentTypeResponseSurrogate ConvertToSurrogate( + in RegisterAgentTypeResponse value) => + new RegisterAgentTypeResponseSurrogate + { + RequestId = value.RequestId, + Success = value.Success, + Error = value.Error + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcRequestSurrogate.cs new file mode 100644 index 000000000000..9791a68d7952 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcRequestSurrogate.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RpcRequestSurrogate.cs + +using Google.Protobuf.Collections; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RpcRequestSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public AgentId Source; + [Id(2)] + public AgentId Target; + [Id(3)] + public string Method; + [Id(4)] + public Payload Payload; + [Id(5)] + public MapField Metadata; +} + +[RegisterConverter] +public sealed class RpcRequestSurrogateConverter : + IConverter +{ + public RpcRequest ConvertFromSurrogate( + in RpcRequestSurrogate surrogate) => + new RpcRequest + { + RequestId = surrogate.RequestId, + Source = surrogate.Source, + Target = surrogate.Target, + Method = surrogate.Method, + Payload = surrogate.Payload, + Metadata = { surrogate.Metadata } + }; + + public RpcRequestSurrogate ConvertToSurrogate( + in RpcRequest value) => + new RpcRequestSurrogate + { + RequestId = value.RequestId, + Source = value.Source, + Target = value.Target, + Method = value.Method, + Payload = value.Payload, + Metadata = value.Metadata + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcResponseSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcResponseSurrogate.cs new file mode 100644 index 000000000000..e5f9fff66405 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RpcResponseSurrogate.cs @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RpcResponseSurrogate.cs + +using Google.Protobuf.Collections; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RpcResponseSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public Payload Payload; + [Id(2)] + public string Error; + [Id(3)] + public MapField Metadata; +} + +[RegisterConverter] +public sealed class RpcResponseurrogateConverter : + IConverter +{ + public RpcResponse ConvertFromSurrogate( + in RpcResponseSurrogate surrogate) => + new RpcResponse + { + RequestId = surrogate.RequestId, + Payload = surrogate.Payload, + Error = surrogate.Error, + Metadata = { surrogate.Metadata } + }; + + public RpcResponseSurrogate ConvertToSurrogate( + in RpcResponse value) => + new RpcResponseSurrogate + { + RequestId = value.RequestId, + Payload = value.Payload, + Error = value.Error, + Metadata = value.Metadata + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs new file mode 100644 index 000000000000..c5427d7bf972 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// TypePrefixSubscription.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct TypePrefixSubscriptionSurrogate +{ + [Id(0)] + public string TopicTypePrefix; + [Id(1)] + public string AgentType; +} + +[RegisterConverter] +public sealed class TypePrefixSubscriptionConverter : + IConverter +{ + public TypePrefixSubscription ConvertFromSurrogate( + in TypePrefixSubscriptionSurrogate surrogate) => + new TypePrefixSubscription + { + TopicTypePrefix = surrogate.TopicTypePrefix, + AgentType = surrogate.AgentType + }; + + public TypePrefixSubscriptionSurrogate ConvertToSurrogate( + in TypePrefixSubscription value) => + new TypePrefixSubscriptionSurrogate + { + TopicTypePrefix = value.TopicTypePrefix, + AgentType = value.AgentType + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs new file mode 100644 index 000000000000..df38462d044a --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// TypeSubscription.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct TypeSubscriptionSurrogate +{ + [Id(0)] + public string TopicType; + [Id(1)] + public string AgentType; +} + +[RegisterConverter] +public sealed class TypeSubscriptionSurrogateConverter : + IConverter +{ + public TypeSubscription ConvertFromSurrogate( + in TypeSubscriptionSurrogate surrogate) => + new TypeSubscription + { + TopicType = surrogate.TopicType, + AgentType = surrogate.AgentType + }; + + public TypeSubscriptionSurrogate ConvertToSurrogate( + in TypeSubscription value) => + new TypeSubscriptionSurrogate + { + TopicType = value.TopicType, + AgentType = value.AgentType + }; +} From 0ac819cda4b7eee1098161530ae1fc23a765c926 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 17 Dec 2024 15:17:20 -0800 Subject: [PATCH 003/110] worker changes --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 86 +++++++++++++------ .../Services/Grpc/GrpcWorkerConnection.cs | 15 ++-- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 146e7a8e257d..aba3f7ff8dcc 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -100,31 +100,26 @@ public async ValueTask RegisterAgentTypeAsync(Registe }; } } - public async ValueTask BroadcastEvent(CloudEvent evt) + public async ValueTask AddSubscriptionAsync(AddSubscriptionRequest request) { - var tasks = new List(_workers.Count); - foreach (var (_, connection) in _supportedAgentTypes) + try { - - tasks.Add(this.SendMessageAsync((IConnection)connection[0], evt, default)); + await _gatewayRegistry.SubscribeAsync(request).ConfigureAwait(true); + return new AddSubscriptionResponse + { + Success = true, + RequestId = request.RequestId + }; } - await Task.WhenAll(tasks).ConfigureAwait(false); - } - //intetionally not static so can be called by some methods implemented in base class - public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) - { - var queue = (GrpcWorkerConnection)connection; - await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); - } - private void DispatchResponse(GrpcWorkerConnection connection, RpcResponse response) - { - if (!_pendingRequests.TryRemove((connection, response.RequestId), out var completion)) + catch (Exception ex) { - _logger.LogWarning("Received response for unknown request."); - return; + return new AddSubscriptionResponse + { + Success = false, + RequestId = request.RequestId, + Error = ex.Message + }; } - // Complete the request. - completion.SetResult(response); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { @@ -149,6 +144,49 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) _logger.LogWarning(exception, "Error removing worker from registry."); } } + internal async Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + { + _logger.LogInformation("Received new connection from {Peer}.", context.Peer); + var workerProcess = new GrpcWorkerConnection(this, requestStream, responseStream, context); + var connectionId = Guid.NewGuid().ToString(); + _workers[workerProcess] = workerProcess; + _workersByConnection[connectionId] = workerProcess; + + var completion = new TaskCompletionSource(); + var _ = Task.Run(() => + { + completion.SetResult(workerProcess.Connect()); + }); + + await completion.Task; + return connectionId; + } + public async ValueTask BroadcastEvent(CloudEvent evt) + { + var tasks = new List(_workers.Count); + foreach (var (_, connection) in _supportedAgentTypes) + { + + tasks.Add(this.SendMessageAsync((IConnection)connection[0], evt, default)); + } + await Task.WhenAll(tasks).ConfigureAwait(false); + } + //intetionally not static so can be called by some methods implemented in base class + public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) + { + var queue = (GrpcWorkerConnection)connection; + await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); + } + private void DispatchResponse(GrpcWorkerConnection connection, RpcResponse response) + { + if (!_pendingRequests.TryRemove((connection, response.RequestId), out var completion)) + { + _logger.LogWarning("Received response for unknown request."); + return; + } + // Complete the request. + completion.SetResult(response); + } //new is intentional... internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Message message) { @@ -309,13 +347,7 @@ private static async Task InvokeRequestDelegate(GrpcWorkerConnection connection, await connection.ResponseStream.WriteAsync(new Message { Response = new RpcResponse { RequestId = request.RequestId, Error = ex.Message } }).ConfigureAwait(false); } } - internal Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) - { - _logger.LogInformation("Received new connection from {Peer}.", context.Peer); - var workerProcess = new GrpcWorkerConnection(this, requestStream, responseStream, context); - _workers[workerProcess] = workerProcess; - return workerProcess.Completion; - } + internal void OnRemoveWorkerProcess(GrpcWorkerConnection workerProcess) { _workers.TryRemove(workerProcess, out _); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs index 315cd81feb1c..00c777953688 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs @@ -10,14 +10,14 @@ namespace Microsoft.AutoGen.Runtime.Grpc; internal sealed class GrpcWorkerConnection : IAsyncDisposable, IConnection { private static long s_nextConnectionId; - private readonly Task _readTask; - private readonly Task _writeTask; + private Task _readTask = Task.CompletedTask; + private Task _writeTask = Task.CompletedTask; private readonly string _connectionId = Interlocked.Increment(ref s_nextConnectionId).ToString(); private readonly object _lock = new(); private readonly HashSet _supportedTypes = []; private readonly GrpcGateway _gateway; private readonly CancellationTokenSource _shutdownCancellationToken = new(); - + public Task Completion { get; private set; } = Task.CompletedTask; public GrpcWorkerConnection(GrpcGateway agentWorker, IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) { _gateway = agentWorker; @@ -25,7 +25,9 @@ public GrpcWorkerConnection(GrpcGateway agentWorker, IAsyncStreamReader ResponseStream = responseStream; ServerCallContext = context; _outboundMessages = Channel.CreateUnbounded(new UnboundedChannelOptions { AllowSynchronousContinuations = true, SingleReader = true, SingleWriter = false }); - + } + public Task Connect() + { var didSuppress = false; if (!ExecutionContext.IsFlowSuppressed()) { @@ -46,7 +48,7 @@ public GrpcWorkerConnection(GrpcGateway agentWorker, IAsyncStreamReader } } - Completion = Task.WhenAll(_readTask, _writeTask); + return Completion = Task.WhenAll(_readTask, _writeTask); } public IAsyncStreamReader RequestStream { get; } @@ -75,9 +77,6 @@ public async Task SendMessage(Message message) { await _outboundMessages.Writer.WriteAsync(message).ConfigureAwait(false); } - - public Task Completion { get; } - public async Task RunReadPump() { await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); From dfc62d4be1d0740aa024e22991d7ed0894fd73eb Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 17 Dec 2024 15:48:07 -0800 Subject: [PATCH 004/110] wip --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 168 ++++++++++-------- 1 file changed, 90 insertions(+), 78 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index aba3f7ff8dcc..7442dbb0fae5 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -24,6 +24,7 @@ public sealed class GrpcGateway : BackgroundService, IGateway internal readonly ConcurrentDictionary _workersByConnection = new(); private readonly ConcurrentDictionary _subscriptionsByAgentType = new(); private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); + private readonly ISubscriptionsGrain _subscriptions; // The mapping from agent id to worker process. private readonly ConcurrentDictionary<(string Type, string Key), GrpcWorkerConnection> _agentDirectory = new(); @@ -36,6 +37,7 @@ public GrpcGateway(IClusterClient clusterClient, ILogger logger) _clusterClient = clusterClient; _reference = clusterClient.CreateObjectReference(this); _gatewayRegistry = clusterClient.GetGrain(0); + _subscriptions = clusterClient.GetGrain(0); } public async ValueTask InvokeRequest(RpcRequest request, CancellationToken cancellationToken = default) { @@ -161,33 +163,10 @@ internal async Task ConnectToWorkerProcess(IAsyncStreamReader r await completion.Task; return connectionId; } - public async ValueTask BroadcastEvent(CloudEvent evt) - { - var tasks = new List(_workers.Count); - foreach (var (_, connection) in _supportedAgentTypes) - { - - tasks.Add(this.SendMessageAsync((IConnection)connection[0], evt, default)); - } - await Task.WhenAll(tasks).ConfigureAwait(false); - } - //intetionally not static so can be called by some methods implemented in base class - public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) + internal async Task SendMessageAsync(GrpcWorkerConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { - var queue = (GrpcWorkerConnection)connection; - await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); - } - private void DispatchResponse(GrpcWorkerConnection connection, RpcResponse response) - { - if (!_pendingRequests.TryRemove((connection, response.RequestId), out var completion)) - { - _logger.LogWarning("Received response for unknown request."); - return; - } - // Complete the request. - completion.SetResult(response); + await connection.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); } - //new is intentional... internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Message message) { _logger.LogInformation("Received message {Message} from connection {Connection}.", message, connection); @@ -214,48 +193,22 @@ internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Mess break; }; } - private async ValueTask RespondBadRequestAsync(GrpcWorkerConnection connection, string error) - { - throw new RpcException(new Status(StatusCode.InvalidArgument, error)); - } - - // agentype:rpc_request={requesting_agent_id} - // {genttype}:rpc_response={request_id} - private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, AddSubscriptionRequest request) + private void DispatchResponse(GrpcWorkerConnection connection, RpcResponse response) { - var topic = ""; - var agentType = ""; - if (request.Subscription.TypePrefixSubscription is not null) - { - topic = request.Subscription.TypePrefixSubscription.TopicTypePrefix; - agentType = request.Subscription.TypePrefixSubscription.AgentType; - } - else if (request.Subscription.TypeSubscription is not null) + if (!_pendingRequests.TryRemove((connection, response.RequestId), out var completion)) { - topic = request.Subscription.TypeSubscription.TopicType; - agentType = request.Subscription.TypeSubscription.AgentType; + _logger.LogWarning("Received response for unknown request id: {RequestId}.", response.RequestId); + return; } - _subscriptionsByAgentType[agentType] = request.Subscription; - _subscriptionsByTopic.GetOrAdd(topic, _ => []).Add(agentType); - await _subscriptions.SubscribeAsync(topic, agentType); - //var response = new AddSubscriptionResponse { RequestId = request.RequestId, Error = "", Success = true }; - Message response = new() - { - AddSubscriptionResponse = new() - { - RequestId = request.RequestId, - Error = "", - Success = true - } - }; - await connection.ResponseStream.WriteAsync(response).ConfigureAwait(false); + // Complete the request. + completion.SetResult(response); } private async ValueTask RegisterAgentTypeAsync(GrpcWorkerConnection connection, RegisterAgentTypeRequest msg) { connection.AddSupportedType(msg.Type); _supportedAgentTypes.GetOrAdd(msg.Type, _ => []).Add(connection); - await _gatewayRegistry.RegisterAgentType(msg.Type, _reference).ConfigureAwait(true); + await _gatewayRegistry.RegisterAgentType(msg, _reference).ConfigureAwait(true); Message response = new() { RegisterAgentTypeResponse = new() @@ -269,12 +222,25 @@ private async ValueTask RegisterAgentTypeAsync(GrpcWorkerConnection connection, } private async ValueTask DispatchEventAsync(CloudEvent evt) { + + var registry = _clusterClient.GetGrain(0); + //intentionally blocking + var targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); + if (targetAgentTypes.Count == 0) + { + _logger.LogWarning("No agents found registered for event {Event}.", evt); + } + else + { + await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); + } + // alternate path // get the event type and then send to all agents that are subscribed to that event type var eventType = evt.Type; // ensure that we get agentTypes as an async enumerable list - try to get the value of agentTypes by topic and then cast it to an async enumerable list if (_subscriptionsByTopic.TryGetValue(eventType, out var agentTypes)) { - await DispatchEventToAgentsAsync(agentTypes, evt); + await DispatchEventToAgentsAsync(agentTypes, evt: evt).ConfigureAwait(false); } // instead of an exact match, we can also check for a prefix match where key starts with the eventType else if (_subscriptionsByTopic.Keys.Any(key => key.StartsWith(eventType))) @@ -295,21 +261,6 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) _logger.LogWarning("No agent types found for event type {EventType}.", eventType); } } - private async ValueTask DispatchEventToAgentsAsync(IEnumerable agentTypes, CloudEvent evt) - { - var tasks = new List(agentTypes.Count()); - foreach (var agentType in agentTypes) - { - if (_supportedAgentTypes.TryGetValue(agentType, out var connections)) - { - foreach (var connection in connections) - { - tasks.Add(this.SendMessageAsync(connection, evt)); - } - } - } - await Task.WhenAll(tasks).ConfigureAwait(false); - } private async ValueTask DispatchRequestAsync(GrpcWorkerConnection connection, RpcRequest request) { var requestId = request.RequestId; @@ -330,10 +281,8 @@ await InvokeRequestDelegate(connection, request, async request => } // Forward the message to the gateway and return the result. return await gateway.InvokeRequest(request).ConfigureAwait(true); - }); - //} + }).ConfigureAwait(false); } - private static async Task InvokeRequestDelegate(GrpcWorkerConnection connection, RpcRequest request, Func> func) { try @@ -347,7 +296,6 @@ private static async Task InvokeRequestDelegate(GrpcWorkerConnection connection, await connection.ResponseStream.WriteAsync(new Message { Response = new RpcResponse { RequestId = request.RequestId, Error = ex.Message } }).ConfigureAwait(false); } } - internal void OnRemoveWorkerProcess(GrpcWorkerConnection workerProcess) { _workers.TryRemove(workerProcess, out _); @@ -368,13 +316,77 @@ internal void OnRemoveWorkerProcess(GrpcWorkerConnection workerProcess) } } } + private static async ValueTask RespondBadRequestAsync(GrpcWorkerConnection connection, string error) + { + throw new RpcException(new Status(StatusCode.InvalidArgument, error)); + } + private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, AddSubscriptionRequest request) + { + var topic = ""; + var agentType = ""; + if (request.Subscription.TypePrefixSubscription is not null) + { + topic = request.Subscription.TypePrefixSubscription.TopicTypePrefix; + agentType = request.Subscription.TypePrefixSubscription.AgentType; + } + else if (request.Subscription.TypeSubscription is not null) + { + topic = request.Subscription.TypeSubscription.TopicType; + agentType = request.Subscription.TypeSubscription.AgentType; + } + _subscriptionsByAgentType[agentType] = request.Subscription; + _subscriptionsByTopic.GetOrAdd(topic, _ => []).Add(agentType); + await _subscriptions.SubscribeAsync(topic, agentType); + //var response = new AddSubscriptionResponse { RequestId = request.RequestId, Error = "", Success = true }; + Message response = new() + { + AddSubscriptionResponse = new() + { + RequestId = request.RequestId, + Error = "", + Success = true + } + }; + await connection.ResponseStream.WriteAsync(response).ConfigureAwait(false); + } + + private async ValueTask DispatchEventToAgentsAsync(IEnumerable agentTypes, CloudEvent evt) + { + var tasks = new List(agentTypes.Count()); + foreach (var agentType in agentTypes) + { + if (_supportedAgentTypes.TryGetValue(agentType, out var connections)) + { + foreach (var connection in connections) + { + tasks.Add(this.SendMessageAsync(connection, evt)); + } + } + } + await Task.WhenAll(tasks).ConfigureAwait(false); + } + async ValueTask IGateway.InvokeRequest(RpcRequest request) { return await this.InvokeRequest(request).ConfigureAwait(false); } + public async ValueTask BroadcastEvent(CloudEvent evt) + { + var tasks = new List(_workers.Count); + foreach (var (_, connection) in _supportedAgentTypes) + { + tasks.Add(this.SendMessageAsync((IConnection)connection[0], evt, default)); + } + await Task.WhenAll(tasks).ConfigureAwait(false); + } Task IGateway.SendMessageAsync(IConnection connection, CloudEvent cloudEvent) { return this.SendMessageAsync(connection, cloudEvent); } + public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) + { + var queue = (GrpcWorkerConnection)connection; + await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); + } } From 70d488c2888ee40fb36d54b31482a37ab2c43275 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 18 Dec 2024 08:19:29 -0800 Subject: [PATCH 005/110] proto updates --- .../Runtime.Grpc/Services/Orleans/AgentsRegistry.cs | 2 +- protos/agent_worker.proto | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs index 30cd40ad35a4..6bee9bb1b246 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs @@ -5,7 +5,7 @@ using Microsoft.AutoGen.Runtime.Grpc.Abstractions; namespace Microsoft.AutoGen.Runtime.Grpc; -internal sealed class AgentsRegistry([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IGrainRegistry +internal sealed class AgentsRegistry([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IRegistryGrain { // TODO: use persistent state for some of these or (better) extend Orleans to implement some of this natively. private readonly Dictionary _workerStates = new(); diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index 7e658699b47e..c5c5d40121c7 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -50,6 +50,13 @@ message Event { message RegisterAgentTypeRequest { string request_id = 1; string type = 2; + +message RegisterAgentTypeRequest { + string request_id = 1; + string type = 2; + repeated string events = 3; + repeated string topics = 4; +} } message RegisterAgentTypeResponse { From 22946a0d446b789b7d6f17ed28e18565e8ea2ee0 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 18 Dec 2024 08:56:50 -0800 Subject: [PATCH 006/110] registry grain cleanup --- .../Abstractions/IRegistryGrain.cs | 1 + .../Services/Orleans/AgentsRegistry.cs | 225 ------------------ .../Orleans/OrleansRuntimeHostingExtenions.cs | 1 + .../Services/Orleans/RegistryGrain.cs | 98 +++++++- protos/agent_worker.proto | 5 - 5 files changed, 92 insertions(+), 238 deletions(-) delete mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs index 2f48b051b38b..6a5a8e725ecd 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistryGrain.cs @@ -6,5 +6,6 @@ namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; /// /// Orleans specific interface, needed to mark the key /// +[Alias("Microsoft.AutoGen.Runtime.Grpc.Abstractions.IRegistryGrain")] public interface IRegistryGrain : IRegistry, IGrainWithIntegerKey { } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs deleted file mode 100644 index 6bee9bb1b246..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistry.cs +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// AgentsRegistry.cs - -using Microsoft.AutoGen.Contracts; -using Microsoft.AutoGen.Runtime.Grpc.Abstractions; - -namespace Microsoft.AutoGen.Runtime.Grpc; -internal sealed class AgentsRegistry([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IRegistryGrain -{ - // TODO: use persistent state for some of these or (better) extend Orleans to implement some of this natively. - private readonly Dictionary _workerStates = new(); - private readonly Dictionary> _supportedAgentTypes = []; - private readonly Dictionary<(string Type, string Key), IGateway> _agentDirectory = []; - private readonly TimeSpan _agentTimeout = TimeSpan.FromMinutes(1); - - public override Task OnActivateAsync(CancellationToken cancellationToken) - { - this.RegisterGrainTimer(static state => state.PurgeInactiveWorkers(), this, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); - return base.OnActivateAsync(cancellationToken); - } - - public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) - { - // get all agent types that are subscribed to the topic - var subscribedAgents = state.State.TopicToAgentTypesMap[topic]; - // get all agent types that are handling the event - var handlingAgents = state.State.EventsToAgentTypesMap[eventType]; - // return the intersection of the two sets - return new(subscribedAgents.Intersect(handlingAgents).ToList()); - } - public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) - { - // TODO: Clarify the logic - bool isNewPlacement; - if (!_agentDirectory.TryGetValue((agentId.Type, agentId.Key), out var worker) || !_workerStates.ContainsKey(worker)) - { - worker = GetCompatibleWorkerCore(agentId.Type); - if (worker is not null) - { - // New activation. - _agentDirectory[(agentId.Type, agentId.Key)] = worker; - isNewPlacement = true; - } - else - { - // No activation, and failed to place. - isNewPlacement = false; - } - } - else - { - // Existing activation. - isNewPlacement = false; - } - return new((worker, isNewPlacement)); - } - public ValueTask RemoveWorker(IGateway worker) - { - if (_workerStates.Remove(worker, out var state)) - { - foreach (var type in state.SupportedTypes) - { - if (_supportedAgentTypes.TryGetValue(type, out var workers)) - { - workers.Remove(worker); - } - } - } - return ValueTask.CompletedTask; - } - public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, IGateway worker) - { - if (!_supportedAgentTypes.TryGetValue(registration.Type, out var supportedAgentTypes)) - { - supportedAgentTypes = _supportedAgentTypes[registration.Type] = []; - } - - if (!supportedAgentTypes.Contains(worker)) - { - supportedAgentTypes.Add(worker); - } - - var workerState = GetOrAddWorker(worker); - workerState.SupportedTypes.Add(registration.Type); - state.State.AgentsToEventsMap[registration.Type] = new HashSet(registration.Events); - state.State.AgentsToTopicsMap[registration.Type] = new HashSet(registration.Topics); - - // construct the inverse map for topics and agent types - foreach (var topic in registration.Topics) - { - if (!state.State.TopicToAgentTypesMap.TryGetValue(topic, out var topicSet)) - { - topicSet = new HashSet(); - state.State.TopicToAgentTypesMap[topic] = topicSet; - } - - topicSet.Add(registration.Type); - } - - // construct the inverse map for events and agent types - foreach (var evt in registration.Events) - { - if (!state.State.EventsToAgentTypesMap.TryGetValue(evt, out var eventSet)) - { - eventSet = new HashSet(); - state.State.EventsToAgentTypesMap[evt] = eventSet; - } - - eventSet.Add(registration.Type); - } - await state.WriteStateAsync().ConfigureAwait(false); - } - public ValueTask AddWorker(IGateway worker) - { - GetOrAddWorker(worker); - return ValueTask.CompletedTask; - } - public ValueTask UnregisterAgentType(string type, IGateway worker) - { - if (_workerStates.TryGetValue(worker, out var state)) - { - state.SupportedTypes.Remove(type); - } - - if (_supportedAgentTypes.TryGetValue(type, out var workers)) - { - workers.Remove(worker); - } - return ValueTask.CompletedTask; - } - private Task PurgeInactiveWorkers() - { - foreach (var (worker, state) in _workerStates) - { - if (DateTimeOffset.UtcNow - state.LastSeen > _agentTimeout) - { - _workerStates.Remove(worker); - foreach (var type in state.SupportedTypes) - { - if (_supportedAgentTypes.TryGetValue(type, out var workers)) - { - workers.Remove(worker); - } - } - } - } - - return Task.CompletedTask; - } - - private WorkerState GetOrAddWorker(IGateway worker) - { - if (!_workerStates.TryGetValue(worker, out var workerState)) - { - workerState = _workerStates[worker] = new(); - } - - workerState.LastSeen = DateTimeOffset.UtcNow; - return workerState; - } - - public ValueTask GetCompatibleWorker(string type) => new(GetCompatibleWorkerCore(type)); - - private IGateway? GetCompatibleWorkerCore(string type) - { - if (_supportedAgentTypes.TryGetValue(type, out var workers)) - { - // Return a random compatible worker. - return workers[Random.Shared.Next(workers.Count)]; - } - - return null; - } - - public async ValueTask SubscribeAsync(AddSubscriptionRequest sub) - { - switch (sub.Subscription.SubscriptionCase) - { - case Subscription.SubscriptionOneofCase.TypePrefixSubscription: - break; - case Subscription.SubscriptionOneofCase.TypeSubscription: - { - // add the topic to the set of topics for the agent type - state.State.AgentsToTopicsMap.TryGetValue(sub.Subscription.TypeSubscription.AgentType, out var topics); - if (topics is null) - { - topics = new HashSet(); - state.State.AgentsToTopicsMap[sub.Subscription.TypeSubscription.AgentType] = topics; - } - topics.Add(sub.Subscription.TypeSubscription.TopicType); - - // add the agent type to the set of agent types for the topic - state.State.TopicToAgentTypesMap.TryGetValue(sub.Subscription.TypeSubscription.TopicType, out var agents); - if (agents is null) - { - agents = new HashSet(); - state.State.TopicToAgentTypesMap[sub.Subscription.TypeSubscription.TopicType] = agents; - } - - agents.Add(sub.Subscription.TypeSubscription.AgentType); - - break; - } - default: - throw new InvalidOperationException("Invalid subscription type"); - } - await state.WriteStateAsync().ConfigureAwait(false); - } - public async ValueTask UnsubscribeAsync(AddSubscriptionRequest request) - { - throw new NotImplementedException(); - } - - public ValueTask>> GetSubscriptions(string agentType) - { - throw new NotImplementedException(); - } - - private sealed class WorkerState - { - public HashSet SupportedTypes { get; set; } = []; - public DateTimeOffset LastSeen { get; set; } - } -} - diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs index 4b8a290df031..68e0c7af745c 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs @@ -3,6 +3,7 @@ using System.Configuration; using Microsoft.AspNetCore.Builder; +using Microsoft.AutoGen.Runtime.Grpc.Abstractions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 8de1618c6002..d2b03e9e7e43 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -2,10 +2,10 @@ // RegistryGrain.cs using Microsoft.AutoGen.Contracts; +using Microsoft.AutoGen.Runtime.Grpc.Abstractions; namespace Microsoft.AutoGen.Runtime.Grpc; - -internal sealed class RegistryGrain : Grain, IRegistryGrain +internal sealed class RegistryGrain([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IRegistryGrain { // TODO: use persistent state for some of these or (better) extend Orleans to implement some of this natively. private readonly Dictionary _workerStates = new(); @@ -18,9 +18,19 @@ public override Task OnActivateAsync(CancellationToken cancellationToken) this.RegisterGrainTimer(static state => state.PurgeInactiveWorkers(), this, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30)); return base.OnActivateAsync(cancellationToken); } + + public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) + { + // get all agent types that are subscribed to the topic + var subscribedAgents = state.State.TopicToAgentTypesMap[topic]; + // get all agent types that are handling the event + var handlingAgents = state.State.EventsToAgentTypesMap[eventType]; + // return the intersection of the two sets + return new(subscribedAgents.Intersect(handlingAgents).ToList()); + } public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) { - // TODO: + // TODO: Clarify the logic bool isNewPlacement; if (!_agentDirectory.TryGetValue((agentId.Type, agentId.Key), out var worker) || !_workerStates.ContainsKey(worker)) { @@ -58,20 +68,47 @@ public ValueTask RemoveWorker(IGateway worker) } return ValueTask.CompletedTask; } - public ValueTask RegisterAgentType(string type, IGateway worker) + public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, IGateway worker) { - if (!_supportedAgentTypes.TryGetValue(type, out var supportedAgentTypes)) + if (!_supportedAgentTypes.TryGetValue(registration.Type, out var supportedAgentTypes)) { - supportedAgentTypes = _supportedAgentTypes[type] = []; + supportedAgentTypes = _supportedAgentTypes[registration.Type] = []; } if (!supportedAgentTypes.Contains(worker)) { supportedAgentTypes.Add(worker); } + var workerState = GetOrAddWorker(worker); - workerState.SupportedTypes.Add(type); - return ValueTask.CompletedTask; + workerState.SupportedTypes.Add(registration.Type); + state.State.AgentsToEventsMap[registration.Type] = new HashSet(registration.Events); + state.State.AgentsToTopicsMap[registration.Type] = new HashSet(registration.Topics); + + // construct the inverse map for topics and agent types + foreach (var topic in registration.Topics) + { + if (!state.State.TopicToAgentTypesMap.TryGetValue(topic, out var topicSet)) + { + topicSet = new HashSet(); + state.State.TopicToAgentTypesMap[topic] = topicSet; + } + + topicSet.Add(registration.Type); + } + + // construct the inverse map for events and agent types + foreach (var evt in registration.Events) + { + if (!state.State.EventsToAgentTypesMap.TryGetValue(evt, out var eventSet)) + { + eventSet = new HashSet(); + state.State.EventsToAgentTypesMap[evt] = eventSet; + } + + eventSet.Add(registration.Type); + } + await state.WriteStateAsync().ConfigureAwait(false); } public ValueTask AddWorker(IGateway worker) { @@ -135,9 +172,54 @@ private WorkerState GetOrAddWorker(IGateway worker) return null; } + public async ValueTask SubscribeAsync(AddSubscriptionRequest sub) + { + switch (sub.Subscription.SubscriptionCase) + { + case Subscription.SubscriptionOneofCase.TypePrefixSubscription: + break; + case Subscription.SubscriptionOneofCase.TypeSubscription: + { + // add the topic to the set of topics for the agent type + state.State.AgentsToTopicsMap.TryGetValue(sub.Subscription.TypeSubscription.AgentType, out var topics); + if (topics is null) + { + topics = new HashSet(); + state.State.AgentsToTopicsMap[sub.Subscription.TypeSubscription.AgentType] = topics; + } + topics.Add(sub.Subscription.TypeSubscription.TopicType); + + // add the agent type to the set of agent types for the topic + state.State.TopicToAgentTypesMap.TryGetValue(sub.Subscription.TypeSubscription.TopicType, out var agents); + if (agents is null) + { + agents = new HashSet(); + state.State.TopicToAgentTypesMap[sub.Subscription.TypeSubscription.TopicType] = agents; + } + + agents.Add(sub.Subscription.TypeSubscription.AgentType); + + break; + } + default: + throw new InvalidOperationException("Invalid subscription type"); + } + await state.WriteStateAsync().ConfigureAwait(false); + } + public async ValueTask UnsubscribeAsync(AddSubscriptionRequest request) + { + throw new NotImplementedException(); + } + + public ValueTask>> GetSubscriptions(string agentType) + { + throw new NotImplementedException(); + } + private sealed class WorkerState { public HashSet SupportedTypes { get; set; } = []; public DateTimeOffset LastSeen { get; set; } } } + diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index c5c5d40121c7..bddf34897300 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -47,17 +47,12 @@ message Event { map metadata = 5; } -message RegisterAgentTypeRequest { - string request_id = 1; - string type = 2; - message RegisterAgentTypeRequest { string request_id = 1; string type = 2; repeated string events = 3; repeated string topics = 4; } -} message RegisterAgentTypeResponse { string request_id = 1; From 43ed890af75aec0e4458ffe794ae6913a8f59e94 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 19 Dec 2024 15:38:16 -0800 Subject: [PATCH 007/110] core services build --- README.md | 2 +- dotnet/AutoGen.sln | 12 +- dotnet/samples/Hello/HelloAgent/Program.cs | 15 +-- dotnet/samples/Hello/HelloAgent/README.md | 2 +- .../samples/Hello/HelloAgentState/Program.cs | 2 +- .../samples/Hello/HelloAgentState/README.md | 2 +- .../Agents/AIAgent/SKAiAgent.cs | 2 +- .../IOAgent/ConsoleAgent/ConsoleAgent.cs | 2 +- .../IOAgent/ConsoleAgent/IHandleConsole.cs | 8 +- .../Core.Grpc/GrpcAgentWorker.cs | 6 +- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 102 ++++++++------- .../Microsoft.AutoGen/Core/AgentExtensions.cs | 4 +- .../Microsoft.AutoGen/Core/AgentMessenger.cs | 123 ------------------ .../Core/AgentMessengerFactory.cs | 12 -- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 4 +- dotnet/src/Microsoft.AutoGen/Core/Client.cs | 6 +- .../Microsoft.AutoGen/Core/IAgentWorker.cs | 1 + .../Core/IAgentWorkerExtensions.cs | 101 ++++++++++++++ dotnet/src/Microsoft.AutoGen/Core/IHandle.cs | 20 ++- .../Core/TopicSubscriptionAttribute.cs | 2 +- .../Core/UninitializedAgentWorker.cs | 20 +++ .../Services/Grpc/GrpcGatewayService.cs | 11 +- .../GrpcGatewayServiceTests.cs | 23 +--- ...icrosoft.AutoGen.Runtime.Grpc.Tests.csproj | 2 +- protos/agent_worker.proto | 2 + 25 files changed, 246 insertions(+), 240 deletions(-) delete mode 100644 dotnet/src/Microsoft.AutoGen/Core/AgentMessenger.cs delete mode 100644 dotnet/src/Microsoft.AutoGen/Core/AgentMessengerFactory.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Core/IAgentWorkerExtensions.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs diff --git a/README.md b/README.md index 96362f2af084..4b5fd029e5b8 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ await app.WaitForShutdownAsync(); [TopicSubscription("agents")] public class HelloAgent( IAgentContext worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent( + [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index aaeb45125ac4..fd4e048eebae 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -144,7 +144,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.AgentHost EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.Grpc.Tests", "test\Microsoft.AutoGen.Runtime.Grpc.Tests\Microsoft.AutoGen.Runtime.Grpc.Tests.csproj", "{0E7983BB-2602-421E-8B37-332E52870A10}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.Tests.Shared", "test\Microsoft.Autogen.Tests.Shared\Microsoft.Autogen.Tests.Shared.csproj", "{6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Tests.Shared", "test\Microsoft.AutoGen.Tests.Shared\Microsoft.AutoGen.Tests.Shared.csproj", "{14F90F79-580E-454D-BA7A-ED6D9723020D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -380,10 +380,10 @@ Global {0E7983BB-2602-421E-8B37-332E52870A10}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E7983BB-2602-421E-8B37-332E52870A10}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E7983BB-2602-421E-8B37-332E52870A10}.Release|Any CPU.Build.0 = Release|Any CPU - {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D}.Release|Any CPU.Build.0 = Release|Any CPU + {14F90F79-580E-454D-BA7A-ED6D9723020D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14F90F79-580E-454D-BA7A-ED6D9723020D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14F90F79-580E-454D-BA7A-ED6D9723020D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14F90F79-580E-454D-BA7A-ED6D9723020D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -450,7 +450,7 @@ Global {3892C83E-7F5D-41DF-A88C-4854EAD38856} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {0E7983BB-2602-421E-8B37-332E52870A10} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} - {6790BEFB-66E4-42D0-AE47-0EFEA8298E3D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} + {14F90F79-580E-454D-BA7A-ED6D9723020D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index dee73b1a47d3..9c3a038260b7 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -18,9 +18,8 @@ namespace Hello { [TopicSubscription("agents")] public class HelloAgent( - IAgentWorker worker, IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : Agent( - worker, + IHostApplicationLifetime hostApplicationLifetime, + [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : Agent( typeRegistry), ISayHello, IHandleConsole, @@ -28,7 +27,7 @@ public class HelloAgent( IHandle, IHandle { - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output { Message = response }; @@ -40,7 +39,7 @@ public async Task Handle(NewMessageReceived item) }; await PublishMessageAsync(goodbye).ConfigureAwait(false); } - public async Task Handle(ConversationClosed item) + public async Task Handle(ConversationClosed item, CancellationToken cancellationToken) { var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; var evt = new Output { Message = goodbye }; @@ -51,13 +50,13 @@ public async Task Handle(ConversationClosed item) } } - public async Task Handle(Shutdown item) + public async Task Handle(Shutdown item, CancellationToken cancellationToken) { Console.WriteLine("Shutting down..."); hostApplicationLifetime.StopApplication(); } - public async Task SayHello(string ask) + public async Task SayHello(string ask, CancellationToken cancellationToken = default) { var response = $"\n\n\n\n***************Hello {ask}**********************\n\n\n\n"; return response; @@ -65,6 +64,6 @@ public async Task SayHello(string ask) } public interface ISayHello { - public Task SayHello(string ask); + public Task SayHello(string ask, CancellationToken cancellationToken = default); } } diff --git a/dotnet/samples/Hello/HelloAgent/README.md b/dotnet/samples/Hello/HelloAgent/README.md index 53e3d6a65eba..067f04f3c30a 100644 --- a/dotnet/samples/Hello/HelloAgent/README.md +++ b/dotnet/samples/Hello/HelloAgent/README.md @@ -44,7 +44,7 @@ Within that event handler you may optionally *emit* new events, which are then s TopicSubscription("HelloAgents")] public class HelloAgent( iAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent( + [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, diff --git a/dotnet/samples/Hello/HelloAgentState/Program.cs b/dotnet/samples/Hello/HelloAgentState/Program.cs index dbb16c3bbb9b..d882f1f42c4a 100644 --- a/dotnet/samples/Hello/HelloAgentState/Program.cs +++ b/dotnet/samples/Hello/HelloAgentState/Program.cs @@ -20,7 +20,7 @@ namespace Hello public class HelloAgent( IAgentWorker worker, IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : Agent( + [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : Agent( worker, typeRegistry), IHandleConsole, diff --git a/dotnet/samples/Hello/HelloAgentState/README.md b/dotnet/samples/Hello/HelloAgentState/README.md index f46c66df1e1d..c8fead8b23b1 100644 --- a/dotnet/samples/Hello/HelloAgentState/README.md +++ b/dotnet/samples/Hello/HelloAgentState/README.md @@ -44,7 +44,7 @@ Within that event handler you may optionally *emit* new events, which are then s TopicSubscription("HelloAgents")] public class HelloAgent( iAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : ConsoleAgent( + [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, diff --git a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs index 1d0c57068e13..210c2054686e 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs @@ -12,7 +12,7 @@ public abstract class SKAiAgent( IAgentWorker worker, ISemanticTextMemory memory, Kernel kernel, - EventTypes typeRegistry) : Agent( + AgentsMetadata typeRegistry) : Agent( worker, typeRegistry) where T : class, new() { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs index 7bfe5ab8d786..03b654741704 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs @@ -13,7 +13,7 @@ public abstract class ConsoleAgent : IOAgent, { // instead of the primary constructor above, make a constructr here that still calls the base constructor - public ConsoleAgent(IAgentWorker worker, [FromKeyedServices("EventTypes")] EventTypes typeRegistry) : base(worker, typeRegistry) + public ConsoleAgent(IAgentWorker worker, [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : base(worker, typeRegistry) { _route = "console"; } diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs index 31b89453a2e6..dced31aac23a 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs @@ -12,7 +12,7 @@ public interface IHandleConsole : IHandle, IHandle AgentId AgentId { get; } ValueTask PublishMessageAsync(T message, string? source = null, CancellationToken token = default) where T : IMessage; - async Task IHandle.Handle(Output item) + async Task IHandle.Handle(Output item, CancellationToken cancellationToken) { // Assuming item has a property `Message` that we want to write to the console Console.WriteLine(item.Message); @@ -22,9 +22,9 @@ async Task IHandle.Handle(Output item) { Route = "console" }; - await PublishMessageAsync(evt); + await PublishMessageAsync(evt).ConfigureAwait(false); } - async Task IHandle.Handle(Input item) + async Task IHandle.Handle(Input item, CancellationToken cancellationToken) { Console.WriteLine("Please enter input:"); string content = Console.ReadLine() ?? string.Empty; @@ -35,7 +35,7 @@ async Task IHandle.Handle(Input item) { Route = "console" }; - await PublishMessageAsync(evt); + await PublishMessageAsync(evt).ConfigureAwait(false); } static Task ProcessOutput(string message) { diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index f96f42a2c11b..e63e2a1a5737 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -32,7 +32,7 @@ public sealed class GrpcAgentWorker( FullMode = BoundedChannelFullMode.Wait }); private readonly AgentRpc.AgentRpcClient _client = client; - private readonly IServiceProvider _serviceProvider = serviceProvider; + public readonly IServiceProvider ServiceProvider = serviceProvider; private readonly IEnumerable> _configuredAgentTypes = configuredAgentTypes; private readonly ILogger _logger = logger; private readonly CancellationTokenSource _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); @@ -40,6 +40,8 @@ public sealed class GrpcAgentWorker( private Task? _readTask; private Task? _writeTask; + IServiceProvider IAgentWorker.ServiceProvider => throw new NotImplementedException(); + public void Dispose() { _outboundMessagesChannel.Writer.TryComplete(); @@ -175,7 +177,7 @@ private Agent GetOrActivateAgent(AgentId agentId) { if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { - agent = (Agent)ActivatorUtilities.CreateInstance(_serviceProvider, agentType, this); + agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); _agents.TryAdd((agentId.Type, agentId.Key), agent); } else diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 67905ecb0543..d986df40add9 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -16,7 +16,7 @@ namespace Microsoft.AutoGen.Core; /// /// Represents the base class for an agent in the AutoGen system. /// -public abstract class Agent : IHandle +public abstract class Agent { private readonly object _lock = new(); private readonly ConcurrentDictionary> _pendingRequests = []; @@ -32,23 +32,25 @@ public abstract class Agent : IHandle public AgentId AgentId { get; private set; } private readonly Channel _mailbox = Channel.CreateUnbounded(); protected internal ILogger _logger; - public AgentMessenger Messenger { get; private set; } + public IAgentWorker Worker { get; private set; } private readonly ConcurrentDictionary _handlersByMessageType; - internal Task Completion { get; private set; } + protected readonly AgentsMetadata EventTypes; - protected readonly EventTypes EventTypes; - - protected Agent(IAgentWorker worker, - EventTypes eventTypes, + protected Agent( + AgentsMetadata eventTypes, ILogger? logger = null) { EventTypes = eventTypes; AgentId = new AgentId(this.GetType().Name, new Guid().ToString()); _logger = logger ?? LoggerFactory.Create(builder => { }).CreateLogger(); _handlersByMessageType = new(GetType().GetHandlersLookupTable()); - Messenger = AgentMessengerFactory.Create(worker, DistributedContextPropagator.Current); AddImplicitSubscriptionsAsync().AsTask().Wait(); - Completion = Start(); + Worker = new UninitializedAgentWorker(); + } + public Task Initialize(IAgentWorker worker) + { + Worker = worker; + return Start(); } private async ValueTask AddImplicitSubscriptionsAsync() @@ -74,7 +76,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() } }; // explicitly wait for this to complete - await Messenger.SendMessageAsync(new Message { AddSubscriptionRequest = subscriptionRequest }).ConfigureAwait(true); + await Worker.SendMessageAsync(new Message { AddSubscriptionRequest = subscriptionRequest }).ConfigureAwait(true); } // using reflection, find all methods that Handle and subscribe to the topic T @@ -82,10 +84,13 @@ private async ValueTask AddImplicitSubscriptionsAsync() foreach (var method in handleMethods) { var eventType = method.GetParameters()[0].ParameterType; - var topic = EventTypes.EventsMap.FirstOrDefault(x => x.Value.Contains(eventType.Name)).Key; - if (topic != null) + var topics = (IAsyncEnumerable?)EventTypes.GetTopicsForAgent(GetType()); + if (topics != null) { - Subscribe(nameof(topic)); + await foreach (var topic in topics.ConfigureAwait(false)) + { + Subscribe(topic); + } } } @@ -148,7 +153,7 @@ protected internal async Task HandleRpcMessage(Message msg, CancellationToken ca { var activity = this.ExtractActivity(msg.CloudEvent.Type, msg.CloudEvent.Attributes); await this.InvokeWithActivityAsync( - static ((Agent Agent, CloudEvent Item) state, CancellationToken _) => state.Agent.CallHandler(state.Item), + static ((Agent Agent, CloudEvent Item) state, CancellationToken _) => state.Agent.CallHandlerAsync(state.Item), (this, msg.CloudEvent), activity, msg.CloudEvent.Type, cancellationToken).ConfigureAwait(false); @@ -186,18 +191,18 @@ public List Subscribe(string topic) } } }; - Messenger.SendMessageAsync(message).AsTask().Wait(); + Worker.SendMessageAsync(message).AsTask().Wait(); return new List { topic }; } public async Task StoreAsync(AgentState state, CancellationToken cancellationToken = default) { - await Messenger.StoreAsync(state, cancellationToken).ConfigureAwait(false); + await Worker.StoreAsync(state, cancellationToken).ConfigureAwait(false); return; } public async Task ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) where T : IMessage, new() { - var agentstate = await Messenger.ReadAsync(agentId, cancellationToken).ConfigureAwait(false); + var agentstate = await Worker.ReadAsync(agentId, cancellationToken).ConfigureAwait(false); return agentstate.FromAgentState(); } private void OnResponseCore(RpcResponse response) @@ -226,7 +231,9 @@ private async Task OnRequestCoreAsync(RpcRequest request, CancellationToken canc { response = new RpcResponse { Error = ex.Message }; } - await Messenger.SendResponseAsync(request, response, cancellationToken).ConfigureAwait(false); + response.RequestId = request.RequestId; + + await Worker.SendResponseAsync(response, cancellationToken).ConfigureAwait(false); } protected async Task RequestAsync(AgentId target, string method, Dictionary parameters) @@ -250,7 +257,7 @@ protected async Task RequestAsync(AgentId target, string method, Di activity?.SetTag("peer.service", target.ToString()); var completion = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - Messenger!.Update(request, activity); + IAgentWorkerExtensions.Update(this.Worker, request, activity); await this.InvokeWithActivityAsync( static async (state, ct) => { @@ -258,7 +265,7 @@ static async (state, ct) => self._pendingRequests.AddOrUpdate(request.RequestId, _ => completion, (_, __) => completion); - await state.Item1.Messenger!.SendRequestAsync(state.Item1, state.request, ct).ConfigureAwait(false); + await state.Item1.Worker!.SendRequestAsync(state.Item1, state.request, ct).ConfigureAwait(false); await completion.Task.ConfigureAwait(false); }, @@ -283,53 +290,54 @@ public async ValueTask PublishEventAsync(CloudEvent item, CancellationToken canc activity?.SetTag("peer.service", $"{item.Type}/{item.Source}"); // TODO: fix activity - Messenger.Update(item, activity); + IAgentWorkerExtensions.Update(this.Worker, item, activity); await this.InvokeWithActivityAsync( static async ((Agent Agent, CloudEvent Event) state, CancellationToken ct) => { - await state.Agent.Messenger.PublishEventAsync(state.Event).ConfigureAwait(false); + await state.Agent.Worker.PublishEventAsync(state.Event).ConfigureAwait(false); }, (this, item), activity, item.Type, cancellationToken).ConfigureAwait(false); } - public Task CallHandler(CloudEvent item) + public Task CallHandlerAsync(CloudEvent item) { // Only send the event to the handler if the agent type is handling that type - // foreach of the keys in the EventTypes.EventsMap[] if it contains the item.type - foreach (var key in EventTypes.EventsMap.Keys) + if (EventTypes.CheckIfTypeHandles(GetType(), eventName: item.Type)) { - if (EventTypes.EventsMap[key].Contains(item.Type)) + var payload = item.ProtoData.Unpack(EventTypes.TypeRegistry); + var eventType = EventTypes.GetEventTypeByName(item.Type); + if (eventType == null) { - var payload = item.ProtoData.Unpack(EventTypes.TypeRegistry); - var convertedPayload = Convert.ChangeType(payload, EventTypes.Types[item.Type]); - var genericInterfaceType = typeof(IHandle<>).MakeGenericType(EventTypes.Types[item.Type]); + _logger.LogError($"Event type {item.Type} not found in the registry"); + return Task.CompletedTask; + } + var convertedPayload = Convert.ChangeType(payload, eventType); + var genericInterfaceType = typeof(IHandle<>).MakeGenericType(eventType); - MethodInfo methodInfo; - try + MethodInfo methodInfo; + try + { + // check that our target actually implements this interface, otherwise call the default static + if (genericInterfaceType.IsAssignableFrom(this.GetType())) { - // check that our target actually implements this interface, otherwise call the default static - if (genericInterfaceType.IsAssignableFrom(this.GetType())) - { - methodInfo = genericInterfaceType.GetMethod(nameof(IHandle.Handle), BindingFlags.Public | BindingFlags.Instance) - ?? throw new InvalidOperationException($"Method not found on type {genericInterfaceType.FullName}"); - return methodInfo.Invoke(this, [payload]) as Task ?? Task.CompletedTask; - } - else - { - // The error here is we have registered for an event that we do not have code to listen to - throw new InvalidOperationException($"No handler found for event '{item.Type}'; expecting IHandle<{item.Type}> implementation."); - } + methodInfo = genericInterfaceType.GetMethod(nameof(IHandle.Handle), BindingFlags.Public | BindingFlags.Instance) + ?? throw new InvalidOperationException($"Method not found on type {genericInterfaceType.FullName}"); + return methodInfo.Invoke(this, [payload]) as Task ?? Task.CompletedTask; } - catch (Exception ex) + else { - _logger.LogError(ex, $"Error invoking method {nameof(IHandle.Handle)}"); - throw; // TODO: ? + // The error here is we have registered for an event that we do not have code to listen to + throw new InvalidOperationException($"Agent Type '{GetType()}' is registered to handle this type but no handler found for event '{item.Type}'; expecting IHandle<{item.Type}> implementation."); } } + catch (Exception ex) + { + _logger.LogError(ex, $"Error invoking method {nameof(IHandle.Handle)}"); + throw; // TODO: ? + } } - return Task.CompletedTask; } diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentExtensions.cs index 911107f784c5..50d25b20ada4 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentExtensions.cs @@ -22,7 +22,7 @@ public static class AgentExtensions public static Activity? ExtractActivity(this Agent agent, string activityName, IDictionary metadata) { Activity? activity; - var (traceParent, traceState) = agent.Messenger.GetTraceIdAndState(metadata); + (string? traceParent, string? traceState) = IAgentWorkerExtensions.GetTraceIdAndState(agent.Worker, metadata); if (!string.IsNullOrEmpty(traceParent)) { if (ActivityContext.TryParse(traceParent, traceState, isRemote: true, out var parentContext)) @@ -43,7 +43,7 @@ public static class AgentExtensions activity.TraceStateString = traceState; } - var baggage = agent.Messenger.ExtractMetadata(metadata); + var baggage = IAgentWorkerExtensions.ExtractMetadata(agent.Worker, metadata); foreach (var baggageItem in baggage) { diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentMessenger.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentMessenger.cs deleted file mode 100644 index 66b1c0c65da9..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentMessenger.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// AgentMessenger.cs - -using System.Diagnostics; -using Google.Protobuf.Collections; -using Microsoft.AutoGen.Contracts; -using static Microsoft.AutoGen.Contracts.CloudEvent.Types; - -namespace Microsoft.AutoGen.Core; - -public sealed class AgentMessenger(IAgentWorker worker, DistributedContextPropagator distributedContextPropagator) -{ - private readonly IAgentWorker worker = worker; - - private DistributedContextPropagator DistributedContextPropagator { get; } = distributedContextPropagator; - public (string?, string?) GetTraceIdAndState(IDictionary metadata) - { - DistributedContextPropagator.ExtractTraceIdAndState(metadata, - static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => - { - var metadata = (IDictionary)carrier!; - fieldValues = null; - metadata.TryGetValue(fieldName, out fieldValue); - }, - out var traceParent, - out var traceState); - return (traceParent, traceState); - } - public (string?, string?) GetTraceIdAndState(MapField metadata) - { - DistributedContextPropagator.ExtractTraceIdAndState(metadata, - static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => - { - var metadata = (MapField)carrier!; - fieldValues = null; - metadata.TryGetValue(fieldName, out var ceValue); - fieldValue = ceValue?.CeString; - }, - out var traceParent, - out var traceState); - return (traceParent, traceState); - } - public void Update(RpcRequest request, Activity? activity = null) - { - DistributedContextPropagator.Inject(activity, request.Metadata, static (carrier, key, value) => - { - var metadata = (IDictionary)carrier!; - if (metadata.TryGetValue(key, out _)) - { - metadata[key] = value; - } - else - { - metadata.Add(key, value); - } - }); - } - public void Update(CloudEvent cloudEvent, Activity? activity = null) - { - DistributedContextPropagator.Inject(activity, cloudEvent.Attributes, static (carrier, key, value) => - { - var mapField = (MapField)carrier!; - if (mapField.TryGetValue(key, out var ceValue)) - { - mapField[key] = new CloudEventAttributeValue { CeString = value }; - } - else - { - mapField.Add(key, new CloudEventAttributeValue { CeString = value }); - } - }); - } - public async ValueTask SendResponseAsync(RpcRequest request, RpcResponse response, CancellationToken cancellationToken = default) - { - response.RequestId = request.RequestId; - await worker.SendResponseAsync(response, cancellationToken).ConfigureAwait(false); - } - public async ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default) - { - await worker.SendRequestAsync(agent, request, cancellationToken).ConfigureAwait(false); - } - public async ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default) - { - await worker.SendMessageAsync(message, cancellationToken).ConfigureAwait(false); - } - public async ValueTask PublishEventAsync(CloudEvent @event, CancellationToken cancellationToken = default) - { - await worker.PublishEventAsync(@event, cancellationToken).ConfigureAwait(false); - } - public async ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) - { - await worker.StoreAsync(value, cancellationToken).ConfigureAwait(false); - } - public ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) - { - return worker.ReadAsync(agentId, cancellationToken); - } - - public IDictionary ExtractMetadata(IDictionary metadata) - { - var baggage = DistributedContextPropagator.ExtractBaggage(metadata, static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => - { - var metadata = (IDictionary)carrier!; - fieldValues = null; - metadata.TryGetValue(fieldName, out fieldValue); - }); - - return baggage as IDictionary ?? new Dictionary(); - } - - public IDictionary ExtractMetadata(MapField metadata) - { - var baggage = DistributedContextPropagator.ExtractBaggage(metadata, static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => - { - var metadata = (MapField)carrier!; - fieldValues = null; - metadata.TryGetValue(fieldName, out var ceValue); - fieldValue = ceValue?.CeString; - }); - - return baggage as IDictionary ?? new Dictionary(); - } -} diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentMessengerFactory.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentMessengerFactory.cs deleted file mode 100644 index c008f9f2d5aa..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentMessengerFactory.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// AgentMessengerFactory.cs - -using System.Diagnostics; -namespace Microsoft.AutoGen.Core; -public class AgentMessengerFactory() -{ - public static AgentMessenger Create(IAgentWorker worker, DistributedContextPropagator distributedContextPropagator) - { - return new AgentMessenger(worker, distributedContextPropagator); - } -} diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 3b70461a39fd..7531429da2ed 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -22,7 +22,7 @@ public class AgentWorker( private readonly ConcurrentDictionary _agentStates = new(); private readonly ConcurrentDictionary _pendingClientRequests = new(); private readonly CancellationTokenSource _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); - private readonly IServiceProvider _serviceProvider = serviceProvider; + public IServiceProvider ServiceProvider { get; } = serviceProvider; private readonly IEnumerable> _configuredAgentTypes = configuredAgentTypes; private readonly ConcurrentDictionary _subscriptionsByAgentType = new(); private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); @@ -182,7 +182,7 @@ private Agent GetOrActivateAgent(AgentId agentId) { if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { - agent = (Agent)ActivatorUtilities.CreateInstance(_serviceProvider, agentType, this); + agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); _agents.TryAdd((agentId.Type, agentId.Key), agent); } else diff --git a/dotnet/src/Microsoft.AutoGen/Core/Client.cs b/dotnet/src/Microsoft.AutoGen/Core/Client.cs index 1d523005fedf..d93aca292ded 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Client.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Client.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AutoGen.Core; -public sealed class Client(IAgentWorker worker, [FromKeyedServices("EventTypes")] EventTypes eventTypes) - : Agent(worker, eventTypes) +public sealed class Client([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes) + : Agent(eventTypes) { -} +} \ No newline at end of file diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs index f26e30584ca6..13e18cf6f8d0 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs @@ -5,6 +5,7 @@ namespace Microsoft.AutoGen.Core; public interface IAgentWorker { + IServiceProvider ServiceProvider { get; } ValueTask PublishEventAsync(CloudEvent evt, CancellationToken cancellationToken = default); ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default); ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default); diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorkerExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorkerExtensions.cs new file mode 100644 index 000000000000..53dd8890e974 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorkerExtensions.cs @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// IAgentWorkerExtensions.cs + +using System.Diagnostics; +using Google.Protobuf.Collections; +using Microsoft.AutoGen.Contracts; +using Microsoft.Extensions.DependencyInjection; +using static Microsoft.AutoGen.Contracts.CloudEvent.Types; + +namespace Microsoft.AutoGen.Core; + +public static class IAgentWorkerExtensions +{ + public static (string?, string?) GetTraceIdAndState(IAgentWorker worker, IDictionary metadata) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + dcp.ExtractTraceIdAndState(metadata, + static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => + { + var metadata = (IDictionary)carrier!; + fieldValues = null; + metadata.TryGetValue(fieldName, out fieldValue); + }, + out var traceParent, + out var traceState); + return (traceParent, traceState); + } + public static (string?, string?) GetTraceIdAndState(IAgentWorker worker, MapField metadata) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + dcp.ExtractTraceIdAndState(metadata, + static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => + { + var metadata = (MapField)carrier!; + fieldValues = null; + metadata.TryGetValue(fieldName, out var ceValue); + fieldValue = ceValue?.CeString; + }, + out var traceParent, + out var traceState); + return (traceParent, traceState); + } + public static void Update(IAgentWorker worker, RpcRequest request, Activity? activity = null) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + dcp.Inject(activity, request.Metadata, static (carrier, key, value) => + { + var metadata = (IDictionary)carrier!; + if (metadata.TryGetValue(key, out _)) + { + metadata[key] = value; + } + else + { + metadata.Add(key, value); + } + }); + } + public static void Update(IAgentWorker worker, CloudEvent cloudEvent, Activity? activity = null) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + dcp.Inject(activity, cloudEvent.Attributes, static (carrier, key, value) => + { + var mapField = (MapField)carrier!; + if (mapField.TryGetValue(key, out var ceValue)) + { + mapField[key] = new CloudEventAttributeValue { CeString = value }; + } + else + { + mapField.Add(key, new CloudEventAttributeValue { CeString = value }); + } + }); + } + + public static IDictionary ExtractMetadata(IAgentWorker worker, IDictionary metadata) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + var baggage = dcp.ExtractBaggage(metadata, static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => + { + var metadata = (IDictionary)carrier!; + fieldValues = null; + metadata.TryGetValue(fieldName, out fieldValue); + }); + + return baggage as IDictionary ?? new Dictionary(); + } + public static IDictionary ExtractMetadata(IAgentWorker worker, MapField metadata) + { + var dcp = worker.ServiceProvider.GetRequiredService(); + var baggage = dcp.ExtractBaggage(metadata, static (object? carrier, string fieldName, out string? fieldValue, out IEnumerable? fieldValues) => + { + var metadata = (MapField)carrier!; + fieldValues = null; + metadata.TryGetValue(fieldName, out var ceValue); + fieldValue = ceValue?.CeString; + }); + + return baggage as IDictionary ?? new Dictionary(); + } +} diff --git a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs index 025ea8a5149c..25f7aea89e9b 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs @@ -1,12 +1,20 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // IHandle.cs + +using Google.Protobuf; + namespace Microsoft.AutoGen.Core; -public interface IHandle -{ - Task HandleObject(object item); -} -public interface IHandle : IHandle +/// +/// Defines a handler interface for processing items of type . +/// +/// The type of item to be handled, which must implement . +public interface IHandle where T : IMessage { - Task Handle(T item); + /// + /// Handles the specified item asynchronously. + /// + /// The item to be handled. + /// A task that represents the asynchronous operation. + Task Handle(T item, CancellationToken cancellationToken); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs b/dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs index ba17520f79b9..8c1e93e2f664 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/TopicSubscriptionAttribute.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // TopicSubscriptionAttribute.cs -namespace Microsoft.AutoGen.Contracts; +namespace Microsoft.AutoGen.Core; [AttributeUsage(AttributeTargets.All)] public class TopicSubscriptionAttribute(string topic) : Attribute diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs new file mode 100644 index 000000000000..6597b005c481 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// UninitializedAgentWorker.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Core; +public class UninitializedAgentWorker() : IAgentWorker +{ + public IServiceProvider ServiceProvider => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + internal const string AgentNotInitializedMessage = "Agent not initialized correctly. An Agent should never be directly intialized - it is always started byt the AgentWorker from the Runtime."; + public ValueTask PublishEventAsync(CloudEvent evt, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public class AgentInitalizedIncorrectlyException(string message) : Exception(message) + { + } +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index a922f23c8e70..156fab2ef191 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -34,7 +34,6 @@ public override async Task GetState(AgentId request, ServerCal var state = await Gateway.ReadAsync(request); return new GetStateResponse { AgentState = state }; } - public override async Task SaveState(AgentState request, ServerCallContext context) { await Gateway.StoreAsync(request); @@ -43,4 +42,14 @@ public override async Task SaveState(AgentState request, Serv Success = true // TODO: Implement error handling }; } + public override async Task AddSubscription(AddSubscriptionRequest request, ServerCallContext context) + { + request.RequestId = context.Peer; + return await Gateway.AddSubscriptionAsync(request); + } + public override async Task RegisterAgent(RegisterAgentTypeRequest request, ServerCallContext context) + { + request.RequestId = context.Peer; + return await Gateway.RegisterAgentTypeAsync(request); + } } diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 507809fc3e5a..6c37c492ab33 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -46,14 +46,11 @@ public async Task Test_Message_Exchange_Through_Gateway() var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - var responseMessage = await client.ReadNext(); - var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), connectionId), client.CallContext); - - var inputEvent = new NewMessageReceived { Message = $"Start-{connectionId}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); + var inputEvent = new NewMessageReceived { Message = $"Start-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); client.AddMessage(new Message { CloudEvent = inputEvent }); var newMessageReceived = await client.ReadNext(); @@ -61,7 +58,7 @@ public async Task Test_Message_Exchange_Through_Gateway() newMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); // Simulate an agent, by publishing a new message in the request stream - var helloEvent = new Hello { Message = $"Hello test-{connectionId}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); + var helloEvent = new Hello { Message = $"Hello test-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); client.AddMessage(new Message { CloudEvent = helloEvent }); var helloMessageReceived = await client.ReadNext(); @@ -81,12 +78,9 @@ public async Task Test_Message_Goes_To_Right_Worker() var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - var responseMessage = await client.ReadNext(); - - var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), connectionId), client.CallContext); + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); + await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); } @@ -102,11 +96,8 @@ public async Task Test_RegisterAgent_Should_Succeed() var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - var responseMessage = await client.ReadNext(); - - var connectionId = responseMessage!.OpenChannelResponse.ConnectionId; - var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), connectionId), client.CallContext); + var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); response.Success.Should().BeTrue(); } diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj index 1cdeb3f295e8..23e3794606e1 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index bddf34897300..d962ae96acb4 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -92,6 +92,8 @@ service AgentRpc { rpc OpenChannel (stream Message) returns (stream Message); rpc GetState(AgentId) returns (GetStateResponse); rpc SaveState(AgentState) returns (SaveStateResponse); + rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse); + rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse); } message AgentState { From 98e517d35f76d391901adb38bdfdaaf8775782c7 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 19 Dec 2024 18:03:54 -0800 Subject: [PATCH 008/110] Adding AgentTests and host builder cleanup --- dotnet/AutoGen.sln | 14 ++-- .../Core/HostBuilderExtensions.cs | 82 +------------------ dotnet/src/Microsoft.AutoGen/Core/IHandle.cs | 4 +- .../AgentTests.cs | 49 +++++------ .../Microsoft.AutoGen.Core.Tests.csproj} | 0 5 files changed, 32 insertions(+), 117 deletions(-) rename dotnet/test/{Microsoft.AutoGen.Agents.Tests => Microsoft.AutoGen.Core.Tests}/AgentTests.cs (70%) rename dotnet/test/{Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj => Microsoft.AutoGen.Core.Tests/Microsoft.AutoGen.Core.Tests.csproj} (100%) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index fd4e048eebae..474371b3b85f 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -126,8 +126,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloAgentState", "samples\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Extensions.Aspire", "src\Microsoft.AutoGen\Extensions\Aspire\Microsoft.AutoGen.Extensions.Aspire.csproj", "{65059914-5527-4A00-9308-9FAF23D5E85A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AutoGen.Agents.Tests", "test\Microsoft.AutoGen.Agents.Tests\Microsoft.AutoGen.Agents.Tests.csproj", "{394FDAF8-74F9-4977-94A5-3371737EB774}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Integration.Tests", "test\Microsoft.AutoGen.Integration.Tests\Microsoft.AutoGen.Integration.Tests.csproj", "{D04C6153-8EAF-4E54-9852-52CEC1BE8D31}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloAgent.AppHost", "test\Microsoft.AutoGen.Integration.Tests.AppHosts\HelloAgent.AppHost\HelloAgent.AppHost.csproj", "{99D7766B-076F-4E6F-A8D2-3DF1DAFA2599}" @@ -146,6 +144,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.G EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Tests.Shared", "test\Microsoft.AutoGen.Tests.Shared\Microsoft.AutoGen.Tests.Shared.csproj", "{14F90F79-580E-454D-BA7A-ED6D9723020D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Tests", "test\Microsoft.AutoGen.Core.Tests\Microsoft.AutoGen.Core.Tests.csproj", "{EAFFE339-26CB-4019-991D-BCCE8E7D33A1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -344,10 +344,6 @@ Global {65059914-5527-4A00-9308-9FAF23D5E85A}.Debug|Any CPU.Build.0 = Debug|Any CPU {65059914-5527-4A00-9308-9FAF23D5E85A}.Release|Any CPU.ActiveCfg = Release|Any CPU {65059914-5527-4A00-9308-9FAF23D5E85A}.Release|Any CPU.Build.0 = Release|Any CPU - {394FDAF8-74F9-4977-94A5-3371737EB774}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {394FDAF8-74F9-4977-94A5-3371737EB774}.Debug|Any CPU.Build.0 = Debug|Any CPU - {394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.ActiveCfg = Release|Any CPU - {394FDAF8-74F9-4977-94A5-3371737EB774}.Release|Any CPU.Build.0 = Release|Any CPU {D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Debug|Any CPU.Build.0 = Debug|Any CPU {D04C6153-8EAF-4E54-9852-52CEC1BE8D31}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -384,6 +380,10 @@ Global {14F90F79-580E-454D-BA7A-ED6D9723020D}.Debug|Any CPU.Build.0 = Debug|Any CPU {14F90F79-580E-454D-BA7A-ED6D9723020D}.Release|Any CPU.ActiveCfg = Release|Any CPU {14F90F79-580E-454D-BA7A-ED6D9723020D}.Release|Any CPU.Build.0 = Release|Any CPU + {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -441,7 +441,6 @@ Global {97550E87-48C6-4EBF-85E1-413ABAE9DBFD} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {64EF61E7-00A6-4E5E-9808-62E10993A0E5} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45} {65059914-5527-4A00-9308-9FAF23D5E85A} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} - {394FDAF8-74F9-4977-94A5-3371737EB774} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {D04C6153-8EAF-4E54-9852-52CEC1BE8D31} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {99D7766B-076F-4E6F-A8D2-3DF1DAFA2599} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {7F60934B-3E59-48D0-B26D-04A39FEC13EF} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} @@ -451,6 +450,7 @@ Global {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {0E7983BB-2602-421E-8B37-332E52870A10} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {14F90F79-580E-454D-BA7A-ED6D9723020D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} + {EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} diff --git a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs index 95d4d7ce7553..96279b46dd43 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs @@ -3,9 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using Google.Protobuf; -using Google.Protobuf.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -14,8 +11,6 @@ namespace Microsoft.AutoGen.Core; public static class HostBuilderExtensions { - private const string _defaultAgentServiceAddress = "https://localhost:53071"; - public static IHostApplicationBuilder AddAgent< [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TAgent>(this IHostApplicationBuilder builder, string typeName) where TAgent : Agent { @@ -30,90 +25,21 @@ public static IHostApplicationBuilder AddAgent(this IHostApplicationBuilder buil return builder; } - public static IHostApplicationBuilder AddAgentWorker(this IHostApplicationBuilder builder, string? agentServiceAddress = null) + public static IHostApplicationBuilder AddAgentWorker(this IHostApplicationBuilder builder) { - agentServiceAddress ??= builder.Configuration["AGENT_HOST"] ?? _defaultAgentServiceAddress; + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => (IHostedService)sp.GetRequiredService()); - builder.Services.AddKeyedSingleton("EventTypes", (sp, key) => + builder.Services.AddKeyedSingleton("AgentsMetadata", (sp, key) => { - var interfaceType = typeof(IMessage); - var pairs = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(assembly => assembly.GetTypes()) - .Where(type => interfaceType.IsAssignableFrom(type) && type.IsClass && !type.IsAbstract) - .Select(t => (t, GetMessageDescriptor(t))); - - var descriptors = pairs.Select(t => t.Item2); - var typeRegistry = TypeRegistry.FromMessages(descriptors); - var types = pairs.ToDictionary(item => item.Item2?.FullName ?? "", item => item.t); - - var eventsMap = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(assembly => assembly.GetTypes()) - .Where(type => ReflectionHelper.IsSubclassOfGeneric(type, typeof(Agent)) && !type.IsAbstract) - .Select(t => (t, t.GetInterfaces() - .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandle<>)) - .Select(i => (GetMessageDescriptor(i.GetGenericArguments().First())?.FullName ?? "")).ToHashSet())) - .ToDictionary(item => item.t, item => item.Item2); - // if the assembly contains any interfaces of type IHandler, then add all the methods of the interface to the eventsMap - var handlersMap = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(assembly => assembly.GetTypes()) - .Where(type => ReflectionHelper.IsSubclassOfGeneric(type, typeof(Agent)) && !type.IsAbstract) - .Select(t => (t, t.GetMethods() - .Where(m => m.Name == "Handle") - .Select(m => (GetMessageDescriptor(m.GetParameters().First().ParameterType)?.FullName ?? "")).ToHashSet())) - .ToDictionary(item => item.t, item => item.Item2); - // get interfaces implemented by the agent and get the methods of the interface if they are named Handle - var ifaceHandlersMap = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(assembly => assembly.GetTypes()) - .Where(type => ReflectionHelper.IsSubclassOfGeneric(type, typeof(Agent)) && !type.IsAbstract) - .Select(t => t.GetInterfaces() - .Select(i => (t, i, i.GetMethods() - .Where(m => m.Name == "Handle") - .Select(m => (GetMessageDescriptor(m.GetParameters().First().ParameterType)?.FullName ?? "")) - //to dictionary of type t and paramter type of the method - .ToDictionary(m => m, m => m).Keys.ToHashSet())).ToList()); - // for each item in ifaceHandlersMap, add the handlers to eventsMap with item as the key - foreach (var item in ifaceHandlersMap) - { - foreach (var iface in item) - { - if (eventsMap.TryGetValue(iface.Item2, out var events)) - { - events.UnionWith(iface.Item3); - } - else - { - eventsMap[iface.Item2] = iface.Item3; - } - } - } - - // merge the handlersMap into the eventsMap - foreach (var item in handlersMap) - { - if (eventsMap.TryGetValue(item.Key, out var events)) - { - events.UnionWith(item.Value); - } - else - { - eventsMap[item.Key] = item.Value; - } - } - return new EventTypes(typeRegistry, types, eventsMap); + return ReflectionHelper.GetAgentsMetadata(assemblies); }); builder.Services.AddSingleton(); builder.Services.AddSingleton(new AgentApplicationBuilder(builder)); return builder; } - - private static MessageDescriptor? GetMessageDescriptor(Type type) - { - var property = type.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public); - return property?.GetValue(null) as MessageDescriptor; - } } public sealed class AgentApplicationBuilder(IHostApplicationBuilder builder) { diff --git a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs index 25f7aea89e9b..0b91f4436d4c 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs @@ -16,5 +16,5 @@ public interface IHandle where T : IMessage /// /// The item to be handled. /// A task that represents the asynchronous operation. - Task Handle(T item, CancellationToken cancellationToken); -} + Task Handle(T item, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs similarity index 70% rename from dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentTests.cs rename to dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 08a88da048de..8040ab451c64 100644 --- a/dotnet/test/Microsoft.AutoGen.Agents.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -2,14 +2,15 @@ // AgentTests.cs using System.Collections.Concurrent; +using System.Diagnostics; using FluentAssertions; using Google.Protobuf.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Moq; using Xunit; using static Microsoft.AutoGen.Core.Tests.AgentTests; @@ -18,13 +19,22 @@ namespace Microsoft.AutoGen.Core.Tests; [Collection(ClusterFixtureCollection.Name)] public class AgentTests(InMemoryAgentRuntimeFixture fixture) { + private readonly IServiceProvider _serviceProvider = fixture.AppHost.Services; private readonly InMemoryAgentRuntimeFixture _fixture = fixture; + // need a variable to store the runtime instance + public static WebApplication? Host { get; private set; } + [Fact] + public void Agent_ShouldThrowException_WhenNotInitialized() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + agent.Subscribe("TestEvent"); + Assert.Throws(() => agent.Worker.ServiceProvider); + } [Fact] public async Task ItInvokeRightHandlerTestAsync() { - var mockWorker = new Mock(); - var agent = new TestAgent(mockWorker.Object, new EventTypes(TypeRegistry.Empty, [], []), new Logger(new LoggerFactory())); + var agent = new TestAgent(new AgentsMetadata(TypeRegistry.Empty, new Dictionary(), new Dictionary>(), new Dictionary>()), new Logger(new LoggerFactory())); await agent.HandleObject("hello world"); await agent.HandleObject(42); @@ -58,28 +68,11 @@ await client.PublishMessageAsync(new TextMessage() /// /// The test agent is a simple agent that is used for testing purposes. /// - public class TestAgent : Agent, IHandle, IHandle, IHandle + public class TestAgent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes, + Logger? logger = null) : Agent(eventTypes, logger), IHandle { - public TestAgent( - IAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes eventTypes, - Logger? logger = null) : base(worker, eventTypes, logger) - { - } - - public Task Handle(string item) - { - ReceivedItems.Add(item); - return Task.CompletedTask; - } - - public Task Handle(int item) - { - ReceivedItems.Add(item); - return Task.CompletedTask; - } - - public Task Handle(TextMessage item) + public Task Handle(TextMessage item, CancellationToken cancellationToken = default) { ReceivedMessages[item.Source] = item.TextMessage_; return Task.CompletedTask; @@ -100,13 +93,9 @@ public sealed class InMemoryAgentRuntimeFixture : IDisposable public InMemoryAgentRuntimeFixture() { var builder = WebApplication.CreateBuilder(); - - // step 1: create in-memory agent runtime - // step 2: register TestAgent to that agent runtime - builder - .AddAgentWorker() + builder.Services.TryAddSingleton(DistributedContextPropagator.Current); + builder.AddAgentWorker() .AddAgent(nameof(TestAgent)); - AppHost = builder.Build(); AppHost.StartAsync().Wait(); } diff --git a/dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Core.Tests/Microsoft.AutoGen.Core.Tests.csproj similarity index 100% rename from dotnet/test/Microsoft.AutoGen.Agents.Tests/Microsoft.AutoGen.Agents.Tests.csproj rename to dotnet/test/Microsoft.AutoGen.Core.Tests/Microsoft.AutoGen.Core.Tests.csproj From ac7bde852504d9488ed71ac13ad2aa6eb9cd2696 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 19 Dec 2024 18:08:28 -0800 Subject: [PATCH 009/110] fixing what the tests found --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index d986df40add9..747762b09eef 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -44,13 +44,14 @@ protected Agent( AgentId = new AgentId(this.GetType().Name, new Guid().ToString()); _logger = logger ?? LoggerFactory.Create(builder => { }).CreateLogger(); _handlersByMessageType = new(GetType().GetHandlersLookupTable()); - AddImplicitSubscriptionsAsync().AsTask().Wait(); Worker = new UninitializedAgentWorker(); } public Task Initialize(IAgentWorker worker) { Worker = worker; - return Start(); + var completion = Start(); + AddImplicitSubscriptionsAsync().AsTask().Wait(); + return completion; } private async ValueTask AddImplicitSubscriptionsAsync() From 5ee0db86e3f25090dbaaabc39e5e0deb111f6a58 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 19 Dec 2024 19:47:41 -0800 Subject: [PATCH 010/110] EventTypes->AgentMetadata --- dotnet/src/Microsoft.AutoGen/Core/ReflectionHelper.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/ReflectionHelper.cs b/dotnet/src/Microsoft.AutoGen/Core/ReflectionHelper.cs index 41b27ffee613..a977af69e79d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/ReflectionHelper.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/ReflectionHelper.cs @@ -23,7 +23,7 @@ public static bool IsSubclassOfGeneric(Type type, Type genericBaseType) } return false; } - public static EventTypes GetAgentsMetadata(params Assembly[] assemblies) + public static AgentsMetadata GetAgentsMetadata(params Assembly[] assemblies) { var interfaceType = typeof(IMessage); var pairs = assemblies @@ -42,8 +42,12 @@ public static EventTypes GetAgentsMetadata(params Assembly[] assemblies) .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandle<>)) .Select(i => GetMessageDescriptor(i.GetGenericArguments().First())?.FullName ?? "").ToHashSet())) .ToDictionary(item => item.t, item => item.Item2); - - return new EventTypes(typeRegistry, types, eventsMap); + var topicsMap = assemblies + .SelectMany(assembly => assembly.GetTypes()) + .Where(type => IsSubclassOfGeneric(type, typeof(Agent)) && !type.IsAbstract) + .Select(t => (t, t.GetCustomAttributes().Select(a => a.Topic).ToHashSet())) + .ToDictionary(item => item.t, item => item.Item2); + return new AgentsMetadata(typeRegistry, types, eventsMap, topicsMap); } /// From bd6664230dbe1f98899feec475b717e0c934c2c1 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 19 Dec 2024 23:21:50 -0800 Subject: [PATCH 011/110] initialize test --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 14 ++++++------- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 1 + .../AgentTests.cs | 21 +++++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 747762b09eef..b5d76e7f3880 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -46,12 +46,11 @@ protected Agent( _handlersByMessageType = new(GetType().GetHandlersLookupTable()); Worker = new UninitializedAgentWorker(); } - public Task Initialize(IAgentWorker worker) + public static void Initialize(IAgentWorker worker, Agent agent) { - Worker = worker; - var completion = Start(); - AddImplicitSubscriptionsAsync().AsTask().Wait(); - return completion; + agent.Worker = worker; + agent.Start().ConfigureAwait(false); + agent.AddImplicitSubscriptionsAsync().AsTask().Wait(); } private async ValueTask AddImplicitSubscriptionsAsync() @@ -85,16 +84,15 @@ private async ValueTask AddImplicitSubscriptionsAsync() foreach (var method in handleMethods) { var eventType = method.GetParameters()[0].ParameterType; - var topics = (IAsyncEnumerable?)EventTypes.GetTopicsForAgent(GetType()); + var topics = EventTypes.GetTopicsForAgent(GetType()); if (topics != null) { - await foreach (var topic in topics.ConfigureAwait(false)) + foreach (var topic in topics) { Subscribe(topic); } } } - } /// diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 7531429da2ed..5e578fb5ab92 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -183,6 +183,7 @@ private Agent GetOrActivateAgent(AgentId agentId) if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); + Agent.Initialize(this, agent); _agents.TryAdd((agentId.Type, agentId.Key), agent); } else diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 8040ab451c64..f4282fe86615 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -24,13 +24,30 @@ public class AgentTests(InMemoryAgentRuntimeFixture fixture) // need a variable to store the runtime instance public static WebApplication? Host { get; private set; } + /// + /// Verify that if the agent is not initialized via AgentWorker, it should throw the correct exception. + /// + /// void [Fact] public void Agent_ShouldThrowException_WhenNotInitialized() { var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - agent.Subscribe("TestEvent"); - Assert.Throws(() => agent.Worker.ServiceProvider); + Assert.Throws(() => { agent.Subscribe("TestEvent"); }); + } + + /// + /// validate that the agent is initialized correctly with implicit subs + /// + /// void + [Fact] + public async Task Agent_ShouldInitializeCorrectly() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + var worker = _serviceProvider.GetRequiredService(); + Agent.Initialize(worker, agent); + Assert.Equal("AgentWorker", agent.Worker.GetType().Name); } + [Fact] public async Task ItInvokeRightHandlerTestAsync() { From 94ddacb225fb9d6c472c838125358c30501e3f01 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 20 Dec 2024 10:44:46 -0800 Subject: [PATCH 012/110] more fixes along the way --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 31 +++++++++++-------- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 3 +- dotnet/src/Microsoft.AutoGen/Core/Client.cs | 2 +- .../Core/HostBuilderExtensions.cs | 7 ++++- .../Core/UninitializedAgentWorker.cs | 2 +- .../AgentTests.cs | 16 +++++++--- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index b5d76e7f3880..3ce1a0039f2c 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -41,7 +41,7 @@ protected Agent( ILogger? logger = null) { EventTypes = eventTypes; - AgentId = new AgentId(this.GetType().Name, new Guid().ToString()); + AgentId = new AgentId(this.GetType().Name, Guid.NewGuid().ToString()); _logger = logger ?? LoggerFactory.Create(builder => { }).CreateLogger(); _handlersByMessageType = new(GetType().GetHandlersLookupTable()); Worker = new UninitializedAgentWorker(); @@ -49,8 +49,10 @@ protected Agent( public static void Initialize(IAgentWorker worker, Agent agent) { agent.Worker = worker; - agent.Start().ConfigureAwait(false); - agent.AddImplicitSubscriptionsAsync().AsTask().Wait(); + agent.Start().ContinueWith(async startTask => + { + await agent.AddImplicitSubscriptionsAsync(); + }, TaskScheduler.Default); } private async ValueTask AddImplicitSubscriptionsAsync() @@ -152,7 +154,7 @@ protected internal async Task HandleRpcMessage(Message msg, CancellationToken ca { var activity = this.ExtractActivity(msg.CloudEvent.Type, msg.CloudEvent.Attributes); await this.InvokeWithActivityAsync( - static ((Agent Agent, CloudEvent Item) state, CancellationToken _) => state.Agent.CallHandlerAsync(state.Item), + static ((Agent Agent, CloudEvent Item) state, CancellationToken ct) => state.Agent.CallHandlerAsync(state.Item, ct), (this, msg.CloudEvent), activity, msg.CloudEvent.Type, cancellationToken).ConfigureAwait(false); @@ -300,7 +302,7 @@ static async ((Agent Agent, CloudEvent Event) state, CancellationToken ct) => item.Type, cancellationToken).ConfigureAwait(false); } - public Task CallHandlerAsync(CloudEvent item) + public Task CallHandlerAsync(CloudEvent item, CancellationToken cancellationToken = default) { // Only send the event to the handler if the agent type is handling that type if (EventTypes.CheckIfTypeHandles(GetType(), eventName: item.Type)) @@ -323,7 +325,7 @@ public Task CallHandlerAsync(CloudEvent item) { methodInfo = genericInterfaceType.GetMethod(nameof(IHandle.Handle), BindingFlags.Public | BindingFlags.Instance) ?? throw new InvalidOperationException($"Method not found on type {genericInterfaceType.FullName}"); - return methodInfo.Invoke(this, [payload]) as Task ?? Task.CompletedTask; + return methodInfo.Invoke(this, new object[] { convertedPayload, cancellationToken }) as Task ?? Task.CompletedTask; } else { @@ -342,23 +344,26 @@ public Task CallHandlerAsync(CloudEvent item) public Task HandleRequestAsync(RpcRequest request) => Task.FromResult(new RpcResponse { Error = "Not implemented" }); - //TODO: should this be async and cancellable? - public virtual Task HandleObject(object item) + /// + /// Handles a generic object + /// + /// The object to handle + /// The cancellation token + /// A task representing the asynchronous operation. + /// TODO: this is only called from tests, should we remove it? + public virtual async Task HandleObjectAsync(object item, CancellationToken cancellationToken = default) { // get all Handle methods var handleTMethods = this.GetType().GetMethods().Where(m => m.Name == "Handle" && m.GetParameters().Length == 1).ToList(); - // get the one that matches the type of the item var handleTMethod = handleTMethods.FirstOrDefault(m => m.GetParameters()[0].ParameterType == item.GetType()); - // if we found one, invoke it if (handleTMethod != null) { - return (Task)handleTMethod.Invoke(this, [item])!; + await (Task)handleTMethod.Invoke(this, [item])!; } - // otherwise, complain - throw new InvalidOperationException($"No handler found for type {item.GetType().FullName}"); + _logger.LogError($"No handler found for type {item.GetType().FullName}"); } public async ValueTask PublishEventAsync(string topic, IMessage evt, CancellationToken cancellationToken = default) { diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 5e578fb5ab92..a4bbe9aa5656 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -182,9 +182,10 @@ private Agent GetOrActivateAgent(AgentId agentId) { if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { - agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); + agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType); Agent.Initialize(this, agent); _agents.TryAdd((agentId.Type, agentId.Key), agent); + } else { diff --git a/dotnet/src/Microsoft.AutoGen/Core/Client.cs b/dotnet/src/Microsoft.AutoGen/Core/Client.cs index d93aca292ded..f689751b4002 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Client.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Client.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AutoGen.Core; -public sealed class Client([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes) +public sealed class Client([FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes) : Agent(eventTypes) { } \ No newline at end of file diff --git a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs index 96279b46dd43..e48195c63a6e 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs @@ -35,7 +35,12 @@ public static IHostApplicationBuilder AddAgentWorker(this IHostApplicationBuilde { return ReflectionHelper.GetAgentsMetadata(assemblies); }); - builder.Services.AddSingleton(); + builder.Services.AddSingleton((s) => { + var worker = s.GetRequiredService(); + var client = ActivatorUtilities.CreateInstance(s); + Agent.Initialize(worker, client); + return client; + }); builder.Services.AddSingleton(new AgentApplicationBuilder(builder)); return builder; diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index 6597b005c481..a6cb6a040d0a 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -7,7 +7,7 @@ namespace Microsoft.AutoGen.Core; public class UninitializedAgentWorker() : IAgentWorker { public IServiceProvider ServiceProvider => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - internal const string AgentNotInitializedMessage = "Agent not initialized correctly. An Agent should never be directly intialized - it is always started byt the AgentWorker from the Runtime."; + internal const string AgentNotInitializedMessage = "Agent not initialized correctly. An Agent should never be directly intialized - it is always started by the AgentWorker from the Runtime."; public ValueTask PublishEventAsync(CloudEvent evt, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index f4282fe86615..eda96fad37b8 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -53,8 +53,8 @@ public async Task ItInvokeRightHandlerTestAsync() { var agent = new TestAgent(new AgentsMetadata(TypeRegistry.Empty, new Dictionary(), new Dictionary>(), new Dictionary>()), new Logger(new LoggerFactory())); - await agent.HandleObject("hello world"); - await agent.HandleObject(42); + await agent.HandleObjectAsync("hello world"); + await agent.HandleObjectAsync(42); agent.ReceivedItems.Should().HaveCount(2); agent.ReceivedItems[0].Should().Be("hello world"); @@ -65,7 +65,6 @@ public async Task ItInvokeRightHandlerTestAsync() public async Task ItDelegateMessageToTestAgentAsync() { var client = _fixture.AppHost.Services.GetRequiredService(); - await client.PublishMessageAsync(new TextMessage() { Source = nameof(ItDelegateMessageToTestAgentAsync), @@ -94,7 +93,16 @@ public Task Handle(TextMessage item, CancellationToken cancellationToken = defau ReceivedMessages[item.Source] = item.TextMessage_; return Task.CompletedTask; } - + public Task Handle(string item) + { + ReceivedItems.Add(item); + return Task.CompletedTask; + } + public Task Handle(int item) + { + ReceivedItems.Add(item); + return Task.CompletedTask; + } public List ReceivedItems { get; private set; } = []; /// From e3db41e40de96dd34a6295659f756aab89f4cb26 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 20 Dec 2024 10:50:59 -0800 Subject: [PATCH 013/110] improve the error for uninitialized agents --- dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index a6cb6a040d0a..e89236314842 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -7,7 +7,7 @@ namespace Microsoft.AutoGen.Core; public class UninitializedAgentWorker() : IAgentWorker { public IServiceProvider ServiceProvider => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - internal const string AgentNotInitializedMessage = "Agent not initialized correctly. An Agent should never be directly intialized - it is always started by the AgentWorker from the Runtime."; + internal const string AgentNotInitializedMessage = "Agent not initialized correctly. An Agent should never be directly intialized - it is always started by the AgentWorker from the Runtime (using the static Initialize() method)."; public ValueTask PublishEventAsync(CloudEvent evt, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); From c7cf200a661ebe6d1d11d9d41a5ba3dfb6cd73ae Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 20 Dec 2024 15:41:13 -0800 Subject: [PATCH 014/110] move message extensions and update AgentWorker --- .../Contracts/MessageExtensions.cs | 49 ---------- .../Core.Grpc/GrpcAgentWorker.cs | 5 + dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 23 +++-- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 88 +++++++++++++---- .../Microsoft.AutoGen/Core/IAgentWorker.cs | 1 + .../Core/MessageExtensions.cs | 96 +++++++++++++++++++ .../Core/UninitializedAgentWorker.cs | 1 + .../TestAgent.cs | 4 +- 8 files changed, 192 insertions(+), 75 deletions(-) delete mode 100644 dotnet/src/Microsoft.AutoGen/Contracts/MessageExtensions.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs diff --git a/dotnet/src/Microsoft.AutoGen/Contracts/MessageExtensions.cs b/dotnet/src/Microsoft.AutoGen/Contracts/MessageExtensions.cs deleted file mode 100644 index c531c5b76ec3..000000000000 --- a/dotnet/src/Microsoft.AutoGen/Contracts/MessageExtensions.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// MessageExtensions.cs - -using Google.Protobuf; -using Google.Protobuf.WellKnownTypes; - -namespace Microsoft.AutoGen.Contracts; - -public static class MessageExtensions -{ - private const string PROTO_DATA_CONTENT_TYPE = "application/x-protobuf"; - public static CloudEvent ToCloudEvent(this T message, string source) where T : IMessage - { - return new CloudEvent - { - ProtoData = Any.Pack(message), - Type = message.Descriptor.FullName, - Source = source, - Id = Guid.NewGuid().ToString(), - SpecVersion = "1.0", - Attributes = { { "datacontenttype", new CloudEvent.Types.CloudEventAttributeValue { CeString = PROTO_DATA_CONTENT_TYPE } } } - }; - } - public static T FromCloudEvent(this CloudEvent cloudEvent) where T : IMessage, new() - { - return cloudEvent.ProtoData.Unpack(); - } - public static AgentState ToAgentState(this T state, AgentId agentId, string eTag) where T : IMessage - { - return new AgentState - { - ProtoData = Any.Pack(state), - AgentId = agentId, - ETag = eTag - }; - } - - public static T FromAgentState(this AgentState state) where T : IMessage, new() - { - if (state.HasTextData == true) - { - if (typeof(T) == typeof(AgentState)) - { - return (T)(IMessage)state; - } - } - return state.ProtoData.Unpack(); - } -} diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index e63e2a1a5737..71209d4ed4d7 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -396,5 +396,10 @@ public async ValueTask ReadAsync(AgentId agentId, CancellationToken throw new KeyNotFoundException($"Failed to read AgentState for {agentId}."); } } + + public ValueTask> GetSubscriptionsAsync(Type type) + { + throw new NotImplementedException(); + } } diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 3ce1a0039f2c..fb7e964381c5 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -175,6 +175,10 @@ await this.InvokeWithActivityAsync( break; } } + public async ValueTask> GetSubscriptionsAsync() + { + return await Worker.GetSubscriptionsAsync(GetType()).ConfigureAwait(false); + } public List Subscribe(string topic) { Message message = new() @@ -277,14 +281,21 @@ static async (state, ct) => // Return the result from the already-completed task return await completion.Task.ConfigureAwait(false); } - - public async ValueTask PublishMessageAsync(T message, string? source = null, CancellationToken token = default) where T : IMessage + /// + /// Publishes a message asynchronously. + /// + /// The type of the message. + /// The message to publish. + /// The source of the message. + /// A token to cancel the operation. + /// A task representing the asynchronous operation. + public async ValueTask PublishMessageAsync(T @event, string? topic = null, string? key = null, CancellationToken token = default ) where T : IMessage { - var src = string.IsNullOrWhiteSpace(source) ? this.AgentId.Key : source; - var evt = message.ToCloudEvent(src); + var k = string.IsNullOrWhiteSpace(key) ? AgentId.Key : key; + var topicType = string.IsNullOrWhiteSpace(topic) ? "default" : topic; + var evt = @event.ToCloudEvent(k, topicType); await PublishEventAsync(evt, token).ConfigureAwait(false); } - public async ValueTask PublishEventAsync(CloudEvent item, CancellationToken cancellationToken = default) { var activity = s_source.StartActivity($"PublishEventAsync '{item.Type}'", ActivityKind.Client, Activity.Current?.Context ?? default); @@ -367,6 +378,6 @@ public virtual async Task HandleObjectAsync(object item, CancellationToken cance } public async ValueTask PublishEventAsync(string topic, IMessage evt, CancellationToken cancellationToken = default) { - await PublishEventAsync(evt.ToCloudEvent(topic), cancellationToken).ConfigureAwait(false); + await PublishEventAsync(evt.ToCloudEvent(key: GetType().Name, topic: topic), cancellationToken).ConfigureAwait(false); } } diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index a4bbe9aa5656..700dc20b0885 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -2,44 +2,68 @@ // AgentWorker.cs using System.Collections.Concurrent; +using System.Diagnostics; using System.Threading.Channels; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; namespace Microsoft.AutoGen.Core; -public class AgentWorker( -IHostApplicationLifetime hostApplicationLifetime, -IServiceProvider serviceProvider, -[FromKeyedServices("AgentTypes")] IEnumerable> configuredAgentTypes) : - IHostedService, - IAgentWorker +/// +/// Represents a worker that manages agents and handles messages. +/// +public class AgentWorker : IHostedService, IAgentWorker { private readonly ConcurrentDictionary _agentTypes = new(); private readonly ConcurrentDictionary<(string Type, string Key), Agent> _agents = new(); + private readonly ILogger _logger; private readonly Channel _mailbox = Channel.CreateUnbounded(); private readonly ConcurrentDictionary _agentStates = new(); private readonly ConcurrentDictionary _pendingClientRequests = new(); - private readonly CancellationTokenSource _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); - public IServiceProvider ServiceProvider { get; } = serviceProvider; - private readonly IEnumerable> _configuredAgentTypes = configuredAgentTypes; - private readonly ConcurrentDictionary _subscriptionsByAgentType = new(); - private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); + private readonly CancellationTokenSource _shutdownCts; + public IServiceProvider ServiceProvider { get; } + private readonly IEnumerable> _configuredAgentTypes; + private readonly DistributedContextPropagator _distributedContextPropagator; private readonly CancellationTokenSource _shutdownCancellationToken = new(); private Task? _mailboxTask; private readonly object _channelLock = new(); - // this is the in-memory version - we just pass the message directly to the agent(s) that handle this type of event + /// + /// Initializes a new instance of the class. + /// + /// The application lifetime. + /// The service provider. + /// The configured agent types. + /// The logger. + /// The distributed context propagator. + public AgentWorker( + IHostApplicationLifetime hostApplicationLifetime, + IServiceProvider serviceProvider, + [FromKeyedServices("AgentTypes")] IEnumerable> configuredAgentTypes, + ILogger logger, + DistributedContextPropagator distributedContextPropagator) + { + _logger = logger; + ServiceProvider = serviceProvider; + _configuredAgentTypes = configuredAgentTypes; + _distributedContextPropagator = distributedContextPropagator; + _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); + } + + /// public async ValueTask PublishEventAsync(CloudEvent cloudEvent, CancellationToken cancellationToken = default) { foreach (var (typeName, _) in _agentTypes) { if (typeName == nameof(Client)) { continue; } - var agent = GetOrActivateAgent(new AgentId(typeName, cloudEvent.Source)); + var agent = GetOrActivateAgent(new AgentId { Type = typeName, Key = cloudEvent.GetSubject() }); agent.ReceiveMessage(new Message { CloudEvent = cloudEvent }); } } + + /// public async ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default) { var requestId = Guid.NewGuid().ToString(); @@ -47,21 +71,28 @@ public async ValueTask SendRequestAsync(Agent agent, RpcRequest request, Cancell request.RequestId = requestId; await _mailbox.Writer.WriteAsync(request, cancellationToken).ConfigureAwait(false); } + + /// public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) { return _mailbox.Writer.WriteAsync(new Message { Response = response }, cancellationToken); } + + /// public ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default) { return _mailbox.Writer.WriteAsync(message, cancellationToken); } + + /// public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) { var agentId = value.AgentId ?? throw new InvalidOperationException("AgentId is required when saving AgentState."); - // add or update _agentStates with the new state var response = _agentStates.AddOrUpdate(agentId.ToString(), value, (key, oldValue) => value); return ValueTask.CompletedTask; } + + /// public ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) { _agentStates.TryGetValue(agentId.ToString(), out var state); @@ -74,6 +105,10 @@ public ValueTask ReadAsync(AgentId agentId, CancellationToken cancel throw new KeyNotFoundException($"Failed to read AgentState for {agentId}."); } } + + /// + /// Runs the message pump. + /// public async Task RunMessagePump() { await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding); @@ -162,6 +197,8 @@ void StartCore() } } } + + /// public async Task StopAsync(CancellationToken cancellationToken) { _shutdownCts.Cancel(); @@ -176,16 +213,26 @@ public async Task StopAsync(CancellationToken cancellationToken) { } } + + /// + /// Gets or activates an agent. + /// + /// The agent ID. + /// The activated agent. + private Agent GetOrActivateAgent(AgentId agentId) { if (!_agents.TryGetValue((agentId.Type, agentId.Key), out var agent)) { if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { - agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType); - Agent.Initialize(this, agent); - _agents.TryAdd((agentId.Type, agentId.Key), agent); - + using (var scope = ServiceProvider.CreateScope()) + { + var scopedProvider = scope.ServiceProvider; + agent = (Agent)ActivatorUtilities.CreateInstance(scopedProvider, agentType); + Agent.Initialize(this, agent); + _agents.TryAdd((agentId.Type, agentId.Key), agent); + } } else { @@ -195,4 +242,9 @@ private Agent GetOrActivateAgent(AgentId agentId) return agent; } + + public ValueTask> GetSubscriptionsAsync(Type type) + { + throw new NotImplementedException(); + } } diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs index 13e18cf6f8d0..ad22df9cd08a 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs @@ -12,4 +12,5 @@ public interface IAgentWorker ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default); ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default); ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); + ValueTask> GetSubscriptionsAsync(Type type); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs new file mode 100644 index 000000000000..5ac9d43cf092 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MessageExtensions.cs + +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Core; + +/// +/// Provides extension methods for converting messages to and from various formats. +/// +public static class MessageExtensions +{ + private const string PROTO_DATA_CONTENT_TYPE = "application/x-protobuf"; + + /// + /// Converts a message to a CloudEvent. + /// + /// The type of the message. + /// The message to convert. + /// The key of the event, maps to the Topic Type + /// The topic of the event, + /// A CloudEvent representing the message. + public static CloudEvent ToCloudEvent(this T message, string key, string topic) where T : IMessage + { + return new CloudEvent + { + ProtoData = Any.Pack(message), + Type = message.Descriptor.FullName, + Source = topic, + Id = Guid.NewGuid().ToString(), + Attributes = { + { + "datacontenttype", new CloudEvent.Types.CloudEventAttributeValue { CeString = PROTO_DATA_CONTENT_TYPE } + }, + { + "subject", new CloudEvent.Types.CloudEventAttributeValue { CeString = key } + } + } + }; + } + + /// + /// Converts a CloudEvent back to a message. + /// + /// The type of the message. + /// The CloudEvent to convert. + /// The message represented by the CloudEvent. + public static T FromCloudEvent(this CloudEvent cloudEvent) where T : IMessage, new() + { + return cloudEvent.ProtoData.Unpack(); + } + + /// + public static string GetSubject(this CloudEvent cloudEvent) + { + return cloudEvent.Attributes["subject"].CeString; + } + + /// + /// Converts a state to an AgentState. + /// + /// The type of the state. + /// The state to convert. + /// The ID of the agent. + /// The ETag of the state. + /// An AgentState representing the state. + public static AgentState ToAgentState(this T state, AgentId agentId, string eTag) where T : IMessage + { + return new AgentState + { + ProtoData = Any.Pack(state), + AgentId = agentId, + ETag = eTag + }; + } + + /// + /// Converts an AgentState back to a state. + /// + /// The type of the state. + /// The AgentState to convert. + /// The state represented by the AgentState. + public static T FromAgentState(this AgentState state) where T : IMessage, new() + { + if (state.HasTextData == true) + { + if (typeof(T) == typeof(AgentState)) + { + return (T)(IMessage)state; + } + } + return state.ProtoData.Unpack(); + } +} diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index e89236314842..7719a294fa48 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -14,6 +14,7 @@ public class UninitializedAgentWorker() : IAgentWorker public ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask> GetSubscriptionsAsync(Type type) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public class AgentInitalizedIncorrectlyException(string message) : Exception(message) { } diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs index fc8260f51d8b..1b3c10350a6c 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs @@ -19,7 +19,7 @@ public async Task Handle(NewMessageReceived item, CancellationToken cancellation { ReceivedMessages[AgentId.Key] = item.Message; var hello = new Hello { Message = item.Message }; - await PublishEventAsync(hello); + await PublishMessageAsync(hello); } public Task Handle(GoodBye item, CancellationToken cancellationToken) { @@ -39,7 +39,7 @@ public async Task Handle(Hello item, CancellationToken cancellationToken) { _logger.LogInformation($"Received Hello message {item.Message}"); ReceivedMessages[AgentId.Key] = item.Message; - await PublishEventAsync(new GoodBye { Message = "" }); + await PublishMessageAsync(new GoodBye { Message = "" }); } public static ConcurrentDictionary ReceivedMessages { get; private set; } = new(); From e42123c234079a50558210e6e77aa63b600560e4 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 21 Dec 2024 21:05:03 -0800 Subject: [PATCH 015/110] getting it all to build --- README.md | 6 +- dotnet/AutoGen.sln | 28 +--- .../Hello/HelloAIAgents/HelloAIAgent.cs | 6 +- dotnet/samples/Hello/HelloAIAgents/Program.cs | 8 +- dotnet/samples/Hello/HelloAgent/Program.cs | 2 +- dotnet/samples/Hello/HelloAgent/README.md | 8 +- .../samples/Hello/HelloAgentState/Program.cs | 10 +- .../samples/Hello/HelloAgentState/README.md | 8 +- .../DevTeam.AgentHost.csproj | 17 --- .../dev-team/DevTeam.AgentHost/Program.cs | 15 --- .../Properties/launchSettings.json | 12 -- .../appsettings.Development.json | 8 -- .../DevTeam.Agents/DevTeam.Agents.csproj | 18 --- .../DevTeam.Agents/Developer/Developer.cs | 63 --------- .../DeveloperLead/DeveloperLead.cs | 70 ---------- .../ProductManager/ProductManager.cs | 63 --------- .../dev-team/DevTeam.Agents/Program.cs | 23 ---- .../Properties/launchSettings.json | 12 -- .../appsettings.Development.json | 8 -- .../DevTeam.AppHost/DevTeam.AppHost.csproj | 2 - .../dev-team/DevTeam.AppHost/Program.cs | 32 ++--- .../Properties/launchSettings.json | 29 +++++ .../DevTeam.Backend/Agents/AzureGenie.cs | 18 +-- .../Agents/Developer/Developer.cs | 60 +++++++++ .../Agents}/Developer/DeveloperPrompts.cs | 2 +- .../Agents/DeveloperLead/DeveloperLead.cs | 65 ++++++++++ .../DeveloperLead/DeveloperLeadPrompts.cs | 2 +- .../dev-team/DevTeam.Backend/Agents/Hubber.cs | 26 ++-- .../Agents}/ProductManager/PMPrompts.cs | 2 +- .../Agents/ProductManager/ProductManager.cs | 59 +++++++++ .../DevTeam.Backend/Agents/Sandbox.cs | 2 +- .../dev-team/DevTeam.Backend/AiAgent.cs | 23 ++++ .../dev-team/DevTeam.Backend/Consts.cs | 9 ++ .../DevTeam.Backend/DevTeam.Backend.csproj | 24 ++-- .../Models/DevPlan.cs | 0 .../Options/AzureOptions.cs | 0 .../Options/GithubOptions.cs | 0 .../dev-team/DevTeam.Backend/Program.cs | 22 ++-- .../DevTeam.Backend/Services/AzureService.cs | 2 +- .../Services/GithubAuthService.cs | 2 +- .../DevTeam.Backend/Services/GithubService.cs | 2 +- .../Services/GithubWebHookProcessor.cs | 32 ++--- .../DevTeam.ServiceDefaults.csproj | 22 ++++ .../DevTeam.ServiceDefaults/Extensions.cs | 120 ++++++++++++++++++ .../DevTeam.Shared/DevTeam.Shared.csproj | 27 ---- .../DevTeam.Shared/EventExtensions.cs | 51 -------- .../DevTeam.Shared/ParseExtensions.cs | 18 --- dotnet/samples/dev-team/Protos/messages.proto | 2 +- dotnet/samples/dev-team/Protos/states.proto | 2 +- dotnet/samples/dev-team/dev team.sln | 49 ------- .../Agents/AIAgent/InferenceAgent.cs | 5 +- .../Agents/AIAgent/SKAiAgent.cs | 2 - .../IOAgent/ConsoleAgent/ConsoleAgent.cs | 6 +- .../IOAgent/ConsoleAgent/IHandleConsole.cs | 2 +- .../Agents/IOAgent/FileAgent/FileAgent.cs | 9 +- .../Agents/IOAgent/IOAgent.cs | 6 +- .../Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs | 7 +- .../Core.Grpc/GrpcAgentWorker.cs | 16 ++- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 14 +- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 78 +++++------- .../Microsoft.AutoGen/Core/IAgentWorker.cs | 4 +- .../Core/UninitializedAgentWorker.cs | 4 +- .../Runtime.Grpc/Abstractions/IGateway.cs | 2 +- .../Runtime.Grpc/Abstractions/IRegistry.cs | 4 +- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 16 +-- .../Services/Grpc/GrpcGatewayService.cs | 2 +- .../Services/Orleans/RegistryGrain.cs | 4 +- ...ate.cs => SubscriptionRequestSurrogate.cs} | 20 +-- ...te.cs => SubscriptionResponseSurrogate.cs} | 20 +-- .../AgentTests.cs | 2 + .../GrpcGatewayServiceTests.cs | 1 + .../TestAgent.cs | 4 +- protos/agent_worker.proto | 11 +- .../runtimes/grpc/_worker_runtime.py | 12 +- .../grpc/_worker_runtime_host_servicer.py | 10 +- .../runtimes/grpc/protos/agent_worker_pb2.py | 48 +++---- .../runtimes/grpc/protos/agent_worker_pb2.pyi | 36 ++++-- .../grpc/protos/agent_worker_pb2_grpc.py | 99 +++++++++++++++ .../grpc/protos/agent_worker_pb2_grpc.pyi | 51 ++++++++ 79 files changed, 821 insertions(+), 765 deletions(-) delete mode 100644 dotnet/samples/dev-team/DevTeam.AgentHost/DevTeam.AgentHost.csproj delete mode 100644 dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.AgentHost/Properties/launchSettings.json delete mode 100644 dotnet/samples/dev-team/DevTeam.AgentHost/appsettings.Development.json delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/DevTeam.Agents.csproj delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/Developer/Developer.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLead.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/ProductManager/ProductManager.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/Program.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/Properties/launchSettings.json delete mode 100644 dotnet/samples/dev-team/DevTeam.Agents/appsettings.Development.json create mode 100644 dotnet/samples/dev-team/DevTeam.AppHost/Properties/launchSettings.json create mode 100644 dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/Developer.cs rename dotnet/samples/dev-team/{DevTeam.Agents => DevTeam.Backend/Agents}/Developer/DeveloperPrompts.cs (98%) create mode 100644 dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLead.cs rename dotnet/samples/dev-team/{DevTeam.Agents => DevTeam.Backend/Agents}/DeveloperLead/DeveloperLeadPrompts.cs (98%) rename dotnet/samples/dev-team/{DevTeam.Agents => DevTeam.Backend/Agents}/ProductManager/PMPrompts.cs (97%) create mode 100644 dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/ProductManager.cs create mode 100644 dotnet/samples/dev-team/DevTeam.Backend/AiAgent.cs create mode 100644 dotnet/samples/dev-team/DevTeam.Backend/Consts.cs rename dotnet/samples/dev-team/{DevTeam.Shared => DevTeam.Backend}/Models/DevPlan.cs (100%) rename dotnet/samples/dev-team/{DevTeam.Shared => DevTeam.Backend}/Options/AzureOptions.cs (100%) rename dotnet/samples/dev-team/{DevTeam.Shared => DevTeam.Backend}/Options/GithubOptions.cs (100%) create mode 100644 dotnet/samples/dev-team/DevTeam.ServiceDefaults/DevTeam.ServiceDefaults.csproj create mode 100644 dotnet/samples/dev-team/DevTeam.ServiceDefaults/Extensions.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Shared/DevTeam.Shared.csproj delete mode 100644 dotnet/samples/dev-team/DevTeam.Shared/EventExtensions.cs delete mode 100644 dotnet/samples/dev-team/DevTeam.Shared/ParseExtensions.cs delete mode 100644 dotnet/samples/dev-team/dev team.sln rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{AddSubscriptionRequestSurrogate.cs => SubscriptionRequestSurrogate.cs} (51%) rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{AddSubscriptionResponseSurrogate.cs => SubscriptionResponseSurrogate.cs} (53%) diff --git a/README.md b/README.md index 4b5fd029e5b8..6c036f8e3889 100644 --- a/README.md +++ b/README.md @@ -187,14 +187,14 @@ await app.WaitForShutdownAsync(); [TopicSubscription("agents")] public class HelloAgent( IAgentContext worker, - [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, IHandle, IHandle { - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output @@ -209,7 +209,7 @@ public class HelloAgent( }.ToCloudEvent(this.AgentId.Key); await PublishEventAsync(goodbye).ConfigureAwait(false); } - public async Task Handle(ConversationClosed item) + public async Task Handle(ConversationClosed item, CancellationToken cancellationToken = default) { var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; var evt = new Output diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 474371b3b85f..116411d25489 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -100,16 +100,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoGen.WebAPI.Sample", "sa EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DevTeam", "DevTeam", "{05B9C173-6441-4DCA-9AC4-E897EF75F331}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.AgentHost", "samples\dev-team\DevTeam.AgentHost\DevTeam.AgentHost.csproj", "{462A357B-7BB9-4927-A9FD-4FB7675898E9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Agents", "samples\dev-team\DevTeam.Agents\DevTeam.Agents.csproj", "{83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.AppHost", "samples\dev-team\DevTeam.AppHost\DevTeam.AppHost.csproj", "{63280C12-3BE3-4C4E-805E-584CDC6BC1F5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Backend", "samples\dev-team\DevTeam.Backend\DevTeam.Backend.csproj", "{EDA3EF83-FC7F-4BCF-945D-B893620EE4B1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Shared", "samples\dev-team\DevTeam.Shared\DevTeam.Shared.csproj", "{01F5D7C3-41EB-409C-9B77-A945C07FA7E8}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hello", "Hello", "{7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hello.AppHost", "samples\Hello\Hello.AppHost\Hello.AppHost.csproj", "{09A373A0-8169-409F-8C37-3FBC1654B122}" @@ -146,6 +140,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Tests.Sha EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Tests", "test\Microsoft.AutoGen.Core.Tests\Microsoft.AutoGen.Core.Tests.csproj", "{EAFFE339-26CB-4019-991D-BCCE8E7D33A1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevTeam.ServiceDefaults", "samples\dev-team\DevTeam.ServiceDefaults\DevTeam.ServiceDefaults.csproj", "{599E1971-1DA9-453F-A7A8-42510BBC95C2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -300,14 +296,6 @@ Global {4385AFCF-AB4A-49B2-BEBA-D33C950E1EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {4385AFCF-AB4A-49B2-BEBA-D33C950E1EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {4385AFCF-AB4A-49B2-BEBA-D33C950E1EE6}.Release|Any CPU.Build.0 = Release|Any CPU - {462A357B-7BB9-4927-A9FD-4FB7675898E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {462A357B-7BB9-4927-A9FD-4FB7675898E9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {462A357B-7BB9-4927-A9FD-4FB7675898E9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {462A357B-7BB9-4927-A9FD-4FB7675898E9}.Release|Any CPU.Build.0 = Release|Any CPU - {83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F}.Release|Any CPU.Build.0 = Release|Any CPU {63280C12-3BE3-4C4E-805E-584CDC6BC1F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {63280C12-3BE3-4C4E-805E-584CDC6BC1F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {63280C12-3BE3-4C4E-805E-584CDC6BC1F5}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -316,10 +304,6 @@ Global {EDA3EF83-FC7F-4BCF-945D-B893620EE4B1}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDA3EF83-FC7F-4BCF-945D-B893620EE4B1}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDA3EF83-FC7F-4BCF-945D-B893620EE4B1}.Release|Any CPU.Build.0 = Release|Any CPU - {01F5D7C3-41EB-409C-9B77-A945C07FA7E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {01F5D7C3-41EB-409C-9B77-A945C07FA7E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {01F5D7C3-41EB-409C-9B77-A945C07FA7E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {01F5D7C3-41EB-409C-9B77-A945C07FA7E8}.Release|Any CPU.Build.0 = Release|Any CPU {09A373A0-8169-409F-8C37-3FBC1654B122}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {09A373A0-8169-409F-8C37-3FBC1654B122}.Debug|Any CPU.Build.0 = Debug|Any CPU {09A373A0-8169-409F-8C37-3FBC1654B122}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -384,6 +368,10 @@ Global {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {EAFFE339-26CB-4019-991D-BCCE8E7D33A1}.Release|Any CPU.Build.0 = Release|Any CPU + {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -429,11 +417,8 @@ Global {CB8824F5-9475-451F-87E8-F2AEF2490A12} = {668726B9-77BC-45CF-B576-0F0773BF1615} {4385AFCF-AB4A-49B2-BEBA-D33C950E1EE6} = {668726B9-77BC-45CF-B576-0F0773BF1615} {05B9C173-6441-4DCA-9AC4-E897EF75F331} = {686480D7-8FEC-4ED3-9C5D-CEBE1057A7ED} - {462A357B-7BB9-4927-A9FD-4FB7675898E9} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} - {83BBB833-A2F0-4A4D-BA1B-8229FC9BCD4F} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} {63280C12-3BE3-4C4E-805E-584CDC6BC1F5} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} {EDA3EF83-FC7F-4BCF-945D-B893620EE4B1} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} - {01F5D7C3-41EB-409C-9B77-A945C07FA7E8} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45} = {686480D7-8FEC-4ED3-9C5D-CEBE1057A7ED} {09A373A0-8169-409F-8C37-3FBC1654B122} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45} {A20B9894-F352-4338-872A-F215A241D43D} = {7EB336C2-7C0A-4BC8-80C6-A3173AB8DC45} @@ -451,6 +436,7 @@ Global {0E7983BB-2602-421E-8B37-332E52870A10} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {14F90F79-580E-454D-BA7A-ED6D9723020D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} + {599E1971-1DA9-453F-A7A8-42510BBC95C2} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} diff --git a/dotnet/samples/Hello/HelloAIAgents/HelloAIAgent.cs b/dotnet/samples/Hello/HelloAIAgents/HelloAIAgent.cs index 0e195ca5b1dd..ba71b31a2017 100644 --- a/dotnet/samples/Hello/HelloAIAgents/HelloAIAgent.cs +++ b/dotnet/samples/Hello/HelloAIAgents/HelloAIAgent.cs @@ -8,17 +8,15 @@ namespace Hello; [TopicSubscription("agents")] public class HelloAIAgent( - IAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry, + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, IHostApplicationLifetime hostApplicationLifetime, IChatClient client) : HelloAgent( - worker, typeRegistry, hostApplicationLifetime), IHandle { // This Handle supercedes the one in the base class - public new async Task Handle(NewMessageReceived item) + public new async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var prompt = "Please write a limerick greeting someone with the name " + item.Message; var response = await client.CompleteAsync(prompt); diff --git a/dotnet/samples/Hello/HelloAIAgents/Program.cs b/dotnet/samples/Hello/HelloAIAgents/Program.cs index f9780d62af98..a5bf4b68ee46 100644 --- a/dotnet/samples/Hello/HelloAIAgents/Program.cs +++ b/dotnet/samples/Hello/HelloAIAgents/Program.cs @@ -33,16 +33,14 @@ namespace Hello { [TopicSubscription("agents")] public class HelloAgent( - IAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry, + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, IHostApplicationLifetime hostApplicationLifetime) : ConsoleAgent( - worker, typeRegistry), ISayHello, IHandle, IHandle { - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output @@ -57,7 +55,7 @@ public async Task Handle(NewMessageReceived item) }; await PublishMessageAsync(goodbye).ConfigureAwait(false); } - public async Task Handle(ConversationClosed item) + public async Task Handle(ConversationClosed item, CancellationToken cancellationToken = default) { var goodbye = $"********************* {item.UserId} said {item.UserMessage} ************************"; var evt = new Output diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index 9c3a038260b7..980c34f8617c 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -19,7 +19,7 @@ namespace Hello [TopicSubscription("agents")] public class HelloAgent( IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : Agent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : Agent( typeRegistry), ISayHello, IHandleConsole, diff --git a/dotnet/samples/Hello/HelloAgent/README.md b/dotnet/samples/Hello/HelloAgent/README.md index 067f04f3c30a..968f454905c3 100644 --- a/dotnet/samples/Hello/HelloAgent/README.md +++ b/dotnet/samples/Hello/HelloAgent/README.md @@ -25,10 +25,10 @@ Flow Diagram: ```mermaid %%{init: {'theme':'forest'}}%% graph LR; - A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"} + A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item, CancellationToken cancellationToken = default)"} B --> |"PublishEventAsync(Output('***Hello, World***'))"| C[ConsoleAgent] C --> D{"WriteConsole()"} - B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"} + B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item, CancellationToken cancellationToken = default)"} B --> |"PublishEventAsync(Output('***Goodbye***'))"| C E --> F{"Shutdown()"} @@ -44,14 +44,14 @@ Within that event handler you may optionally *emit* new events, which are then s TopicSubscription("HelloAgents")] public class HelloAgent( iAgentWorker worker, - [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, IHandle, IHandle { - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output diff --git a/dotnet/samples/Hello/HelloAgentState/Program.cs b/dotnet/samples/Hello/HelloAgentState/Program.cs index d882f1f42c4a..013d70786551 100644 --- a/dotnet/samples/Hello/HelloAgentState/Program.cs +++ b/dotnet/samples/Hello/HelloAgentState/Program.cs @@ -18,10 +18,8 @@ namespace Hello { [TopicSubscription("agents")] public class HelloAgent( - IAgentWorker worker, IHostApplicationLifetime hostApplicationLifetime, - [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : Agent( - worker, + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : Agent( typeRegistry), IHandleConsole, IHandle, @@ -29,7 +27,7 @@ public class HelloAgent( IHandle { private AgentState? State { get; set; } - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output @@ -57,7 +55,7 @@ await StoreAsync(new AgentState await PublishMessageAsync(new Shutdown { Message = this.AgentId.Key }).ConfigureAwait(false); } - public async Task Handle(ConversationClosed item) + public async Task Handle(ConversationClosed item, CancellationToken cancellationToken = default) { State = await ReadAsync(this.AgentId).ConfigureAwait(false); var state = JsonSerializer.Deserialize>(State.TextData) ?? new Dictionary { { "data", "No state data found" } }; @@ -74,7 +72,7 @@ await StoreAsync(new AgentState TextData = JsonSerializer.Serialize(state) }).ConfigureAwait(false); } - public async Task Handle(Shutdown item) + public async Task Handle(Shutdown item, CancellationToken cancellationToken = default) { string? workflow = null; // make sure the workflow is finished diff --git a/dotnet/samples/Hello/HelloAgentState/README.md b/dotnet/samples/Hello/HelloAgentState/README.md index c8fead8b23b1..801d79a7c8f0 100644 --- a/dotnet/samples/Hello/HelloAgentState/README.md +++ b/dotnet/samples/Hello/HelloAgentState/README.md @@ -25,10 +25,10 @@ Flow Diagram: ```mermaid %%{init: {'theme':'forest'}}%% graph LR; - A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item)"} + A[Main] --> |"PublishEventAsync(NewMessage('World'))"| B{"Handle(NewMessageReceived item, CancellationToken cancellationToken = default)"} B --> |"PublishEventAsync(Output('***Hello, World***'))"| C[ConsoleAgent] C --> D{"WriteConsole()"} - B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item)"} + B --> |"PublishEventAsync(ConversationClosed('Goodbye'))"| E{"Handle(ConversationClosed item, CancellationToken cancellationToken = default)"} B --> |"PublishEventAsync(Output('***Goodbye***'))"| C E --> F{"Shutdown()"} @@ -44,14 +44,14 @@ Within that event handler you may optionally *emit* new events, which are then s TopicSubscription("HelloAgents")] public class HelloAgent( iAgentWorker worker, - [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : ConsoleAgent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : ConsoleAgent( worker, typeRegistry), ISayHello, IHandle, IHandle { - public async Task Handle(NewMessageReceived item) + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/DevTeam.AgentHost.csproj b/dotnet/samples/dev-team/DevTeam.AgentHost/DevTeam.AgentHost.csproj deleted file mode 100644 index 4da4bfd8d7e6..000000000000 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/DevTeam.AgentHost.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net8.0 - enable - enable - - $(NoWarn);CS8002 - - - - - - - - - diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs b/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs deleted file mode 100644 index 82a2bf22ce98..000000000000 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Program.cs -using Microsoft.AutoGen.Runtime.Grpc; - -var builder = WebApplication.CreateBuilder(args); - -builder.AddServiceDefaults(); -builder.AddAgentService(); - -var app = builder.Build(); - -app.MapDefaultEndpoints(); -app.MapAgentService(); - -app.Run(); diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/Properties/launchSettings.json b/dotnet/samples/dev-team/DevTeam.AgentHost/Properties/launchSettings.json deleted file mode 100644 index c43e7586ac17..000000000000 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/Properties/launchSettings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "profiles": { - "DevTeam.AgentHost": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:50670;http://localhost:50673" - } - } -} \ No newline at end of file diff --git a/dotnet/samples/dev-team/DevTeam.AgentHost/appsettings.Development.json b/dotnet/samples/dev-team/DevTeam.AgentHost/appsettings.Development.json deleted file mode 100644 index 0c208ae9181e..000000000000 --- a/dotnet/samples/dev-team/DevTeam.AgentHost/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/DevTeam.Agents.csproj b/dotnet/samples/dev-team/DevTeam.Agents/DevTeam.Agents.csproj deleted file mode 100644 index bc70545810bc..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/DevTeam.Agents.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - - - - diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Developer/Developer.cs b/dotnet/samples/dev-team/DevTeam.Agents/Developer/Developer.cs deleted file mode 100644 index ffc474a93124..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/Developer/Developer.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Developer.cs - -using DevTeam.Shared; -using Microsoft.AutoGen.Agents; -using Microsoft.AutoGen.Contracts; -using Microsoft.AutoGen.Core; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Memory; - -namespace DevTeam.Agents; - -[TopicSubscription("devteam")] -public class Dev(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger logger) - : SKAiAgent(worker, memory, kernel, typeRegistry), IDevelopApps, - IHandle, - IHandle -{ - public async Task Handle(CodeGenerationRequested item) - { - var code = await GenerateCode(item.Ask); - var evt = new CodeGenerated - { - Org = item.Org, - Repo = item.Repo, - IssueNumber = item.IssueNumber, - Code = code - }; - await PublishMessageAsync(evt); - } - - public async Task Handle(CodeChainClosed item) - { - //TODO: Get code from state - var lastCode = ""; // _state.State.History.Last().Message - var evt = new CodeCreated - { - Code = lastCode - }; - await PublishMessageAsync(evt); - } - - public async Task GenerateCode(string ask) - { - try - { - var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; - var instruction = "Consider the following architectural guidelines:!waf!"; - var enhancedContext = await AddKnowledge(instruction, "waf", context); - return await CallFunction(DeveloperSkills.Implement, enhancedContext); - } - catch (Exception ex) - { - logger.LogError(ex, "Error generating code"); - return ""; - } - } -} - -public interface IDevelopApps -{ - public Task GenerateCode(string ask); -} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLead.cs b/dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLead.cs deleted file mode 100644 index ffeefe7d430f..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLead.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// DeveloperLead.cs - -using DevTeam.Shared; -using Microsoft.AutoGen.Agents; -using Microsoft.AutoGen.Contracts; -using Microsoft.AutoGen.Core; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Connectors.OpenAI; -using Microsoft.SemanticKernel.Memory; - -namespace DevTeam.Agents; - -[TopicSubscription("devteam")] -public class DeveloperLead(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger logger) - : SKAiAgent(worker, memory, kernel, typeRegistry), ILeadDevelopers, - IHandle, - IHandle -{ - public async Task Handle(DevPlanRequested item) - { - var plan = await CreatePlan(item.Ask); - var evt = new DevPlanGenerated - { - Org = item.Org, - Repo = item.Repo, - IssueNumber = item.IssueNumber, - Plan = plan - }; - await PublishMessageAsync(evt); - } - - public async Task Handle(DevPlanChainClosed item) - { - // TODO: Get plan from state - var lastPlan = ""; // _state.State.History.Last().Message - var evt = new DevPlanCreated - { - Plan = lastPlan - }; - await PublishMessageAsync(evt); - } - public async Task CreatePlan(string ask) - { - try - { - var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; - var instruction = "Consider the following architectural guidelines:!waf!"; - var enhancedContext = await AddKnowledge(instruction, "waf", context); - var settings = new OpenAIPromptExecutionSettings - { - ResponseFormat = "json_object", - MaxTokens = 4096, - Temperature = 0.8, - TopP = 1 - }; - return await CallFunction(DevLeadSkills.Plan, enhancedContext, settings); - } - catch (Exception ex) - { - logger.LogError(ex, "Error creating development plan"); - return ""; - } - } -} - -public interface ILeadDevelopers -{ - public Task CreatePlan(string ask); -} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/ProductManager/ProductManager.cs b/dotnet/samples/dev-team/DevTeam.Agents/ProductManager/ProductManager.cs deleted file mode 100644 index 5306a91838e3..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/ProductManager/ProductManager.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// ProductManager.cs - -using DevTeam.Shared; -using Microsoft.AutoGen.Agents; -using Microsoft.AutoGen.Contracts; -using Microsoft.AutoGen.Core; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Memory; - -namespace DevTeam.Agents; - -[TopicSubscription("devteam")] -public class ProductManager(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, ILogger logger) - : SKAiAgent(worker, memory, kernel, typeRegistry), IManageProducts, - IHandle, - IHandle -{ - public async Task Handle(ReadmeChainClosed item) - { - // TODO: Get readme from state - var lastReadme = ""; // _state.State.History.Last().Message - var evt = new ReadmeCreated - { - Readme = lastReadme - }; - await PublishMessageAsync(evt); - } - - public async Task Handle(ReadmeRequested item) - { - var readme = await CreateReadme(item.Ask); - var evt = new ReadmeGenerated - { - Readme = readme, - Org = item.Org, - Repo = item.Repo, - IssueNumber = item.IssueNumber - }; - await PublishMessageAsync(evt); - } - - public async Task CreateReadme(string ask) - { - try - { - var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; - var instruction = "Consider the following architectural guidelines:!waf!"; - var enhancedContext = await AddKnowledge(instruction, "waf", context); - return await CallFunction(PMSkills.Readme, enhancedContext); - } - catch (Exception ex) - { - logger.LogError(ex, "Error creating readme"); - return ""; - } - } -} - -public interface IManageProducts -{ - public Task CreateReadme(string ask); -} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs b/dotnet/samples/dev-team/DevTeam.Agents/Program.cs deleted file mode 100644 index bd9e4ad24832..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/Program.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Program.cs - -using DevTeam.Agents; -using Microsoft.AutoGen.Core; -using Microsoft.AutoGen.Extensions.SemanticKernel; - -var builder = WebApplication.CreateBuilder(args); - -builder.AddServiceDefaults(); - -builder.ConfigureSemanticKernel(); - -builder.AddAgentWorker(builder.Configuration["AGENT_HOST"]!) - .AddAgent(nameof(Dev)) - .AddAgent(nameof(ProductManager)) - .AddAgent(nameof(DeveloperLead)); - -var app = builder.Build(); - -app.MapDefaultEndpoints(); - -app.Run(); diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Properties/launchSettings.json b/dotnet/samples/dev-team/DevTeam.Agents/Properties/launchSettings.json deleted file mode 100644 index 8edfece6ad8d..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/Properties/launchSettings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "profiles": { - "DevTeam.Agents": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:50669;http://localhost:50671" - } - } -} \ No newline at end of file diff --git a/dotnet/samples/dev-team/DevTeam.Agents/appsettings.Development.json b/dotnet/samples/dev-team/DevTeam.Agents/appsettings.Development.json deleted file mode 100644 index 0c208ae9181e..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Agents/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/dotnet/samples/dev-team/DevTeam.AppHost/DevTeam.AppHost.csproj b/dotnet/samples/dev-team/DevTeam.AppHost/DevTeam.AppHost.csproj index 89d121b303ea..eab38e3ba71a 100644 --- a/dotnet/samples/dev-team/DevTeam.AppHost/DevTeam.AppHost.csproj +++ b/dotnet/samples/dev-team/DevTeam.AppHost/DevTeam.AppHost.csproj @@ -21,8 +21,6 @@ - - diff --git a/dotnet/samples/dev-team/DevTeam.AppHost/Program.cs b/dotnet/samples/dev-team/DevTeam.AppHost/Program.cs index 99dd61a790bc..227a35e6bcb5 100644 --- a/dotnet/samples/dev-team/DevTeam.AppHost/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.AppHost/Program.cs @@ -7,22 +7,16 @@ var qdrant = builder.AddQdrant("qdrant"); -var orleans = builder.AddOrleans("orleans") - .WithDevelopmentClustering(); +var agentHost = builder.AddContainer("agent-host", "autogen-host") + .WithEnvironment("ASPNETCORE_URLS", "https://+;http://+") + .WithEnvironment("ASPNETCORE_HTTPS_PORTS", "5001") + .WithEnvironment("ASPNETCORE_Kestrel__Certificates__Default__Password", "mysecurepass") + .WithEnvironment("ASPNETCORE_Kestrel__Certificates__Default__Path", "/https/devcert.pfx") + .WithBindMount("./certs", "/https/", true) + .WithHttpsEndpoint(targetPort: 5001); -var agentHost = builder.AddProject("agenthost") - .WithReference(orleans); var agentHostHttps = agentHost.GetEndpoint("https"); -//TODO: pass the right variables - aca environment -// var environmentId = builder.AddParameter("environmentId"); -// var acaSessions = builder.AddBicepTemplateString( -// name: "aca-sessions", -// bicepContent: BicepTemplates.Sessions -// ) -// .WithParameter("environmentId", environmentId); -// var acaSessionsEndpoint = acaSessions.GetOutput("endpoint"); - builder.AddProject("backend") .WithEnvironment("AGENT_HOST", $"{agentHostHttps.Property(EndpointProperty.Url)}") .WithEnvironment("Qdrant__Endpoint", $"{qdrant.Resource.HttpEndpoint.Property(EndpointProperty.Url)}") @@ -33,16 +27,10 @@ .WithEnvironment("Github__AppId", builder.Configuration["Github:AppId"]) .WithEnvironment("Github__InstallationId", builder.Configuration["Github:InstallationId"]) .WithEnvironment("Github__WebhookSecret", builder.Configuration["Github:WebhookSecret"]) - .WithEnvironment("Github__AppKey", builder.Configuration["Github:AppKey"]); + .WithEnvironment("Github__AppKey", builder.Configuration["Github:AppKey"]) + .WaitFor(agentHost) + .WaitFor(qdrant); //TODO: add this to the config in backend //.WithEnvironment("", acaSessionsEndpoint); -builder.AddProject("dev-agents") - .WithEnvironment("AGENT_HOST", $"{agentHostHttps.Property(EndpointProperty.Url)}") - .WithEnvironment("Qdrant__Endpoint", $"{qdrant.Resource.HttpEndpoint.Property(EndpointProperty.Url)}") - .WithEnvironment("Qdrant__ApiKey", $"{qdrant.Resource.ApiKeyParameter.Value}") - .WithEnvironment("Qdrant__VectorSize", "1536") - .WithEnvironment("OpenAI__Key", builder.Configuration["OpenAI:Key"]) - .WithEnvironment("OpenAI__Endpoint", builder.Configuration["OpenAI:Endpoint"]); - builder.Build().Run(); diff --git a/dotnet/samples/dev-team/DevTeam.AppHost/Properties/launchSettings.json b/dotnet/samples/dev-team/DevTeam.AppHost/Properties/launchSettings.json new file mode 100644 index 000000000000..eae31b662c3d --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.AppHost/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:17034;http://localhost:15043", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21249", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22030" + } + }, + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15043", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19105", + "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20096" + } + } + } + } \ No newline at end of file diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/AzureGenie.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/AzureGenie.cs index 85d498bcc5aa..59ac34ba45a3 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Agents/AzureGenie.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/AzureGenie.cs @@ -1,21 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // AzureGenie.cs -using DevTeam.Backend; -using DevTeam.Shared; -using Microsoft.AutoGen.Agents; +using DevTeam.Backend.Services; using Microsoft.AutoGen.Core; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Memory; -namespace Microsoft.AI.DevTeam; +namespace DevTeam.Backend.Agents; -public class AzureGenie(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageAzure azureService) - : SKAiAgent(worker, memory, kernel, typeRegistry), +[TopicSubscription(Consts.TopicName)] +public class AzureGenie([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, IManageAzure azureService) + : Agent(typeRegistry), IHandle, IHandle - { - public async Task Handle(ReadmeCreated item) + public async Task Handle(ReadmeCreated item, CancellationToken cancellationToken = default) { // TODO: Not sure we need to store the files if we use ACA Sessions // //var data = item.ToData(); @@ -30,7 +26,7 @@ public async Task Handle(ReadmeCreated item) await Task.CompletedTask; } - public async Task Handle(CodeCreated item) + public async Task Handle(CodeCreated item, CancellationToken cancellationToken = default) { // TODO: Not sure we need to store the files if we use ACA Sessions // //var data = item.ToData(); diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/Developer.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/Developer.cs new file mode 100644 index 000000000000..b0f52f5bd5eb --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/Developer.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Developer.cs + +using DevTeam.Agents; +using Microsoft.AutoGen.Core; + +namespace DevTeam.Backend.Agents.Developer; + +[TopicSubscription(Consts.TopicName)] +public class Dev([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, ILogger logger) + : AiAgent(typeRegistry, logger), IDevelopApps, + IHandle, + IHandle +{ + public async Task Handle(CodeGenerationRequested item, CancellationToken cancellationToken = default) + { + var code = await GenerateCode(item.Ask); + var evt = new CodeGenerated + { + Org = item.Org, + Repo = item.Repo, + IssueNumber = item.IssueNumber, + Code = code + }; + // TODO: Read the Topic from the agent metadata + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + + public async Task Handle(CodeChainClosed item, CancellationToken cancellationToken = default) + { + //TODO: Get code from state + var lastCode = ""; // _state.State.History.Last().Message + var evt = new CodeCreated + { + Code = lastCode + }; + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + + public async Task GenerateCode(string ask) + { + try + { + //var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; + //var instruction = "Consider the following architectural guidelines:!waf!"; + //var enhancedContext = await AddKnowledge(instruction, "waf"); + return await CallFunction(DeveloperSkills.Implement); + } + catch (Exception ex) + { + logger.LogError(ex, "Error generating code"); + return ""; + } + } +} + +public interface IDevelopApps +{ + public Task GenerateCode(string ask); +} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/Developer/DeveloperPrompts.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/DeveloperPrompts.cs similarity index 98% rename from dotnet/samples/dev-team/DevTeam.Agents/Developer/DeveloperPrompts.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/DeveloperPrompts.cs index d4b5a4f942d3..9b248807b656 100644 --- a/dotnet/samples/dev-team/DevTeam.Agents/Developer/DeveloperPrompts.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Developer/DeveloperPrompts.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // DeveloperPrompts.cs -namespace DevTeam.Agents; +namespace DevTeam.Backend.Agents.Developer; public static class DeveloperSkills { public const string Implement = """ diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLead.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLead.cs new file mode 100644 index 000000000000..b935d31b8f71 --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLead.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// DeveloperLead.cs + +using DevTeam.Agents; +using Microsoft.AutoGen.Core; + +namespace DevTeam.Backend.Agents.DeveloperLead; + +[TopicSubscription(Consts.TopicName)] +public class DeveloperLead([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, ILogger logger) + : AiAgent(typeRegistry, logger), ILeadDevelopers, + IHandle, + IHandle +{ + public async Task Handle(DevPlanRequested item, CancellationToken cancellationToken = default) + { + var plan = await CreatePlan(item.Ask); + var evt = new DevPlanGenerated + { + Org = item.Org, + Repo = item.Repo, + IssueNumber = item.IssueNumber, + Plan = plan + }; + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + + public async Task Handle(DevPlanChainClosed item, CancellationToken cancellationToken = default) + { + // TODO: Get plan from state + var lastPlan = ""; // _state.State.History.Last().Message + var evt = new DevPlanCreated + { + Plan = lastPlan + }; + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + public async Task CreatePlan(string ask) + { + try + { + //var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; + //var instruction = "Consider the following architectural guidelines:!waf!"; + //var enhancedContext = await AddKnowledge(instruction, "waf", context); + //var settings = new OpenAIPromptExecutionSettings + //{ + // ResponseFormat = "json_object", + // MaxTokens = 4096, + // Temperature = 0.8, + // TopP = 1 + //}; + return await CallFunction(DevLeadSkills.Plan); + } + catch (Exception ex) + { + logger.LogError(ex, "Error creating development plan"); + return ""; + } + } +} + +public interface ILeadDevelopers +{ + public Task CreatePlan(string ask); +} diff --git a/dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLeadPrompts.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLeadPrompts.cs similarity index 98% rename from dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLeadPrompts.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLeadPrompts.cs index 0aeb3b26dbb4..756052fdf4f5 100644 --- a/dotnet/samples/dev-team/DevTeam.Agents/DeveloperLead/DeveloperLeadPrompts.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/DeveloperLead/DeveloperLeadPrompts.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // DeveloperLeadPrompts.cs -namespace DevTeam.Agents; +namespace DevTeam.Backend.Agents.DeveloperLead; public static class DevLeadSkills { public const string Plan = """ diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/Hubber.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Hubber.cs index 3ba0eeb69b25..8ba4ddf923ce 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Agents/Hubber.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Hubber.cs @@ -2,18 +2,14 @@ // Hubber.cs using System.Text.Json; -using DevTeam; -using DevTeam.Backend; -using DevTeam.Shared; -using Microsoft.AutoGen.Agents; +using DevTeam.Backend.Services; using Microsoft.AutoGen.Core; -using Microsoft.SemanticKernel; -using Microsoft.SemanticKernel.Memory; -namespace Microsoft.AI.DevTeam; +namespace DevTeam.Backend.Agents; -public class Hubber(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memory, [FromKeyedServices("EventTypes")] EventTypes typeRegistry, IManageGithub ghService) - : SKAiAgent(worker, memory, kernel, typeRegistry), +[TopicSubscription(Consts.TopicName)] +public class Hubber([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, IManageGithub ghService) + : Agent(typeRegistry), IHandle, IHandle, IHandle, @@ -21,7 +17,7 @@ public class Hubber(IAgentWorker worker, Kernel kernel, ISemanticTextMemory memo IHandle, IHandle { - public async Task Handle(NewAsk item) + public async Task Handle(NewAsk item, CancellationToken cancellationToken = default) { var pmIssue = await CreateIssue(item.Org, item.Repo, item.Ask, "PM.Readme", item.IssueNumber); var devLeadIssue = await CreateIssue(item.Org, item.Repo, item.Ask, "DevLead.Plan", item.IssueNumber); @@ -30,25 +26,25 @@ public async Task Handle(NewAsk item) await CreateBranch(item.Org, item.Repo, $"sk-{item.IssueNumber}"); } - public async Task Handle(ReadmeGenerated item) + public async Task Handle(ReadmeGenerated item, CancellationToken cancellationToken = default) { var contents = string.IsNullOrEmpty(item.Readme) ? "Sorry, I got tired, can you try again please? " : item.Readme; await PostComment(item.Org, item.Repo, item.IssueNumber, contents); } - public async Task Handle(DevPlanGenerated item) + public async Task Handle(DevPlanGenerated item, CancellationToken cancellationToken = default) { var contents = string.IsNullOrEmpty(item.Plan) ? "Sorry, I got tired, can you try again please? " : item.Plan; await PostComment(item.Org, item.Repo, item.IssueNumber, contents); } - public async Task Handle(CodeGenerated item) + public async Task Handle(CodeGenerated item, CancellationToken cancellationToken = default) { var contents = string.IsNullOrEmpty(item.Code) ? "Sorry, I got tired, can you try again please? " : item.Code; await PostComment(item.Org, item.Repo, item.IssueNumber, contents); } - public async Task Handle(DevPlanCreated item) + public async Task Handle(DevPlanCreated item, CancellationToken cancellationToken = default) { var plan = JsonSerializer.Deserialize(item.Plan); var prompts = plan!.Steps.SelectMany(s => s.Subtasks!.Select(st => st.Prompt)); @@ -62,7 +58,7 @@ public async Task Handle(DevPlanCreated item) } } - public async Task Handle(ReadmeStored item) + public async Task Handle(ReadmeStored item, CancellationToken cancellationToken = default) { var branch = $"sk-{item.ParentNumber}"; await CommitToBranch(item.Org, item.Repo, item.ParentNumber, item.IssueNumber, "output", branch); diff --git a/dotnet/samples/dev-team/DevTeam.Agents/ProductManager/PMPrompts.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/PMPrompts.cs similarity index 97% rename from dotnet/samples/dev-team/DevTeam.Agents/ProductManager/PMPrompts.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/PMPrompts.cs index 08d173b1166e..b10092fb046c 100644 --- a/dotnet/samples/dev-team/DevTeam.Agents/ProductManager/PMPrompts.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/PMPrompts.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // PMPrompts.cs -namespace DevTeam.Agents; +namespace DevTeam.Backend.Agents.ProductManager; public static class PMSkills { public const string BootstrapProject = """ diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/ProductManager.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/ProductManager.cs new file mode 100644 index 000000000000..93da47e53cdd --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/ProductManager/ProductManager.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// ProductManager.cs + +using DevTeam.Agents; +using Microsoft.AutoGen.Core; + +namespace DevTeam.Backend.Agents.ProductManager; + +[TopicSubscription(Consts.TopicName)] +public class ProductManager([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, ILogger logger) + : AiAgent(typeRegistry, logger), IManageProducts, + IHandle, + IHandle +{ + public async Task Handle(ReadmeChainClosed item, CancellationToken cancellationToken = default) + { + // TODO: Get readme from state + var lastReadme = ""; // _state.State.History.Last().Message + var evt = new ReadmeCreated + { + Readme = lastReadme + }; + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + + public async Task Handle(ReadmeRequested item, CancellationToken cancellationToken = default) + { + var readme = await CreateReadme(item.Ask); + var evt = new ReadmeGenerated + { + Readme = readme, + Org = item.Org, + Repo = item.Repo, + IssueNumber = item.IssueNumber + }; + await PublishMessageAsync(evt, topic: Consts.TopicName).ConfigureAwait(false); + } + + public async Task CreateReadme(string ask) + { + try + { + //var context = new KernelArguments { ["input"] = AppendChatHistory(ask) }; + //var instruction = "Consider the following architectural guidelines:!waf!"; + //var enhancedContext = await AddKnowledge(instruction, "waf", context); + return await CallFunction(PMSkills.Readme); + } + catch (Exception ex) + { + logger.LogError(ex, "Error creating readme"); + return ""; + } + } +} + +public interface IManageProducts +{ + public Task CreateReadme(string ask); +} diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Agents/Sandbox.cs b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Sandbox.cs index 19b0db00553a..306ebc945a49 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Agents/Sandbox.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Agents/Sandbox.cs @@ -3,7 +3,7 @@ // namespace DevTeam.Backend; -// public sealed class Sandbox : Agent +// public sealed class Sandbox : AgentBase // { // private const string ReminderName = "SandboxRunReminder"; // private readonly IManageAzure _azService; diff --git a/dotnet/samples/dev-team/DevTeam.Backend/AiAgent.cs b/dotnet/samples/dev-team/DevTeam.Backend/AiAgent.cs new file mode 100644 index 000000000000..427e7bb95f32 --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.Backend/AiAgent.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AiAgent.cs + +using Microsoft.AutoGen.Core; + +namespace DevTeam.Agents; + +public class AiAgent : Agent +{ + public AiAgent(AgentsMetadata eventTypes, ILogger> logger) : base(eventTypes, logger) + { + } + + protected async Task AddKnowledge(string instruction, string v) + { + throw new NotImplementedException(); + } + + protected async Task CallFunction(string prompt) + { + throw new NotImplementedException(); + } +} diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Consts.cs b/dotnet/samples/dev-team/DevTeam.Backend/Consts.cs new file mode 100644 index 000000000000..c29f662cdfd7 --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.Backend/Consts.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Consts.cs + +namespace DevTeam.Backend; + +public class Consts +{ + public const string TopicName = "devteam"; +} diff --git a/dotnet/samples/dev-team/DevTeam.Backend/DevTeam.Backend.csproj b/dotnet/samples/dev-team/DevTeam.Backend/DevTeam.Backend.csproj index f13c0cbe4f0d..34030a8817fb 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/DevTeam.Backend.csproj +++ b/dotnet/samples/dev-team/DevTeam.Backend/DevTeam.Backend.csproj @@ -1,8 +1,4 @@ - - - - - + net8.0 @@ -12,11 +8,9 @@ + - - - @@ -26,13 +20,19 @@ + + + + + + + + - - - - + + diff --git a/dotnet/samples/dev-team/DevTeam.Shared/Models/DevPlan.cs b/dotnet/samples/dev-team/DevTeam.Backend/Models/DevPlan.cs similarity index 100% rename from dotnet/samples/dev-team/DevTeam.Shared/Models/DevPlan.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Models/DevPlan.cs diff --git a/dotnet/samples/dev-team/DevTeam.Shared/Options/AzureOptions.cs b/dotnet/samples/dev-team/DevTeam.Backend/Options/AzureOptions.cs similarity index 100% rename from dotnet/samples/dev-team/DevTeam.Shared/Options/AzureOptions.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Options/AzureOptions.cs diff --git a/dotnet/samples/dev-team/DevTeam.Shared/Options/GithubOptions.cs b/dotnet/samples/dev-team/DevTeam.Backend/Options/GithubOptions.cs similarity index 100% rename from dotnet/samples/dev-team/DevTeam.Shared/Options/GithubOptions.cs rename to dotnet/samples/dev-team/DevTeam.Backend/Options/GithubOptions.cs diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs index abc37cf12608..a2ba9021c271 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs @@ -2,29 +2,35 @@ // Program.cs using Azure.Identity; -using DevTeam.Backend; using DevTeam.Options; -using Microsoft.AI.DevTeam; -using Microsoft.AutoGen.Core; -using Microsoft.AutoGen.Extensions.SemanticKernel; using Microsoft.Extensions.Azure; using Microsoft.Extensions.Options; +using Microsoft.AutoGen.Core; using Octokit.Webhooks; using Octokit.Webhooks.AspNetCore; +using DevTeam.Backend.Services; +using DevTeam.Backend.Agents; +using DevTeam.Backend.Agents.ProductManager; +using DevTeam.Backend.Agents.DeveloperLead; +using DevTeam.Backend.Agents.Developer; +using Microsoft.AutoGen.Core.Grpc; var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); -builder.ConfigureSemanticKernel(); builder.Services.AddHttpClient(); builder.Services.AddControllers(); builder.Services.AddSwaggerGen(); -builder.AddAgentWorker(builder.Configuration["AGENT_HOST"]!) +builder.AddGrpcAgentWorker(builder.Configuration["AGENT_HOST"]!) + .AddAgentWorker() .AddAgent(nameof(AzureGenie)) //.AddAgent(nameof(Sandbox)) - .AddAgent(nameof(Hubber)); + .AddAgent(nameof(Hubber)) + .AddAgent(nameof(Dev)) + .AddAgent(nameof(ProductManager)) + .AddAgent(nameof(DeveloperLead)); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -58,7 +64,7 @@ var app = builder.Build(); -app.MapDefaultEndpoints(); +Microsoft.Extensions.Hosting.AspireHostingExtensions.MapDefaultEndpoints(app); app.UseRouting() .UseEndpoints(endpoints => { diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Services/AzureService.cs b/dotnet/samples/dev-team/DevTeam.Backend/Services/AzureService.cs index 3c3bbf07a0b7..619da62d6873 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Services/AzureService.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Services/AzureService.cs @@ -12,7 +12,7 @@ using DevTeam.Options; using Microsoft.Extensions.Options; -namespace DevTeam.Backend; +namespace DevTeam.Backend.Services; public class AzureService : IManageAzure { diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubAuthService.cs b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubAuthService.cs index d1a3bb7c08df..ba6b9564b9b5 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubAuthService.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubAuthService.cs @@ -9,7 +9,7 @@ using Microsoft.IdentityModel.Tokens; using Octokit; -namespace DevTeam.Backend; +namespace DevTeam.Backend.Services; public class GithubAuthService { private readonly GithubOptions _githubSettings; diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubService.cs b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubService.cs index 5c6dc2125fa9..1108d42e4017 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubService.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubService.cs @@ -8,7 +8,7 @@ using Octokit; using Octokit.Helpers; -namespace DevTeam.Backend; +namespace DevTeam.Backend.Services; public class GithubService : IManageGithub { diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs index 80660328ecae..7264f5621311 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs @@ -2,7 +2,7 @@ // GithubWebHookProcessor.cs using System.Globalization; -using DevTeam.Shared; +using Google.Protobuf; using Microsoft.AutoGen.Contracts; using Microsoft.AutoGen.Core; using Octokit.Webhooks; @@ -11,12 +11,12 @@ using Octokit.Webhooks.Events.Issues; using Octokit.Webhooks.Models; -namespace DevTeam.Backend; +namespace DevTeam.Backend.Services; -public sealed class GithubWebHookProcessor(ILogger logger, AgentWorker client) : WebhookEventProcessor +public sealed class GithubWebHookProcessor(ILogger logger, Client client) : WebhookEventProcessor { private readonly ILogger _logger = logger; - private readonly AgentWorker _client = client; + private readonly Client _client = client; protected override async Task ProcessIssuesWebhookAsync(WebhookHeaders headers, IssuesEvent issuesEvent, IssuesAction action) { @@ -43,7 +43,7 @@ protected override async Task ProcessIssuesWebhookAsync(WebhookHeaders headers, return; } - long? parentNumber = labels.TryGetValue("Parent", out string? value) ? long.Parse(value) : null; + long? parentNumber = labels.TryGetValue("Parent", out var value) ? long.Parse(value) : null; var skillName = labels.Keys.Where(k => k != "Parent").FirstOrDefault(); if (skillName == null) @@ -114,15 +114,15 @@ private async Task HandleClosingIssue(long issueNumber, string skillName, string { var subject = suffix + issueNumber.ToString(); - var evt = (skillName, functionName) switch + IMessage evt = (skillName, functionName) switch { - ("PM", "Readme") => new ReadmeChainClosed { }.ToCloudEvent(subject), - ("DevLead", "Plan") => new DevPlanChainClosed { }.ToCloudEvent(subject), - ("Developer", "Implement") => new CodeChainClosed { }.ToCloudEvent(subject), + ("PM", "Readme") => new ReadmeChainClosed { }, + ("DevLead", "Plan") => new DevPlanChainClosed { }, + ("Developer", "Implement") => new CodeChainClosed { }, _ => new CloudEvent() // TODO: default event }; - await _client.PublishEventAsync(evt); + await _client.PublishMessageAsync(evt, Consts.TopicName, subject); } private async Task HandleNewAsk(long issueNumber, string skillName, string functionName, string suffix, string input, string org, string repo) @@ -132,15 +132,15 @@ private async Task HandleNewAsk(long issueNumber, string skillName, string funct _logger.LogInformation("Handling new ask"); var subject = suffix + issueNumber.ToString(); - var evt = (skillName, functionName) switch + IMessage evt = (skillName, functionName) switch { - ("Do", "It") => new NewAsk { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }.ToCloudEvent(subject), - ("PM", "Readme") => new ReadmeRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }.ToCloudEvent(subject), - ("DevLead", "Plan") => new DevPlanRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }.ToCloudEvent(subject), - ("Developer", "Implement") => new CodeGenerationRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }.ToCloudEvent(subject), + ("Do", "It") => new NewAsk { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }, + ("PM", "Readme") => new ReadmeRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }, + ("DevLead", "Plan") => new DevPlanRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }, + ("Developer", "Implement") => new CodeGenerationRequested { Ask = input, IssueNumber = issueNumber, Org = org, Repo = repo }, _ => new CloudEvent() }; - await _client.PublishEventAsync(evt); + await _client.PublishMessageAsync(evt, Consts.TopicName, subject); } catch (Exception ex) { diff --git a/dotnet/samples/dev-team/DevTeam.ServiceDefaults/DevTeam.ServiceDefaults.csproj b/dotnet/samples/dev-team/DevTeam.ServiceDefaults/DevTeam.ServiceDefaults.csproj new file mode 100644 index 000000000000..2388aea655b8 --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.ServiceDefaults/DevTeam.ServiceDefaults.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + + + + + + diff --git a/dotnet/samples/dev-team/DevTeam.ServiceDefaults/Extensions.cs b/dotnet/samples/dev-team/DevTeam.ServiceDefaults/Extensions.cs new file mode 100644 index 000000000000..adb2952115ff --- /dev/null +++ b/dotnet/samples/dev-team/DevTeam.ServiceDefaults/Extensions.cs @@ -0,0 +1,120 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Extensions.cs + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; +// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// This project should be referenced by each service project in your solution. +// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults +public static class Extensions +{ + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + builder.ConfigureOpenTelemetry(); + + builder.AddDefaultHealthChecks(); + + builder.Services.AddServiceDiscovery(); + + builder.Services.ConfigureHttpClientDefaults(http => + { + // Turn on resilience by default + http.AddStandardResilienceHandler(); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + // Uncomment the following to restrict the allowed schemes for service discovery. + // builder.Services.Configure(options => + // { + // options.AllowedSchemes = ["https"]; + // }); + + return builder; + } + + public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => + { + metrics.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation(); + }) + .WithTracing(tracing => + { + tracing.AddSource(builder.Environment.ApplicationName) + .AddAspNetCoreInstrumentation() + // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) + //.AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(); + + return builder; + } + + private static TBuilder AddOpenTelemetryExporters(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + if (useOtlpExporter) + { + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + } + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package) + //if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"])) + //{ + // builder.Services.AddOpenTelemetry() + // .UseAzureMonitor(); + //} + + return builder; + } + + public static TBuilder AddDefaultHealthChecks(this TBuilder builder) where TBuilder : IHostApplicationBuilder + { + builder.Services.AddHealthChecks() + // Add a default liveness check to ensure app is responsive + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + // Adding health checks endpoints to applications in non-development environments has security implications. + // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments. + if (app.Environment.IsDevelopment()) + { + // All health checks must pass for app to be considered ready to accept traffic after starting + app.MapHealthChecks("/health"); + + // Only health checks tagged with the "live" tag must pass for app to be considered alive + app.MapHealthChecks("/alive", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("live") + }); + } + + return app; + } +} diff --git a/dotnet/samples/dev-team/DevTeam.Shared/DevTeam.Shared.csproj b/dotnet/samples/dev-team/DevTeam.Shared/DevTeam.Shared.csproj deleted file mode 100644 index 674bba3b13ec..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Shared/DevTeam.Shared.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - net8.0 - enable - enable - - - - - - - - - - - - - - - - - diff --git a/dotnet/samples/dev-team/DevTeam.Shared/EventExtensions.cs b/dotnet/samples/dev-team/DevTeam.Shared/EventExtensions.cs deleted file mode 100644 index bbf51dcdea6f..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Shared/EventExtensions.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// EventExtensions.cs - -using System.Globalization; -using Microsoft.AutoGen.Contracts; - -namespace DevTeam; - -public static class EventExtensions -{ - public static GithubContext ToGithubContext(this Event evt) - { - ArgumentNullException.ThrowIfNull(evt); - var data = new Dictionary();// JsonSerializer.Deserialize>(evt.Data); - return new GithubContext - { - Org = data?["org"] ?? "", - Repo = data?["repo"] ?? "", - IssueNumber = data?.TryParseLong("issueNumber") ?? default, - ParentNumber = data?.TryParseLong("parentNumber") - }; - } - - public static Dictionary ToData(this Event evt) - { - ArgumentNullException.ThrowIfNull(evt); - return //JsonSerializer.Deserialize>(evt.Data) ?? - new Dictionary(); - } - public static Dictionary ToData(this GithubContext context) - { - ArgumentNullException.ThrowIfNull(context); - - return new Dictionary { - { "org", context.Org }, - { "repo", context.Repo }, - { "issueNumber", $"{context.IssueNumber}" }, - { "parentNumber", context.ParentNumber?.ToString(CultureInfo.InvariantCulture) ?? "" } - }; - } -} - -public class GithubContext -{ - public required string Org { get; set; } - public required string Repo { get; set; } - public long IssueNumber { get; set; } - public long? ParentNumber { get; set; } - - public string Subject => $"{Org}/{Repo}/{IssueNumber}"; -} diff --git a/dotnet/samples/dev-team/DevTeam.Shared/ParseExtensions.cs b/dotnet/samples/dev-team/DevTeam.Shared/ParseExtensions.cs deleted file mode 100644 index c4681513dd10..000000000000 --- a/dotnet/samples/dev-team/DevTeam.Shared/ParseExtensions.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// ParseExtensions.cs - -namespace DevTeam; - -public static class ParseExtensions -{ - public static long TryParseLong(this Dictionary data, string key) - { - ArgumentNullException.ThrowIfNull(data); - - if (data.TryGetValue(key, out string? value) && !string.IsNullOrEmpty(value) && long.TryParse(value, out var result)) - { - return result; - } - return default; - } -} diff --git a/dotnet/samples/dev-team/Protos/messages.proto b/dotnet/samples/dev-team/Protos/messages.proto index 23db04a439f1..05861668b966 100644 --- a/dotnet/samples/dev-team/Protos/messages.proto +++ b/dotnet/samples/dev-team/Protos/messages.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package devteam; -option csharp_namespace = "DevTeam.Shared"; +option csharp_namespace = "DevTeam"; message NewAsk { string org = 1; diff --git a/dotnet/samples/dev-team/Protos/states.proto b/dotnet/samples/dev-team/Protos/states.proto index 4aaec1090639..b093aa1ad2ad 100644 --- a/dotnet/samples/dev-team/Protos/states.proto +++ b/dotnet/samples/dev-team/Protos/states.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package devteam; -option csharp_namespace = "DevTeam.Shared"; +option csharp_namespace = "DevTeam"; message DeveloperState { diff --git a/dotnet/samples/dev-team/dev team.sln b/dotnet/samples/dev-team/dev team.sln deleted file mode 100644 index f8a7aeacd924..000000000000 --- a/dotnet/samples/dev-team/dev team.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.11.35327.3 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.AgentHost", "DevTeam.AgentHost\DevTeam.AgentHost.csproj", "{A6FC8B01-A177-4690-BD16-73EE3D0C06A0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Backend", "DevTeam.Backend\DevTeam.Backend.csproj", "{2D4BAD10-85F3-4E4B-B759-13449A212A96}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Agents", "DevTeam.Agents\DevTeam.Agents.csproj", "{A51CE540-72B0-4271-B63D-A30CAB61C227}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.AppHost", "DevTeam.AppHost\DevTeam.AppHost.csproj", "{2B8A3C64-9F4E-4CC5-9466-AFFD8E676D2E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevTeam.Shared", "DevTeam.Shared\DevTeam.Shared.csproj", "{557701A5-35D8-4CE3-BA75-D5412B4227F5}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A6FC8B01-A177-4690-BD16-73EE3D0C06A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6FC8B01-A177-4690-BD16-73EE3D0C06A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6FC8B01-A177-4690-BD16-73EE3D0C06A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6FC8B01-A177-4690-BD16-73EE3D0C06A0}.Release|Any CPU.Build.0 = Release|Any CPU - {2D4BAD10-85F3-4E4B-B759-13449A212A96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2D4BAD10-85F3-4E4B-B759-13449A212A96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2D4BAD10-85F3-4E4B-B759-13449A212A96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2D4BAD10-85F3-4E4B-B759-13449A212A96}.Release|Any CPU.Build.0 = Release|Any CPU - {A51CE540-72B0-4271-B63D-A30CAB61C227}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A51CE540-72B0-4271-B63D-A30CAB61C227}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A51CE540-72B0-4271-B63D-A30CAB61C227}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A51CE540-72B0-4271-B63D-A30CAB61C227}.Release|Any CPU.Build.0 = Release|Any CPU - {2B8A3C64-9F4E-4CC5-9466-AFFD8E676D2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2B8A3C64-9F4E-4CC5-9466-AFFD8E676D2E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2B8A3C64-9F4E-4CC5-9466-AFFD8E676D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2B8A3C64-9F4E-4CC5-9466-AFFD8E676D2E}.Release|Any CPU.Build.0 = Release|Any CPU - {557701A5-35D8-4CE3-BA75-D5412B4227F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {557701A5-35D8-4CE3-BA75-D5412B4227F5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {557701A5-35D8-4CE3-BA75-D5412B4227F5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {557701A5-35D8-4CE3-BA75-D5412B4227F5}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {DE04DB59-B8CD-4305-875B-E71442345CCF} - EndGlobalSection -EndGlobal diff --git a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs index bfcd7c6cc179..750643846fac 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/InferenceAgent.cs @@ -5,10 +5,9 @@ using Microsoft.Extensions.AI; namespace Microsoft.AutoGen.Agents; public abstract class InferenceAgent( - IAgentWorker worker, - EventTypes typeRegistry, + AgentsMetadata typeRegistry, IChatClient client) - : Agent(worker, typeRegistry) + : Agent(typeRegistry) where T : IMessage, new() { protected IChatClient ChatClient { get; } = client; diff --git a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs index 210c2054686e..1c1509d263f8 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/AIAgent/SKAiAgent.cs @@ -9,11 +9,9 @@ namespace Microsoft.AutoGen.Agents; public abstract class SKAiAgent( - IAgentWorker worker, ISemanticTextMemory memory, Kernel kernel, AgentsMetadata typeRegistry) : Agent( - worker, typeRegistry) where T : class, new() { protected AgentState _state = new(); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs index 03b654741704..2f71d2976bc1 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/ConsoleAgent.cs @@ -13,11 +13,11 @@ public abstract class ConsoleAgent : IOAgent, { // instead of the primary constructor above, make a constructr here that still calls the base constructor - public ConsoleAgent(IAgentWorker worker, [FromKeyedServices("EventTypes")] AgentsMetadata typeRegistry) : base(worker, typeRegistry) + public ConsoleAgent([FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : base(typeRegistry) { _route = "console"; } - public override async Task Handle(Input item) + public override async Task Handle(Input item, CancellationToken cancellationToken) { Console.WriteLine("Please enter input:"); string content = Console.ReadLine() ?? string.Empty; @@ -31,7 +31,7 @@ public override async Task Handle(Input item) await PublishMessageAsync(evt); } - public override async Task Handle(Output item) + public override async Task Handle(Output item, CancellationToken cancellationToken) { // Assuming item has a property `Content` that we want to write to the console Console.WriteLine(item.Message); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs index dced31aac23a..cd0fa71eca0d 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs @@ -10,7 +10,7 @@ namespace Microsoft.AutoGen.Agents; public interface IHandleConsole : IHandle, IHandle { AgentId AgentId { get; } - ValueTask PublishMessageAsync(T message, string? source = null, CancellationToken token = default) where T : IMessage; + ValueTask PublishMessageAsync(T message, string? source = null, string? key = null, CancellationToken token = default) where T : IMessage; async Task IHandle.Handle(Output item, CancellationToken cancellationToken) { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/FileAgent/FileAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/FileAgent/FileAgent.cs index ddab8a61ed58..a1d385286937 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/FileAgent/FileAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/FileAgent/FileAgent.cs @@ -9,16 +9,15 @@ namespace Microsoft.AutoGen.Agents; [TopicSubscription("FileIO")] public abstract class FileAgent( - IAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry, + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, string inputPath = "input.txt", string outputPath = "output.txt" - ) : IOAgent(worker, typeRegistry), + ) : IOAgent(typeRegistry), IUseFiles, IHandle, IHandle { - public override async Task Handle(Input item) + public override async Task Handle(Input item, CancellationToken cancellationToken = default) { // validate that the file exists if (!File.Exists(inputPath)) @@ -46,7 +45,7 @@ public override async Task Handle(Input item) }; await PublishMessageAsync(evt); } - public override async Task Handle(Output item) + public override async Task Handle(Output item, CancellationToken cancellationToken = default) { using (var writer = new StreamWriter(outputPath, append: true)) { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/IOAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/IOAgent.cs index e2b53d694885..6f2ab5a76dba 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/IOAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/IOAgent.cs @@ -5,11 +5,11 @@ using Microsoft.AutoGen.Core; namespace Microsoft.AutoGen.Agents; -public abstract class IOAgent(IAgentWorker worker, EventTypes eventTypes) : Agent(worker, eventTypes) +public abstract class IOAgent(AgentsMetadata eventTypes) : Agent(eventTypes) { public string _route = "base"; - public virtual async Task Handle(Input item) + public virtual async Task Handle(Input item, CancellationToken cancellationToken) { var evt = new InputProcessed @@ -19,7 +19,7 @@ public virtual async Task Handle(Input item) await PublishMessageAsync(evt); } - public virtual async Task Handle(Output item) + public virtual async Task Handle(Output item, CancellationToken cancellationToken) { var evt = new OutputWritten { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs index 3e43096bee29..a94d8d1813e6 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/WebAPIAgent/WebAPIAgent.cs @@ -18,10 +18,9 @@ public abstract class WebAPIAgent : IOAgent, public WebAPIAgent( IAgentWorker worker, - [FromKeyedServices("EventTypes")] EventTypes typeRegistry, + [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, ILogger logger, string url = "/agents/webio") : base( - worker, typeRegistry) { _url = url; @@ -53,7 +52,7 @@ public WebAPIAgent( app.Run(); } - public override async Task Handle(Input item) + public override async Task Handle(Input item, CancellationToken cancellationToken = default) { // Process the input (this is a placeholder, replace with actual processing logic) await ProcessInput(item.Message); @@ -65,7 +64,7 @@ public override async Task Handle(Input item) await PublishMessageAsync(evt); } - public override async Task Handle(Output item) + public override async Task Handle(Output item, CancellationToken cancellationToken = default) { // Assuming item has a property `Content` that we want to return in the response var evt = new OutputWritten diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 71209d4ed4d7..29d3be57d4c2 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -216,7 +216,7 @@ await WriteChannelAsync(new Message { var subscriptionRequest = new Message { - AddSubscriptionRequest = new AddSubscriptionRequest + SubscriptionRequest = new SubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -234,7 +234,7 @@ await WriteChannelAsync(new Message { subscriptionRequest = new Message { - AddSubscriptionRequest = new AddSubscriptionRequest + SubscriptionRequest = new SubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -397,7 +397,17 @@ public async ValueTask ReadAsync(AgentId agentId, CancellationToken } } - public ValueTask> GetSubscriptionsAsync(Type type) + public ValueTask> GetSubscriptionsAsync(Type type) + { + throw new NotImplementedException(); + } + + public ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index fb7e964381c5..50a29203d4c7 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -49,10 +49,8 @@ protected Agent( public static void Initialize(IAgentWorker worker, Agent agent) { agent.Worker = worker; - agent.Start().ContinueWith(async startTask => - { - await agent.AddImplicitSubscriptionsAsync(); - }, TaskScheduler.Default); + agent.Start().Wait(); + agent.AddImplicitSubscriptionsAsync().AsTask().Wait(); } private async ValueTask AddImplicitSubscriptionsAsync() @@ -65,7 +63,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() foreach (var topicType in topicTypes) { - var subscriptionRequest = new AddSubscriptionRequest + var subscriptionRequest = new SubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -78,7 +76,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() } }; // explicitly wait for this to complete - await Worker.SendMessageAsync(new Message { AddSubscriptionRequest = subscriptionRequest }).ConfigureAwait(true); + await Worker.SendMessageAsync(new Message { SubscriptionRequest = subscriptionRequest }).ConfigureAwait(true); } // using reflection, find all methods that Handle and subscribe to the topic T @@ -175,7 +173,7 @@ await this.InvokeWithActivityAsync( break; } } - public async ValueTask> GetSubscriptionsAsync() + public async ValueTask> GetSubscriptionsAsync() { return await Worker.GetSubscriptionsAsync(GetType()).ConfigureAwait(false); } @@ -183,7 +181,7 @@ public List Subscribe(string topic) { Message message = new() { - AddSubscriptionRequest = new() + SubscriptionRequest = new() { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 700dc20b0885..8de12f77bb4a 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -2,56 +2,41 @@ // AgentWorker.cs using System.Collections.Concurrent; -using System.Diagnostics; using System.Threading.Channels; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; namespace Microsoft.AutoGen.Core; /// /// Represents a worker that manages agents and handles messages. /// -public class AgentWorker : IHostedService, IAgentWorker +/// +/// Initializes a new instance of the class. +/// +/// The application lifetime. +/// The service provider. +/// The configured agent types. +public class AgentWorker( + IHostApplicationLifetime hostApplicationLifetime, + IServiceProvider serviceProvider, + [FromKeyedServices("AgentTypes")] IEnumerable> configuredAgentTypes) : IHostedService, IAgentWorker { private readonly ConcurrentDictionary _agentTypes = new(); private readonly ConcurrentDictionary<(string Type, string Key), Agent> _agents = new(); - private readonly ILogger _logger; private readonly Channel _mailbox = Channel.CreateUnbounded(); private readonly ConcurrentDictionary _agentStates = new(); private readonly ConcurrentDictionary _pendingClientRequests = new(); - private readonly CancellationTokenSource _shutdownCts; - public IServiceProvider ServiceProvider { get; } - private readonly IEnumerable> _configuredAgentTypes; - private readonly DistributedContextPropagator _distributedContextPropagator; + private readonly CancellationTokenSource _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); + public IServiceProvider ServiceProvider { get; } = serviceProvider; + private readonly IEnumerable> _configuredAgentTypes = configuredAgentTypes; + private readonly ConcurrentDictionary> _subscriptionsByAgentType = new(); + private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); private readonly CancellationTokenSource _shutdownCancellationToken = new(); private Task? _mailboxTask; private readonly object _channelLock = new(); - /// - /// Initializes a new instance of the class. - /// - /// The application lifetime. - /// The service provider. - /// The configured agent types. - /// The logger. - /// The distributed context propagator. - public AgentWorker( - IHostApplicationLifetime hostApplicationLifetime, - IServiceProvider serviceProvider, - [FromKeyedServices("AgentTypes")] IEnumerable> configuredAgentTypes, - ILogger logger, - DistributedContextPropagator distributedContextPropagator) - { - _logger = logger; - ServiceProvider = serviceProvider; - _configuredAgentTypes = configuredAgentTypes; - _distributedContextPropagator = distributedContextPropagator; - _shutdownCts = CancellationTokenSource.CreateLinkedTokenSource(hostApplicationLifetime.ApplicationStopping); - } - /// public async ValueTask PublishEventAsync(CloudEvent cloudEvent, CancellationToken cancellationToken = default) { @@ -129,10 +114,10 @@ public async Task RunMessagePump() agentToInvoke.ReceiveMessage(msg); } break; - case Message msg when msg.AddSubscriptionRequest != null: - await AddSubscriptionRequestAsync(msg.AddSubscriptionRequest).ConfigureAwait(true); + case Message msg when msg.SubscriptionRequest != null: + await SubscribeAsync(msg.SubscriptionRequest).ConfigureAwait(true); break; - case Message msg when msg.AddSubscriptionResponse != null: + case Message msg when msg.SubscriptionResponse != null: break; case Message msg when msg.RegisterAgentTypeResponse != null: break; @@ -149,22 +134,19 @@ public async Task RunMessagePump() } } } - private async ValueTask AddSubscriptionRequestAsync(AddSubscriptionRequest subscription) + public async ValueTask SubscribeAsync(SubscriptionRequest subscription, CancellationToken cancellationToken = default) { var topic = subscription.Subscription.TypeSubscription.TopicType; var agentType = subscription.Subscription.TypeSubscription.AgentType; - _subscriptionsByAgentType[agentType] = subscription.Subscription; + _subscriptionsByAgentType.GetOrAdd(key: agentType, _ => []).Add(subscription.Subscription); _subscriptionsByTopic.GetOrAdd(topic, _ => []).Add(agentType); - Message response = new() + var response = new SubscriptionResponse { - AddSubscriptionResponse = new() - { - RequestId = subscription.RequestId, - Error = "", - Success = true - } + RequestId = subscription.RequestId, + Error = "", + Success = true }; - await _mailbox.Writer.WriteAsync(response).ConfigureAwait(false); + return response; } public async Task StartAsync(CancellationToken cancellationToken) @@ -243,7 +225,15 @@ private Agent GetOrActivateAgent(AgentId agentId) return agent; } - public ValueTask> GetSubscriptionsAsync(Type type) + public ValueTask> GetSubscriptionsAsync(Type type) + { + if (_subscriptionsByAgentType.TryGetValue(type.Name, out var subscriptions)) + { + return new ValueTask>(subscriptions); + } + return new ValueTask>([]); + } + public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs index ad22df9cd08a..a8be598aa7ca 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs @@ -12,5 +12,7 @@ public interface IAgentWorker ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default); ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default); ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); - ValueTask> GetSubscriptionsAsync(Type type); + ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask> GetSubscriptionsAsync(Type type); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index 7719a294fa48..fec7fef60cc5 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -14,7 +14,9 @@ public class UninitializedAgentWorker() : IAgentWorker public ValueTask SendRequestAsync(Agent agent, RpcRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - public ValueTask> GetSubscriptionsAsync(Type type) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask> GetSubscriptionsAsync(Type type) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public class AgentInitalizedIncorrectlyException(string message) : Exception(message) { } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs index dd7263729378..3d7044f96d87 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs @@ -11,6 +11,6 @@ public interface IGateway : IGrainObserver ValueTask StoreAsync(Contracts.AgentState value); ValueTask ReadAsync(AgentId agentId); ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request); - ValueTask AddSubscriptionAsync(AddSubscriptionRequest request); + ValueTask AddSubscriptionAsync(SubscriptionRequest request); Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs index ffb053956ffc..31ff29a0600e 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs @@ -67,14 +67,14 @@ public interface IRegistry /// /// The subscription request. /// A task representing the asynchronous operation. - ValueTask SubscribeAsync(AddSubscriptionRequest request); + ValueTask SubscribeAsync(SubscriptionRequest request); /// /// Unsubscribes an agent from a topic. /// /// The unsubscription request. /// A task representing the asynchronous operation. - ValueTask UnsubscribeAsync(AddSubscriptionRequest request); // TODO: This should have its own request type. + ValueTask UnsubscribeAsync(SubscriptionRequest request); // TODO: This should have its own request type. /// /// Gets the subscriptions for a specified agent type. diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 7442dbb0fae5..fe76aaa6fe99 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -102,12 +102,12 @@ public async ValueTask RegisterAgentTypeAsync(Registe }; } } - public async ValueTask AddSubscriptionAsync(AddSubscriptionRequest request) + public async ValueTask AddSubscriptionAsync(SubscriptionRequest request) { try { await _gatewayRegistry.SubscribeAsync(request).ConfigureAwait(true); - return new AddSubscriptionResponse + return new SubscriptionResponse { Success = true, RequestId = request.RequestId @@ -115,7 +115,7 @@ public async ValueTask AddSubscriptionAsync(AddSubscrip } catch (Exception ex) { - return new AddSubscriptionResponse + return new SubscriptionResponse { Success = false, RequestId = request.RequestId, @@ -184,8 +184,8 @@ internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Mess case Message.MessageOneofCase.RegisterAgentTypeRequest: await RegisterAgentTypeAsync(connection, message.RegisterAgentTypeRequest); break; - case Message.MessageOneofCase.AddSubscriptionRequest: - await AddSubscriptionAsync(connection, message.AddSubscriptionRequest); + case Message.MessageOneofCase.SubscriptionRequest: + await AddSubscriptionAsync(connection, message.SubscriptionRequest); break; default: // if it wasn't recognized return bad request @@ -320,7 +320,7 @@ private static async ValueTask RespondBadRequestAsync(GrpcWorkerConnection conne { throw new RpcException(new Status(StatusCode.InvalidArgument, error)); } - private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, AddSubscriptionRequest request) + private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, SubscriptionRequest request) { var topic = ""; var agentType = ""; @@ -337,10 +337,10 @@ private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, Ad _subscriptionsByAgentType[agentType] = request.Subscription; _subscriptionsByTopic.GetOrAdd(topic, _ => []).Add(agentType); await _subscriptions.SubscribeAsync(topic, agentType); - //var response = new AddSubscriptionResponse { RequestId = request.RequestId, Error = "", Success = true }; + //var response = new SubscriptionResponse { RequestId = request.RequestId, Error = "", Success = true }; Message response = new() { - AddSubscriptionResponse = new() + SubscriptionResponse = new() { RequestId = request.RequestId, Error = "", diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index 156fab2ef191..56c5d919c3f3 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -42,7 +42,7 @@ public override async Task SaveState(AgentState request, Serv Success = true // TODO: Implement error handling }; } - public override async Task AddSubscription(AddSubscriptionRequest request, ServerCallContext context) + public override async Task AddSubscription(SubscriptionRequest request, ServerCallContext context) { request.RequestId = context.Peer; return await Gateway.AddSubscriptionAsync(request); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index d2b03e9e7e43..fab3c8b6eb63 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -172,7 +172,7 @@ private WorkerState GetOrAddWorker(IGateway worker) return null; } - public async ValueTask SubscribeAsync(AddSubscriptionRequest sub) + public async ValueTask SubscribeAsync(SubscriptionRequest sub) { switch (sub.Subscription.SubscriptionCase) { @@ -206,7 +206,7 @@ public async ValueTask SubscribeAsync(AddSubscriptionRequest sub) } await state.WriteStateAsync().ConfigureAwait(false); } - public async ValueTask UnsubscribeAsync(AddSubscriptionRequest request) + public async ValueTask UnsubscribeAsync(SubscriptionRequest request) { throw new NotImplementedException(); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs similarity index 51% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs index e732c3ffc982..f273b0b2347c 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// AddSubscriptionRequestSurrogate.cs +// SubscriptionRequestSurrogate.cs using Microsoft.AutoGen.Contracts; namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; [GenerateSerializer] -public struct AddSubscriptionRequestSurrogate +public struct SubscriptionRequestSurrogate { [Id(0)] public string RequestId; @@ -15,13 +15,13 @@ public struct AddSubscriptionRequestSurrogate } [RegisterConverter] -public sealed class AddSubscriptionRequestSurrogateConverter : - IConverter +public sealed class SubscriptionRequestSurrogateConverter : + IConverter { - public AddSubscriptionRequest ConvertFromSurrogate( - in AddSubscriptionRequestSurrogate surrogate) + public SubscriptionRequest ConvertFromSurrogate( + in SubscriptionRequestSurrogate surrogate) { - var request = new AddSubscriptionRequest() + var request = new SubscriptionRequest() { RequestId = surrogate.RequestId, Subscription = surrogate.Subscription @@ -29,9 +29,9 @@ public AddSubscriptionRequest ConvertFromSurrogate( return request; } - public AddSubscriptionRequestSurrogate ConvertToSurrogate( - in AddSubscriptionRequest value) => - new AddSubscriptionRequestSurrogate + public SubscriptionRequestSurrogate ConvertToSurrogate( + in SubscriptionRequest value) => + new SubscriptionRequestSurrogate { RequestId = value.RequestId, Subscription = value.Subscription diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs similarity index 53% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs index d35a3c5f6f89..5e8938643dcc 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// AddSubscriptionResponseSurrogate.cs +// SubscriptionResponseSurrogate.cs using Microsoft.AutoGen.Contracts; namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; [GenerateSerializer] -public struct AddSubscriptionResponseSurrogate +public struct SubscriptionResponseSurrogate { [Id(0)] public string RequestId; @@ -17,21 +17,21 @@ public struct AddSubscriptionResponseSurrogate } [RegisterConverter] -public sealed class AddSubscriptionResponseSurrogateConverter : - IConverter +public sealed class SubscriptionResponseSurrogateConverter : + IConverter { - public AddSubscriptionResponse ConvertFromSurrogate( - in AddSubscriptionResponseSurrogate surrogate) => - new AddSubscriptionResponse + public SubscriptionResponse ConvertFromSurrogate( + in SubscriptionResponseSurrogate surrogate) => + new SubscriptionResponse { RequestId = surrogate.RequestId, Success = surrogate.Success, Error = surrogate.Error }; - public AddSubscriptionResponseSurrogate ConvertToSurrogate( - in AddSubscriptionResponse value) => - new AddSubscriptionResponseSurrogate + public SubscriptionResponseSurrogate ConvertToSurrogate( + in SubscriptionResponse value) => + new SubscriptionResponseSurrogate { RequestId = value.RequestId, Success = value.Success, diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index eda96fad37b8..2fb8a3a8e638 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -46,6 +46,8 @@ public async Task Agent_ShouldInitializeCorrectly() var worker = _serviceProvider.GetRequiredService(); Agent.Initialize(worker, agent); Assert.Equal("AgentWorker", agent.Worker.GetType().Name); + var subscriptions = await agent.GetSubscriptionsAsync(); + Assert.Equal(2, subscriptions.Count); } [Fact] diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 6c37c492ab33..841264a1230a 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging; using Moq; using Tests.Events; +using NewMessageReceived = Tests.Events.NewMessageReceived; namespace Microsoft.AutoGen.Runtime.Grpc.Tests; [Collection(ClusterCollection.Name)] diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs index 1b3c10350a6c..655a14cb418a 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs @@ -10,7 +10,7 @@ namespace Microsoft.AutoGen.Runtime.Grpc.Tests; [TopicSubscription("gh-gh-gh")] -public class PBAgent([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes, ILogger? logger = null) +public class PBAgent([FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes, ILogger? logger = null) : Agent(eventTypes, logger) , IHandle , IHandle @@ -31,7 +31,7 @@ public Task Handle(GoodBye item, CancellationToken cancellationToken) } [TopicSubscription("gh-gh-gh")] -public class GMAgent([FromKeyedServices("EventTypes")] AgentsMetadata eventTypes, ILogger? logger = null) +public class GMAgent([FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes, ILogger? logger = null) : Agent(eventTypes, logger) , IHandle { diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index d962ae96acb4..09eb1b3fb18e 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -77,12 +77,12 @@ message Subscription { } } -message AddSubscriptionRequest { +message SubscriptionRequest { string request_id = 1; Subscription subscription = 2; } -message AddSubscriptionResponse { +message SubscriptionResponse { string request_id = 1; bool success = 2; optional string error = 3; @@ -93,7 +93,8 @@ service AgentRpc { rpc GetState(AgentId) returns (GetStateResponse); rpc SaveState(AgentState) returns (SaveStateResponse); rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse); - rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse); + rpc AddSubscription(SubscriptionRequest) returns (SubscriptionResponse); + rpc RemoveSubscription(SubscriptionRequest) returns (SubscriptionResponse); } message AgentState { @@ -124,8 +125,8 @@ message Message { io.cloudevents.v1.CloudEvent cloudEvent = 3; RegisterAgentTypeRequest registerAgentTypeRequest = 4; RegisterAgentTypeResponse registerAgentTypeResponse = 5; - AddSubscriptionRequest addSubscriptionRequest = 6; - AddSubscriptionResponse addSubscriptionResponse = 7; + SubscriptionRequest SubscriptionRequest = 6; + SubscriptionResponse SubscriptionResponse = 7; } } diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py index d2bf41ce0d1f..6b0183080790 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py @@ -237,7 +237,7 @@ async def _run_read_loop(self) -> None: message = await self._host_connection.recv() # type: ignore oneofcase = agent_worker_pb2.Message.WhichOneof(message, "message") match oneofcase: - case "registerAgentTypeRequest" | "addSubscriptionRequest": + case "registerAgentTypeRequest" | "SubscriptionRequest": logger.warning(f"Cant handle {oneofcase}, skipping.") case "request": task = asyncio.create_task(self._process_request(message.request)) @@ -263,9 +263,9 @@ async def _run_read_loop(self) -> None: self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "addSubscriptionResponse": + case "SubscriptionResponse": task = asyncio.create_task( - self._process_add_subscription_response(message.addSubscriptionResponse) + self._process_add_subscription_response(message.SubscriptionResponse) ) self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) @@ -827,7 +827,7 @@ async def add_subscription(self, subscription: Subscription) -> None: match subscription: case TypeSubscription(topic_type=topic_type, agent_type=agent_type): message = agent_worker_pb2.Message( - addSubscriptionRequest=agent_worker_pb2.AddSubscriptionRequest( + SubscriptionRequest=agent_worker_pb2.SubscriptionRequest( request_id=request_id, subscription=agent_worker_pb2.Subscription( typeSubscription=agent_worker_pb2.TypeSubscription( @@ -838,7 +838,7 @@ async def add_subscription(self, subscription: Subscription) -> None: ) case TypePrefixSubscription(topic_type_prefix=topic_type_prefix, agent_type=agent_type): message = agent_worker_pb2.Message( - addSubscriptionRequest=agent_worker_pb2.AddSubscriptionRequest( + SubscriptionRequest=agent_worker_pb2.SubscriptionRequest( request_id=request_id, subscription=agent_worker_pb2.Subscription( typePrefixSubscription=agent_worker_pb2.TypePrefixSubscription( @@ -862,7 +862,7 @@ async def add_subscription(self, subscription: Subscription) -> None: # Wait for the subscription response. await future - async def _process_add_subscription_response(self, response: agent_worker_pb2.AddSubscriptionResponse) -> None: + async def _process_add_subscription_response(self, response: agent_worker_pb2.SubscriptionResponse) -> None: future = self._pending_requests.pop(response.request_id) if response.HasField("error") and response.error != "": future.set_exception(RuntimeError(response.error)) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py index 0bb8ae0a8a20..67a43ef545b4 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py @@ -127,13 +127,13 @@ async def _receive_messages( self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "addSubscriptionRequest": - add_subscription: agent_worker_pb2.AddSubscriptionRequest = message.addSubscriptionRequest + case "SubscriptionRequest": + add_subscription: agent_worker_pb2.SubscriptionRequest = message.SubscriptionRequest task = asyncio.create_task(self._process_add_subscription_request(add_subscription, client_id)) self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "registerAgentTypeResponse" | "addSubscriptionResponse": + case "registerAgentTypeResponse" | "SubscriptionResponse": logger.warning(f"Received unexpected message type: {oneofcase}") case None: logger.warning("Received empty message") @@ -217,7 +217,7 @@ async def _process_register_agent_type_request( ) async def _process_add_subscription_request( - self, add_subscription_req: agent_worker_pb2.AddSubscriptionRequest, client_id: int + self, add_subscription_req: agent_worker_pb2.SubscriptionRequest, client_id: int ) -> None: oneofcase = add_subscription_req.subscription.WhichOneof("subscription") subscription: Subscription | None = None @@ -254,7 +254,7 @@ async def _process_add_subscription_request( # Send a response back to the client. await self._send_queues[client_id].put( agent_worker_pb2.Message( - addSubscriptionResponse=agent_worker_pb2.AddSubscriptionResponse( + SubscriptionResponse=agent_worker_pb2.SubscriptionResponse( request_id=add_subscription_req.request_id, success=success, error=error ) ) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py index b4794f1eaba6..76cd7f159b1a 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py @@ -16,7 +16,7 @@ from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x61gent_worker.proto\x12\x06\x61gents\x1a\x10\x63loudevent.proto\x1a\x19google/protobuf/any.proto\"\'\n\x07TopicId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"$\n\x07\x41gentId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"E\n\x07Payload\x12\x11\n\tdata_type\x18\x01 \x01(\t\x12\x19\n\x11\x64\x61ta_content_type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x89\x02\n\nRpcRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12$\n\x06source\x18\x02 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12\x1f\n\x06target\x18\x03 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0e\n\x06method\x18\x04 \x01(\t\x12 \n\x07payload\x18\x05 \x01(\x0b\x32\x0f.agents.Payload\x12\x32\n\x08metadata\x18\x06 \x03(\x0b\x32 .agents.RpcRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\xb8\x01\n\x0bRpcResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12 \n\x07payload\x18\x02 \x01(\x0b\x32\x0f.agents.Payload\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x33\n\x08metadata\x18\x04 \x03(\x0b\x32!.agents.RpcResponse.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe4\x01\n\x05\x45vent\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x14\n\x0ctopic_source\x18\x02 \x01(\t\x12$\n\x06source\x18\x03 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12 \n\x07payload\x18\x04 \x01(\x0b\x32\x0f.agents.Payload\x12-\n\x08metadata\x18\x05 \x03(\x0b\x32\x1b.agents.Event.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"<\n\x18RegisterAgentTypeRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\"^\n\x19RegisterAgentTypeResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\":\n\x10TypeSubscription\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"G\n\x16TypePrefixSubscription\x12\x19\n\x11topic_type_prefix\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"\x96\x01\n\x0cSubscription\x12\x34\n\x10typeSubscription\x18\x01 \x01(\x0b\x32\x18.agents.TypeSubscriptionH\x00\x12@\n\x16typePrefixSubscription\x18\x02 \x01(\x0b\x32\x1e.agents.TypePrefixSubscriptionH\x00\x42\x0e\n\x0csubscription\"X\n\x16\x41\x64\x64SubscriptionRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12*\n\x0csubscription\x18\x02 \x01(\x0b\x32\x14.agents.Subscription\"\\\n\x17\x41\x64\x64SubscriptionResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x9d\x01\n\nAgentState\x12!\n\x08\x61gent_id\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0c\n\x04\x65Tag\x18\x02 \x01(\t\x12\x15\n\x0b\x62inary_data\x18\x03 \x01(\x0cH\x00\x12\x13\n\ttext_data\x18\x04 \x01(\tH\x00\x12*\n\nproto_data\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x06\n\x04\x64\x61ta\"j\n\x10GetStateResponse\x12\'\n\x0b\x61gent_state\x18\x01 \x01(\x0b\x32\x12.agents.AgentState\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"B\n\x11SaveStateResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\xad\x03\n\x07Message\x12%\n\x07request\x18\x01 \x01(\x0b\x32\x12.agents.RpcRequestH\x00\x12\'\n\x08response\x18\x02 \x01(\x0b\x32\x13.agents.RpcResponseH\x00\x12\x33\n\ncloudEvent\x18\x03 \x01(\x0b\x32\x1d.io.cloudevents.v1.CloudEventH\x00\x12\x44\n\x18registerAgentTypeRequest\x18\x04 \x01(\x0b\x32 .agents.RegisterAgentTypeRequestH\x00\x12\x46\n\x19registerAgentTypeResponse\x18\x05 \x01(\x0b\x32!.agents.RegisterAgentTypeResponseH\x00\x12@\n\x16\x61\x64\x64SubscriptionRequest\x18\x06 \x01(\x0b\x32\x1e.agents.AddSubscriptionRequestH\x00\x12\x42\n\x17\x61\x64\x64SubscriptionResponse\x18\x07 \x01(\x0b\x32\x1f.agents.AddSubscriptionResponseH\x00\x42\t\n\x07message2\xb2\x01\n\x08\x41gentRpc\x12\x33\n\x0bOpenChannel\x12\x0f.agents.Message\x1a\x0f.agents.Message(\x01\x30\x01\x12\x35\n\x08GetState\x12\x0f.agents.AgentId\x1a\x18.agents.GetStateResponse\x12:\n\tSaveState\x12\x12.agents.AgentState\x1a\x19.agents.SaveStateResponseB\x1e\xaa\x02\x1bMicrosoft.AutoGen.Contractsb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x61gent_worker.proto\x12\x06\x61gents\x1a\x10\x63loudevent.proto\x1a\x19google/protobuf/any.proto\"\'\n\x07TopicId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"$\n\x07\x41gentId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"E\n\x07Payload\x12\x11\n\tdata_type\x18\x01 \x01(\t\x12\x19\n\x11\x64\x61ta_content_type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x89\x02\n\nRpcRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12$\n\x06source\x18\x02 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12\x1f\n\x06target\x18\x03 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0e\n\x06method\x18\x04 \x01(\t\x12 \n\x07payload\x18\x05 \x01(\x0b\x32\x0f.agents.Payload\x12\x32\n\x08metadata\x18\x06 \x03(\x0b\x32 .agents.RpcRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\xb8\x01\n\x0bRpcResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12 \n\x07payload\x18\x02 \x01(\x0b\x32\x0f.agents.Payload\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x33\n\x08metadata\x18\x04 \x03(\x0b\x32!.agents.RpcResponse.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe4\x01\n\x05\x45vent\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x14\n\x0ctopic_source\x18\x02 \x01(\t\x12$\n\x06source\x18\x03 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12 \n\x07payload\x18\x04 \x01(\x0b\x32\x0f.agents.Payload\x12-\n\x08metadata\x18\x05 \x03(\x0b\x32\x1b.agents.Event.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\\\n\x18RegisterAgentTypeRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06\x65vents\x18\x03 \x03(\t\x12\x0e\n\x06topics\x18\x04 \x03(\t\"^\n\x19RegisterAgentTypeResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\":\n\x10TypeSubscription\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"G\n\x16TypePrefixSubscription\x12\x19\n\x11topic_type_prefix\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"\x96\x01\n\x0cSubscription\x12\x34\n\x10typeSubscription\x18\x01 \x01(\x0b\x32\x18.agents.TypeSubscriptionH\x00\x12@\n\x16typePrefixSubscription\x18\x02 \x01(\x0b\x32\x1e.agents.TypePrefixSubscriptionH\x00\x42\x0e\n\x0csubscription\"U\n\x13SubscriptionRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12*\n\x0csubscription\x18\x02 \x01(\x0b\x32\x14.agents.Subscription\"Y\n\x14SubscriptionResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x9d\x01\n\nAgentState\x12!\n\x08\x61gent_id\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0c\n\x04\x65Tag\x18\x02 \x01(\t\x12\x15\n\x0b\x62inary_data\x18\x03 \x01(\x0cH\x00\x12\x13\n\ttext_data\x18\x04 \x01(\tH\x00\x12*\n\nproto_data\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x06\n\x04\x64\x61ta\"j\n\x10GetStateResponse\x12\'\n\x0b\x61gent_state\x18\x01 \x01(\x0b\x32\x12.agents.AgentState\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"B\n\x11SaveStateResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\xa1\x03\n\x07Message\x12%\n\x07request\x18\x01 \x01(\x0b\x32\x12.agents.RpcRequestH\x00\x12\'\n\x08response\x18\x02 \x01(\x0b\x32\x13.agents.RpcResponseH\x00\x12\x33\n\ncloudEvent\x18\x03 \x01(\x0b\x32\x1d.io.cloudevents.v1.CloudEventH\x00\x12\x44\n\x18registerAgentTypeRequest\x18\x04 \x01(\x0b\x32 .agents.RegisterAgentTypeRequestH\x00\x12\x46\n\x19registerAgentTypeResponse\x18\x05 \x01(\x0b\x32!.agents.RegisterAgentTypeResponseH\x00\x12:\n\x13SubscriptionRequest\x18\x06 \x01(\x0b\x32\x1b.agents.SubscriptionRequestH\x00\x12<\n\x14SubscriptionResponse\x18\x07 \x01(\x0b\x32\x1c.agents.SubscriptionResponseH\x00\x42\t\n\x07message2\xa7\x03\n\x08\x41gentRpc\x12\x33\n\x0bOpenChannel\x12\x0f.agents.Message\x1a\x0f.agents.Message(\x01\x30\x01\x12\x35\n\x08GetState\x12\x0f.agents.AgentId\x1a\x18.agents.GetStateResponse\x12:\n\tSaveState\x12\x12.agents.AgentState\x1a\x19.agents.SaveStateResponse\x12T\n\rRegisterAgent\x12 .agents.RegisterAgentTypeRequest\x1a!.agents.RegisterAgentTypeResponse\x12L\n\x0f\x41\x64\x64Subscription\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponse\x12O\n\x12RemoveSubscription\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponseB\x1e\xaa\x02\x1bMicrosoft.AutoGen.Contractsb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -49,27 +49,27 @@ _globals['_EVENT_METADATAENTRY']._serialized_start=433 _globals['_EVENT_METADATAENTRY']._serialized_end=480 _globals['_REGISTERAGENTTYPEREQUEST']._serialized_start=911 - _globals['_REGISTERAGENTTYPEREQUEST']._serialized_end=971 - _globals['_REGISTERAGENTTYPERESPONSE']._serialized_start=973 - _globals['_REGISTERAGENTTYPERESPONSE']._serialized_end=1067 - _globals['_TYPESUBSCRIPTION']._serialized_start=1069 - _globals['_TYPESUBSCRIPTION']._serialized_end=1127 - _globals['_TYPEPREFIXSUBSCRIPTION']._serialized_start=1129 - _globals['_TYPEPREFIXSUBSCRIPTION']._serialized_end=1200 - _globals['_SUBSCRIPTION']._serialized_start=1203 - _globals['_SUBSCRIPTION']._serialized_end=1353 - _globals['_ADDSUBSCRIPTIONREQUEST']._serialized_start=1355 - _globals['_ADDSUBSCRIPTIONREQUEST']._serialized_end=1443 - _globals['_ADDSUBSCRIPTIONRESPONSE']._serialized_start=1445 - _globals['_ADDSUBSCRIPTIONRESPONSE']._serialized_end=1537 - _globals['_AGENTSTATE']._serialized_start=1540 - _globals['_AGENTSTATE']._serialized_end=1697 - _globals['_GETSTATERESPONSE']._serialized_start=1699 - _globals['_GETSTATERESPONSE']._serialized_end=1805 - _globals['_SAVESTATERESPONSE']._serialized_start=1807 - _globals['_SAVESTATERESPONSE']._serialized_end=1873 - _globals['_MESSAGE']._serialized_start=1876 - _globals['_MESSAGE']._serialized_end=2305 - _globals['_AGENTRPC']._serialized_start=2308 - _globals['_AGENTRPC']._serialized_end=2486 + _globals['_REGISTERAGENTTYPEREQUEST']._serialized_end=1003 + _globals['_REGISTERAGENTTYPERESPONSE']._serialized_start=1005 + _globals['_REGISTERAGENTTYPERESPONSE']._serialized_end=1099 + _globals['_TYPESUBSCRIPTION']._serialized_start=1101 + _globals['_TYPESUBSCRIPTION']._serialized_end=1159 + _globals['_TYPEPREFIXSUBSCRIPTION']._serialized_start=1161 + _globals['_TYPEPREFIXSUBSCRIPTION']._serialized_end=1232 + _globals['_SUBSCRIPTION']._serialized_start=1235 + _globals['_SUBSCRIPTION']._serialized_end=1385 + _globals['_SUBSCRIPTIONREQUEST']._serialized_start=1387 + _globals['_SUBSCRIPTIONREQUEST']._serialized_end=1472 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_start=1474 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_end=1563 + _globals['_AGENTSTATE']._serialized_start=1566 + _globals['_AGENTSTATE']._serialized_end=1723 + _globals['_GETSTATERESPONSE']._serialized_start=1725 + _globals['_GETSTATERESPONSE']._serialized_end=1831 + _globals['_SAVESTATERESPONSE']._serialized_start=1833 + _globals['_SAVESTATERESPONSE']._serialized_end=1899 + _globals['_MESSAGE']._serialized_start=1902 + _globals['_MESSAGE']._serialized_end=2319 + _globals['_AGENTRPC']._serialized_start=2322 + _globals['_AGENTRPC']._serialized_end=2745 # @@protoc_insertion_point(module_scope) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi index 79e384ab948b..ff0ec2e9c801 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi @@ -220,15 +220,23 @@ class RegisterAgentTypeRequest(google.protobuf.message.Message): REQUEST_ID_FIELD_NUMBER: builtins.int TYPE_FIELD_NUMBER: builtins.int + EVENTS_FIELD_NUMBER: builtins.int + TOPICS_FIELD_NUMBER: builtins.int request_id: builtins.str type: builtins.str + @property + def events(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... + @property + def topics(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... def __init__( self, *, request_id: builtins.str = ..., type: builtins.str = ..., + events: collections.abc.Iterable[builtins.str] | None = ..., + topics: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["request_id", b"request_id", "type", b"type"]) -> None: ... + def ClearField(self, field_name: typing.Literal["events", b"events", "request_id", b"request_id", "topics", b"topics", "type", b"type"]) -> None: ... global___RegisterAgentTypeRequest = RegisterAgentTypeRequest @@ -314,7 +322,7 @@ class Subscription(google.protobuf.message.Message): global___Subscription = Subscription @typing.final -class AddSubscriptionRequest(google.protobuf.message.Message): +class SubscriptionRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor REQUEST_ID_FIELD_NUMBER: builtins.int @@ -331,10 +339,10 @@ class AddSubscriptionRequest(google.protobuf.message.Message): def HasField(self, field_name: typing.Literal["subscription", b"subscription"]) -> builtins.bool: ... def ClearField(self, field_name: typing.Literal["request_id", b"request_id", "subscription", b"subscription"]) -> None: ... -global___AddSubscriptionRequest = AddSubscriptionRequest +global___SubscriptionRequest = SubscriptionRequest @typing.final -class AddSubscriptionResponse(google.protobuf.message.Message): +class SubscriptionResponse(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor REQUEST_ID_FIELD_NUMBER: builtins.int @@ -354,7 +362,7 @@ class AddSubscriptionResponse(google.protobuf.message.Message): def ClearField(self, field_name: typing.Literal["_error", b"_error", "error", b"error", "request_id", b"request_id", "success", b"success"]) -> None: ... def WhichOneof(self, oneof_group: typing.Literal["_error", b"_error"]) -> typing.Literal["error"] | None: ... -global___AddSubscriptionResponse = AddSubscriptionResponse +global___SubscriptionResponse = SubscriptionResponse @typing.final class AgentState(google.protobuf.message.Message): @@ -440,8 +448,8 @@ class Message(google.protobuf.message.Message): CLOUDEVENT_FIELD_NUMBER: builtins.int REGISTERAGENTTYPEREQUEST_FIELD_NUMBER: builtins.int REGISTERAGENTTYPERESPONSE_FIELD_NUMBER: builtins.int - ADDSUBSCRIPTIONREQUEST_FIELD_NUMBER: builtins.int - ADDSUBSCRIPTIONRESPONSE_FIELD_NUMBER: builtins.int + SUBSCRIPTIONREQUEST_FIELD_NUMBER: builtins.int + SUBSCRIPTIONRESPONSE_FIELD_NUMBER: builtins.int @property def request(self) -> global___RpcRequest: ... @property @@ -453,9 +461,9 @@ class Message(google.protobuf.message.Message): @property def registerAgentTypeResponse(self) -> global___RegisterAgentTypeResponse: ... @property - def addSubscriptionRequest(self) -> global___AddSubscriptionRequest: ... + def SubscriptionRequest(self) -> global___SubscriptionRequest: ... @property - def addSubscriptionResponse(self) -> global___AddSubscriptionResponse: ... + def SubscriptionResponse(self) -> global___SubscriptionResponse: ... def __init__( self, *, @@ -464,11 +472,11 @@ class Message(google.protobuf.message.Message): cloudEvent: cloudevent_pb2.CloudEvent | None = ..., registerAgentTypeRequest: global___RegisterAgentTypeRequest | None = ..., registerAgentTypeResponse: global___RegisterAgentTypeResponse | None = ..., - addSubscriptionRequest: global___AddSubscriptionRequest | None = ..., - addSubscriptionResponse: global___AddSubscriptionResponse | None = ..., + SubscriptionRequest: global___SubscriptionRequest | None = ..., + SubscriptionResponse: global___SubscriptionResponse | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["addSubscriptionRequest", b"addSubscriptionRequest", "addSubscriptionResponse", b"addSubscriptionResponse", "cloudEvent", b"cloudEvent", "message", b"message", "registerAgentTypeRequest", b"registerAgentTypeRequest", "registerAgentTypeResponse", b"registerAgentTypeResponse", "request", b"request", "response", b"response"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["addSubscriptionRequest", b"addSubscriptionRequest", "addSubscriptionResponse", b"addSubscriptionResponse", "cloudEvent", b"cloudEvent", "message", b"message", "registerAgentTypeRequest", b"registerAgentTypeRequest", "registerAgentTypeResponse", b"registerAgentTypeResponse", "request", b"request", "response", b"response"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["message", b"message"]) -> typing.Literal["request", "response", "cloudEvent", "registerAgentTypeRequest", "registerAgentTypeResponse", "addSubscriptionRequest", "addSubscriptionResponse"] | None: ... + def HasField(self, field_name: typing.Literal["SubscriptionRequest", b"SubscriptionRequest", "SubscriptionResponse", b"SubscriptionResponse", "cloudEvent", b"cloudEvent", "message", b"message", "registerAgentTypeRequest", b"registerAgentTypeRequest", "registerAgentTypeResponse", b"registerAgentTypeResponse", "request", b"request", "response", b"response"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["SubscriptionRequest", b"SubscriptionRequest", "SubscriptionResponse", b"SubscriptionResponse", "cloudEvent", b"cloudEvent", "message", b"message", "registerAgentTypeRequest", b"registerAgentTypeRequest", "registerAgentTypeResponse", b"registerAgentTypeResponse", "request", b"request", "response", b"response"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["message", b"message"]) -> typing.Literal["request", "response", "cloudEvent", "registerAgentTypeRequest", "registerAgentTypeResponse", "SubscriptionRequest", "SubscriptionResponse"] | None: ... global___Message = Message diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py index fc27021587f6..c363d9968034 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py @@ -29,6 +29,21 @@ def __init__(self, channel): request_serializer=agent__worker__pb2.AgentState.SerializeToString, response_deserializer=agent__worker__pb2.SaveStateResponse.FromString, ) + self.RegisterAgent = channel.unary_unary( + '/agents.AgentRpc/RegisterAgent', + request_serializer=agent__worker__pb2.RegisterAgentTypeRequest.SerializeToString, + response_deserializer=agent__worker__pb2.RegisterAgentTypeResponse.FromString, + ) + self.AddSubscription = channel.unary_unary( + '/agents.AgentRpc/AddSubscription', + request_serializer=agent__worker__pb2.SubscriptionRequest.SerializeToString, + response_deserializer=agent__worker__pb2.SubscriptionResponse.FromString, + ) + self.RemoveSubscription = channel.unary_unary( + '/agents.AgentRpc/RemoveSubscription', + request_serializer=agent__worker__pb2.SubscriptionRequest.SerializeToString, + response_deserializer=agent__worker__pb2.SubscriptionResponse.FromString, + ) class AgentRpcServicer(object): @@ -52,6 +67,24 @@ def SaveState(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def RegisterAgent(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def AddSubscription(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RemoveSubscription(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_AgentRpcServicer_to_server(servicer, server): rpc_method_handlers = { @@ -70,6 +103,21 @@ def add_AgentRpcServicer_to_server(servicer, server): request_deserializer=agent__worker__pb2.AgentState.FromString, response_serializer=agent__worker__pb2.SaveStateResponse.SerializeToString, ), + 'RegisterAgent': grpc.unary_unary_rpc_method_handler( + servicer.RegisterAgent, + request_deserializer=agent__worker__pb2.RegisterAgentTypeRequest.FromString, + response_serializer=agent__worker__pb2.RegisterAgentTypeResponse.SerializeToString, + ), + 'AddSubscription': grpc.unary_unary_rpc_method_handler( + servicer.AddSubscription, + request_deserializer=agent__worker__pb2.SubscriptionRequest.FromString, + response_serializer=agent__worker__pb2.SubscriptionResponse.SerializeToString, + ), + 'RemoveSubscription': grpc.unary_unary_rpc_method_handler( + servicer.RemoveSubscription, + request_deserializer=agent__worker__pb2.SubscriptionRequest.FromString, + response_serializer=agent__worker__pb2.SubscriptionResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'agents.AgentRpc', rpc_method_handlers) @@ -130,3 +178,54 @@ def SaveState(request, agent__worker__pb2.SaveStateResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def RegisterAgent(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/RegisterAgent', + agent__worker__pb2.RegisterAgentTypeRequest.SerializeToString, + agent__worker__pb2.RegisterAgentTypeResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def AddSubscription(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/AddSubscription', + agent__worker__pb2.SubscriptionRequest.SerializeToString, + agent__worker__pb2.SubscriptionResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def RemoveSubscription(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/RemoveSubscription', + agent__worker__pb2.SubscriptionRequest.SerializeToString, + agent__worker__pb2.SubscriptionResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi index bf6bc1ba2d64..94539461f70c 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi @@ -34,6 +34,21 @@ class AgentRpcStub: agent_worker_pb2.SaveStateResponse, ] + RegisterAgent: grpc.UnaryUnaryMultiCallable[ + agent_worker_pb2.RegisterAgentTypeRequest, + agent_worker_pb2.RegisterAgentTypeResponse, + ] + + AddSubscription: grpc.UnaryUnaryMultiCallable[ + agent_worker_pb2.SubscriptionRequest, + agent_worker_pb2.SubscriptionResponse, + ] + + RemoveSubscription: grpc.UnaryUnaryMultiCallable[ + agent_worker_pb2.SubscriptionRequest, + agent_worker_pb2.SubscriptionResponse, + ] + class AgentRpcAsyncStub: OpenChannel: grpc.aio.StreamStreamMultiCallable[ agent_worker_pb2.Message, @@ -50,6 +65,21 @@ class AgentRpcAsyncStub: agent_worker_pb2.SaveStateResponse, ] + RegisterAgent: grpc.aio.UnaryUnaryMultiCallable[ + agent_worker_pb2.RegisterAgentTypeRequest, + agent_worker_pb2.RegisterAgentTypeResponse, + ] + + AddSubscription: grpc.aio.UnaryUnaryMultiCallable[ + agent_worker_pb2.SubscriptionRequest, + agent_worker_pb2.SubscriptionResponse, + ] + + RemoveSubscription: grpc.aio.UnaryUnaryMultiCallable[ + agent_worker_pb2.SubscriptionRequest, + agent_worker_pb2.SubscriptionResponse, + ] + class AgentRpcServicer(metaclass=abc.ABCMeta): @abc.abstractmethod def OpenChannel( @@ -72,4 +102,25 @@ class AgentRpcServicer(metaclass=abc.ABCMeta): context: _ServicerContext, ) -> typing.Union[agent_worker_pb2.SaveStateResponse, collections.abc.Awaitable[agent_worker_pb2.SaveStateResponse]]: ... + @abc.abstractmethod + def RegisterAgent( + self, + request: agent_worker_pb2.RegisterAgentTypeRequest, + context: _ServicerContext, + ) -> typing.Union[agent_worker_pb2.RegisterAgentTypeResponse, collections.abc.Awaitable[agent_worker_pb2.RegisterAgentTypeResponse]]: ... + + @abc.abstractmethod + def AddSubscription( + self, + request: agent_worker_pb2.SubscriptionRequest, + context: _ServicerContext, + ) -> typing.Union[agent_worker_pb2.SubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.SubscriptionResponse]]: ... + + @abc.abstractmethod + def RemoveSubscription( + self, + request: agent_worker_pb2.SubscriptionRequest, + context: _ServicerContext, + ) -> typing.Union[agent_worker_pb2.SubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.SubscriptionResponse]]: ... + def add_AgentRpcServicer_to_server(servicer: AgentRpcServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ... From 823019d7b3d3617931ed83b67403793040cdd682 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 21 Dec 2024 21:10:35 -0800 Subject: [PATCH 016/110] start mustnt wait --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 50a29203d4c7..da3dfa6388fa 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -49,7 +49,7 @@ protected Agent( public static void Initialize(IAgentWorker worker, Agent agent) { agent.Worker = worker; - agent.Start().Wait(); + agent.Start(); agent.AddImplicitSubscriptionsAsync().AsTask().Wait(); } From b501d25aa40a97a9463bf6a31657b96afcd4c2d9 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 21 Dec 2024 22:01:05 -0800 Subject: [PATCH 017/110] add unsubscribe --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 40 ++++++++++++------- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 20 ++++++++++ .../AgentTests.cs | 28 ++++++++++++- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index da3dfa6388fa..9385d9fda223 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -76,7 +76,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() } }; // explicitly wait for this to complete - await Worker.SendMessageAsync(new Message { SubscriptionRequest = subscriptionRequest }).ConfigureAwait(true); + Worker.SubscribeAsync(subscriptionRequest).AsTask().Wait(); } // using reflection, find all methods that Handle and subscribe to the topic T @@ -89,7 +89,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() { foreach (var topic in topics) { - Subscribe(topic); + await SubscribeAsync(topic).ConfigureAwait(true); } } } @@ -177,26 +177,36 @@ public async ValueTask> GetSubscriptionsAsync() { return await Worker.GetSubscriptionsAsync(GetType()).ConfigureAwait(false); } - public List Subscribe(string topic) + public async ValueTask SubscribeAsync(string topic) { - Message message = new() + return await UpdateSubscriptionAsync(topic, true).ConfigureAwait(true); + } + public async ValueTask UnsubscribeAsync(string topic) + { + return await UpdateSubscriptionAsync(topic, false).ConfigureAwait(true); + } + private async ValueTask UpdateSubscriptionAsync(string topic, bool subscribe) + { + SubscriptionRequest subscriptionRequest = new() { - SubscriptionRequest = new() + RequestId = Guid.NewGuid().ToString(), + Subscription = new Subscription { - RequestId = Guid.NewGuid().ToString(), - Subscription = new Subscription + TypeSubscription = new TypeSubscription { - TypeSubscription = new TypeSubscription - { - TopicType = topic, - AgentType = this.AgentId.Key - } + TopicType = topic, + AgentType = this.AgentId.Type } } }; - Worker.SendMessageAsync(message).AsTask().Wait(); - - return new List { topic }; + var subscriptionResponse = subscribe + ? await Worker.SubscribeAsync(subscriptionRequest).ConfigureAwait(true) + : await Worker.UnsubscribeAsync(subscriptionRequest).ConfigureAwait(true); + if (!subscriptionResponse.Success) + { + _logger.LogError($"{GetType}{AgentId.Key}: Failed to unsubscribe from topic {topic}"); + } + return subscriptionResponse; } public async Task StoreAsync(AgentState state, CancellationToken cancellationToken = default) { diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 8de12f77bb4a..8697f99c9701 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -148,6 +148,26 @@ public async ValueTask SubscribeAsync(SubscriptionRequest }; return response; } + public async ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + { + var topic = request.Subscription.TypeSubscription.TopicType; + var agentType = request.Subscription.TypeSubscription.AgentType; + if (_subscriptionsByAgentType.TryGetValue(agentType, out var subscriptions)) + { + subscriptions.Remove(request.Subscription); + } + if (_subscriptionsByTopic.TryGetValue(topic, out var agentTypes)) + { + agentTypes.Remove(agentType); + } + var response = new SubscriptionResponse + { + RequestId = request.RequestId, + Error = "", + Success = true + }; + return response; + } public async Task StartAsync(CancellationToken cancellationToken) { diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 2fb8a3a8e638..f4403f5278e5 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -29,10 +29,15 @@ public class AgentTests(InMemoryAgentRuntimeFixture fixture) /// /// void [Fact] - public void Agent_ShouldThrowException_WhenNotInitialized() + public async Task Agent_ShouldThrowException_WhenNotInitialized() { var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - Assert.Throws(() => { agent.Subscribe("TestEvent"); }); + await Assert.ThrowsAsync( + async () => + { + await agent.SubscribeAsync("TestEvent"); + } + ); } /// @@ -49,6 +54,25 @@ public async Task Agent_ShouldInitializeCorrectly() var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); } + /// + /// Test SubscribeAsync method + /// + /// void + [Fact] + public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + var worker = _serviceProvider.GetRequiredService(); + Agent.Initialize(worker, agent); + var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + Assert.Equal(2, subscriptions.Count); + await agent.SubscribeAsync("TestEvent"); + subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + Assert.Equal(3, subscriptions.Count); + await agent.UnsubscribeAsync("TestEvent"); + subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + Assert.Equal(2, subscriptions.Count); + } [Fact] public async Task ItInvokeRightHandlerTestAsync() From 83f5fc0df87fc8a8446b7a0afe92622fb96db787 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 22 Dec 2024 10:42:21 -0800 Subject: [PATCH 018/110] adding tests for agentstate --- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 4 --- .../AgentTests.cs | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 8697f99c9701..2bdeb4e22af8 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -253,8 +253,4 @@ public ValueTask> GetSubscriptionsAsync(Type type) } return new ValueTask>([]); } - public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } } diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index f4403f5278e5..30c0bf22c844 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Diagnostics; +using System.Text.Json; using FluentAssertions; using Google.Protobuf.Reflection; using Microsoft.AspNetCore.Builder; @@ -74,6 +75,31 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() Assert.Equal(2, subscriptions.Count); } + /// + /// Test StoreAsync and ReadAsync methods + /// + /// void + [Fact] + public async Task StoreAsync_and_ReadAsyncTest() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + var worker = _serviceProvider.GetRequiredService(); + Agent.Initialize(worker, agent); + Dictionary state = new() + { + { "testdata", "Active" } + }; + await agent.StoreAsync(new AgentState + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); + var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); + var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; + read.TryGetValue("testdata", out var value); + Assert.Equal("Active", value); + } + [Fact] public async Task ItInvokeRightHandlerTestAsync() { From acaf3d33ddaa87bcdef4859d239f7730908c31ef Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 22 Dec 2024 10:59:38 -0800 Subject: [PATCH 019/110] publish and receive test --- .../AgentTests.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 30c0bf22c844..ff162aab6711 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -100,6 +100,36 @@ await agent.StoreAsync(new AgentState Assert.Equal("Active", value); } + /// + /// Test PublishMessageAsync method and ReceiveMessage method + /// + /// void + [Fact] + public async Task PublishMessageAsync_and_ReceiveMessageTest() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + var worker = _serviceProvider.GetRequiredService(); + Agent.Initialize(worker, agent); + await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); + var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + var found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.True(found); + await agent.PublishMessageAsync(new TextMessage() + { + Source = "TestEvent", + TextMessage_ = "buffer" + }).ConfigureAwait(true); + await Task.Delay(100); + Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); + } + [Fact] public async Task ItInvokeRightHandlerTestAsync() { From 1d6e4437b24e01ae1da8ea4f3f555c6a5587af92 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 08:53:55 -0800 Subject: [PATCH 020/110] Improving the subscription tests timing --- .../AgentTests.cs | 111 +++++++++++++++--- 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index ff162aab6711..8e5cf309e2ea 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -48,12 +48,11 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() [Fact] public async Task Agent_ShouldInitializeCorrectly() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - var worker = _serviceProvider.GetRequiredService(); - Agent.Initialize(worker, agent); - Assert.Equal("AgentWorker", agent.Worker.GetType().Name); + var (worker, agent) = _fixture.Start(); + Assert.Equal("AgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); + _fixture.Stop(); } /// /// Test SubscribeAsync method @@ -62,17 +61,32 @@ public async Task Agent_ShouldInitializeCorrectly() [Fact] public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - var worker = _serviceProvider.GetRequiredService(); - Agent.Initialize(worker, agent); - var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); - Assert.Equal(2, subscriptions.Count); + var (_, agent) = _fixture.Start(); await agent.SubscribeAsync("TestEvent"); + await Task.Delay(100); + var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + var found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.True(found); + await agent.UnsubscribeAsync("TestEvent").ConfigureAwait(true); + await Task.Delay(500); subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); - Assert.Equal(3, subscriptions.Count); - await agent.UnsubscribeAsync("TestEvent"); - subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); - Assert.Equal(2, subscriptions.Count); + found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.False(found); + _fixture.Stop(); } /// @@ -82,9 +96,7 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() [Fact] public async Task StoreAsync_and_ReadAsyncTest() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - var worker = _serviceProvider.GetRequiredService(); - Agent.Initialize(worker, agent); + var (_, agent) = _fixture.Start(); Dictionary state = new() { { "testdata", "Active" } @@ -98,6 +110,7 @@ await agent.StoreAsync(new AgentState var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); Assert.Equal("Active", value); + _fixture.Stop(); } /// @@ -107,9 +120,7 @@ await agent.StoreAsync(new AgentState [Fact] public async Task PublishMessageAsync_and_ReceiveMessageTest() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); - var worker = _serviceProvider.GetRequiredService(); - Agent.Initialize(worker, agent); + var (_, agent) = _fixture.Start(); await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); var found = false; @@ -128,6 +139,7 @@ await agent.PublishMessageAsync(new TextMessage() }).ConfigureAwait(true); await Task.Delay(100); Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); + _fixture.Stop(); } [Fact] @@ -163,6 +175,41 @@ await client.PublishMessageAsync(new TextMessage() TestAgent.ReceivedMessages[nameof(ItDelegateMessageToTestAgentAsync)].Should().NotBeNull(); } + /// + /// GetAppHost - provides an app host used for one test vs the fixture which is shared. + /// + /// WebApplication + internal static WebApplication GetAppHost() + { + var builder = WebApplication.CreateBuilder(); + builder.Services.TryAddSingleton(DistributedContextPropagator.Current); + builder.AddAgentWorker() + .AddAgent(nameof(TestAgent)); + Host = builder.Build(); + Host.StartAsync().Wait(); + return Host; + } + /// + /// Start - starts the agent + /// + /// IAgentWorker, TestAgent + internal (IAgentWorker, TestAgent) Start() + { + var agent = ActivatorUtilities.CreateInstance(GetAppHost().Services); + var worker = _serviceProvider.GetRequiredService(); + Agent.Initialize(worker, agent); + return (worker, agent); + } + /// + /// Stop - stops the agent + /// + /// WebApplication + /// void + internal static void Stop(WebApplication Host) + { + Host.StopAsync().Wait(); + } + /// /// The test agent is a simple agent that is used for testing purposes. /// @@ -195,6 +242,13 @@ public Task Handle(int item) } } +/// +/// InMemoryAgentRuntimeFixture - provides a fixture for the agent runtime. +/// +/// +/// This fixture is used to provide a runtime for the agent tests. +/// However, it is shared between tests. So operations from one test can affect another. +/// public sealed class InMemoryAgentRuntimeFixture : IDisposable { public InMemoryAgentRuntimeFixture() @@ -213,6 +267,25 @@ void IDisposable.Dispose() AppHost.StopAsync().Wait(); AppHost.Dispose(); } + /// + /// Start - starts the agent + /// + /// IAgentWorker, TestAgent + public (IAgentWorker, TestAgent) Start() + { + var agent = ActivatorUtilities.CreateInstance(AppHost.Services); + var worker = AppHost.Services.GetRequiredService(); + Agent.Initialize(worker, agent); + return (worker, agent); + } + /// + /// Stop - stops the agent + /// + /// void + public void Stop() + { + AppHost.StopAsync().Wait(); + } } [CollectionDefinition(Name)] From 7d4308fd6873e1e734136d574b662ff110c70ad0 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 11:29:59 -0800 Subject: [PATCH 021/110] tests pass now --- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 10 ++++++++-- .../AgentTests.cs | 20 +++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index 2bdeb4e22af8..aaf6c795d14d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -154,11 +154,17 @@ public async ValueTask UnsubscribeAsync(SubscriptionReques var agentType = request.Subscription.TypeSubscription.AgentType; if (_subscriptionsByAgentType.TryGetValue(agentType, out var subscriptions)) { - subscriptions.Remove(request.Subscription); + while (subscriptions.Remove(request.Subscription)) + { + //ensures all instances are removed + } } if (_subscriptionsByTopic.TryGetValue(topic, out var agentTypes)) { - agentTypes.Remove(agentType); + while (agentTypes.Remove(agentType)) + { + //ensures all instances are removed + } } var response = new SubscriptionResponse { diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 8e5cf309e2ea..c349a32cb460 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -193,12 +193,13 @@ internal static WebApplication GetAppHost() /// Start - starts the agent /// /// IAgentWorker, TestAgent - internal (IAgentWorker, TestAgent) Start() + internal (WebApplication, IAgentWorker, TestAgent) Start() { - var agent = ActivatorUtilities.CreateInstance(GetAppHost().Services); + var host = GetAppHost(); + var agent = ActivatorUtilities.CreateInstance(host.Services); var worker = _serviceProvider.GetRequiredService(); Agent.Initialize(worker, agent); - return (worker, agent); + return (host, worker, agent); } /// /// Stop - stops the agent @@ -208,6 +209,7 @@ internal static WebApplication GetAppHost() internal static void Stop(WebApplication Host) { Host.StopAsync().Wait(); + Host.DisposeAsync().AsTask().Wait(); } /// @@ -249,7 +251,7 @@ public Task Handle(int item) /// This fixture is used to provide a runtime for the agent tests. /// However, it is shared between tests. So operations from one test can affect another. /// -public sealed class InMemoryAgentRuntimeFixture : IDisposable +public sealed class InMemoryAgentRuntimeFixture { public InMemoryAgentRuntimeFixture() { @@ -262,12 +264,7 @@ public InMemoryAgentRuntimeFixture() } public IHost AppHost { get; } - void IDisposable.Dispose() - { - AppHost.StopAsync().Wait(); - AppHost.Dispose(); - } - /// + /// /// Start - starts the agent /// /// IAgentWorker, TestAgent @@ -284,7 +281,8 @@ void IDisposable.Dispose() /// void public void Stop() { - AppHost.StopAsync().Wait(); + IHostApplicationLifetime hostApplicationLifetime = AppHost.Services.GetRequiredService(); + hostApplicationLifetime.StopApplication(); } } From 2e1d24f90b766a60db8d253654d206f62f5c7eb5 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 11:31:38 -0800 Subject: [PATCH 022/110] rename some wierd methods --- dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index c349a32cb460..0eb5bb7c1a0b 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -143,7 +143,7 @@ await agent.PublishMessageAsync(new TextMessage() } [Fact] - public async Task ItInvokeRightHandlerTestAsync() + public async Task InvokeCorrectHandler() { var agent = new TestAgent(new AgentsMetadata(TypeRegistry.Empty, new Dictionary(), new Dictionary>(), new Dictionary>()), new Logger(new LoggerFactory())); @@ -156,23 +156,23 @@ public async Task ItInvokeRightHandlerTestAsync() } [Fact] - public async Task ItDelegateMessageToTestAgentAsync() + public async Task DelegateMessageToTestAgentAsync() { var client = _fixture.AppHost.Services.GetRequiredService(); await client.PublishMessageAsync(new TextMessage() { - Source = nameof(ItDelegateMessageToTestAgentAsync), + Source = nameof(DelegateMessageToTestAgentAsync), TextMessage_ = "buffer" }, token: CancellationToken.None); // wait for 10 seconds var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); - while (!TestAgent.ReceivedMessages.ContainsKey(nameof(ItDelegateMessageToTestAgentAsync)) && !cts.Token.IsCancellationRequested) + while (!TestAgent.ReceivedMessages.ContainsKey(nameof(DelegateMessageToTestAgentAsync)) && !cts.Token.IsCancellationRequested) { await Task.Delay(100); } - TestAgent.ReceivedMessages[nameof(ItDelegateMessageToTestAgentAsync)].Should().NotBeNull(); + TestAgent.ReceivedMessages[nameof(DelegateMessageToTestAgentAsync)].Should().NotBeNull(); } /// From b69bbb56e0c2a5f958828f9a2ed47992600b819b Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 12:07:09 -0800 Subject: [PATCH 023/110] remove unused. --- .../AgentTests.cs | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 0eb5bb7c1a0b..02e927b072e9 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -175,43 +175,6 @@ await client.PublishMessageAsync(new TextMessage() TestAgent.ReceivedMessages[nameof(DelegateMessageToTestAgentAsync)].Should().NotBeNull(); } - /// - /// GetAppHost - provides an app host used for one test vs the fixture which is shared. - /// - /// WebApplication - internal static WebApplication GetAppHost() - { - var builder = WebApplication.CreateBuilder(); - builder.Services.TryAddSingleton(DistributedContextPropagator.Current); - builder.AddAgentWorker() - .AddAgent(nameof(TestAgent)); - Host = builder.Build(); - Host.StartAsync().Wait(); - return Host; - } - /// - /// Start - starts the agent - /// - /// IAgentWorker, TestAgent - internal (WebApplication, IAgentWorker, TestAgent) Start() - { - var host = GetAppHost(); - var agent = ActivatorUtilities.CreateInstance(host.Services); - var worker = _serviceProvider.GetRequiredService(); - Agent.Initialize(worker, agent); - return (host, worker, agent); - } - /// - /// Stop - stops the agent - /// - /// WebApplication - /// void - internal static void Stop(WebApplication Host) - { - Host.StopAsync().Wait(); - Host.DisposeAsync().AsTask().Wait(); - } - /// /// The test agent is a simple agent that is used for testing purposes. /// From 1d583230f48d3477336e6da1241d676cd03b0fdc Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 12:11:53 -0800 Subject: [PATCH 024/110] adding test project for grpc core --- dotnet/AutoGen.sln | 7 + .../AgentGrpcTests.cs | 254 ++++++++++++++++++ .../Microsoft.AutoGen.Core.Grpc.Tests.csproj | 16 ++ 3 files changed, 277 insertions(+) create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 116411d25489..76a759e37692 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -142,6 +142,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Test EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevTeam.ServiceDefaults", "samples\dev-team\DevTeam.ServiceDefaults\DevTeam.ServiceDefaults.csproj", "{599E1971-1DA9-453F-A7A8-42510BBC95C2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Grpc.Tests", "test\Microsoft.AutoGen.Core.Grpc.Tests\Microsoft.AutoGen.Core.Grpc.Tests.csproj", "{33A28A4B-123B-4416-9631-0F759B8D6172}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -372,6 +374,10 @@ Global {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {599E1971-1DA9-453F-A7A8-42510BBC95C2}.Release|Any CPU.Build.0 = Release|Any CPU + {33A28A4B-123B-4416-9631-0F759B8D6172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33A28A4B-123B-4416-9631-0F759B8D6172}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33A28A4B-123B-4416-9631-0F759B8D6172}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33A28A4B-123B-4416-9631-0F759B8D6172}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -437,6 +443,7 @@ Global {14F90F79-580E-454D-BA7A-ED6D9723020D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {599E1971-1DA9-453F-A7A8-42510BBC95C2} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} + {33A28A4B-123B-4416-9631-0F759B8D6172} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs new file mode 100644 index 000000000000..275b82e745e2 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -0,0 +1,254 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// AgentGrpcTests.cs + +using System.Collections.Concurrent; +using System.Text.Json; +using FluentAssertions; +using Google.Protobuf.Reflection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AutoGen.Contracts; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Xunit; +using static Microsoft.AutoGen.Core.Grpc.Tests.AgentGrpcTests; + +namespace Microsoft.AutoGen.Core.Grpc.Tests; + +[Collection(GrpcClusterFixtureCollection.Name)] +public class AgentGrpcTests(GrpcRuntimeFixture fixture) +{ + private readonly IServiceProvider _serviceProvider = fixture.AppHost.Services; + private readonly GrpcRuntimeFixture _fixture = fixture; + // need a variable to store the runtime instance + public static WebApplication? Host { get; private set; } + + /// + /// Verify that if the agent is not initialized via AgentWorker, it should throw the correct exception. + /// + /// void + [Fact] + public async Task Agent_ShouldThrowException_WhenNotInitialized() + { + var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + await Assert.ThrowsAsync( + async () => + { + await agent.SubscribeAsync("TestEvent"); + } + ); + } + + /// + /// validate that the agent is initialized correctly with implicit subs + /// + /// void + [Fact] + public async Task Agent_ShouldInitializeCorrectly() + { + var (worker, agent) = _fixture.Start(); + Assert.Equal("AgentWorker", worker.GetType().Name); + var subscriptions = await agent.GetSubscriptionsAsync(); + Assert.Equal(2, subscriptions.Count); + _fixture.Stop(); + } + /// + /// Test SubscribeAsync method + /// + /// void + [Fact] + public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() + { + var (_, agent) = _fixture.Start(); + await agent.SubscribeAsync("TestEvent"); + await Task.Delay(100); + var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + var found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.True(found); + await agent.UnsubscribeAsync("TestEvent").ConfigureAwait(true); + await Task.Delay(500); + subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.False(found); + _fixture.Stop(); + } + + /// + /// Test StoreAsync and ReadAsync methods + /// + /// void + [Fact] + public async Task StoreAsync_and_ReadAsyncTest() + { + var (_, agent) = _fixture.Start(); + Dictionary state = new() + { + { "testdata", "Active" } + }; + await agent.StoreAsync(new AgentState + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); + var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); + var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; + read.TryGetValue("testdata", out var value); + Assert.Equal("Active", value); + _fixture.Stop(); + } + + /// + /// Test PublishMessageAsync method and ReceiveMessage method + /// + /// void + [Fact] + public async Task PublishMessageAsync_and_ReceiveMessageTest() + { + var (_, agent) = _fixture.Start(); + await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); + var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); + var found = false; + foreach (var subscription in subscriptions) + { + if (subscription.TypeSubscription.TopicType == "TestEvent") + { + found = true; + } + } + Assert.True(found); + await agent.PublishMessageAsync(new TextMessage() + { + Source = "TestEvent", + TextMessage_ = "buffer" + }).ConfigureAwait(true); + await Task.Delay(100); + Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); + _fixture.Stop(); + } + + [Fact] + public async Task InvokeCorrectHandler() + { + var agent = new TestAgent(new AgentsMetadata(TypeRegistry.Empty, new Dictionary(), new Dictionary>(), new Dictionary>()), new Logger(new LoggerFactory())); + + await agent.HandleObjectAsync("hello world"); + await agent.HandleObjectAsync(42); + + agent.ReceivedItems.Should().HaveCount(2); + agent.ReceivedItems[0].Should().Be("hello world"); + agent.ReceivedItems[1].Should().Be(42); + } + + [Fact] + public async Task DelegateMessageToTestAgentAsync() + { + var client = _fixture.AppHost.Services.GetRequiredService(); + await client.PublishMessageAsync(new TextMessage() + { + Source = nameof(DelegateMessageToTestAgentAsync), + TextMessage_ = "buffer" + }, token: CancellationToken.None); + + // wait for 10 seconds + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + while (!TestAgent.ReceivedMessages.ContainsKey(nameof(DelegateMessageToTestAgentAsync)) && !cts.Token.IsCancellationRequested) + { + await Task.Delay(100); + } + + TestAgent.ReceivedMessages[nameof(DelegateMessageToTestAgentAsync)].Should().NotBeNull(); + } + + /// + /// The test agent is a simple agent that is used for testing purposes. + /// + public class TestAgent( + [FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes, + Logger? logger = null) : Agent(eventTypes, logger), IHandle + { + public Task Handle(TextMessage item, CancellationToken cancellationToken = default) + { + ReceivedMessages[item.Source] = item.TextMessage_; + return Task.CompletedTask; + } + public Task Handle(string item) + { + ReceivedItems.Add(item); + return Task.CompletedTask; + } + public Task Handle(int item) + { + ReceivedItems.Add(item); + return Task.CompletedTask; + } + public List ReceivedItems { get; private set; } = []; + + /// + /// Key: source + /// Value: message + /// + public static ConcurrentDictionary ReceivedMessages { get; private set; } = new(); + } +} + +/// +/// GrpcRuntimeFixture - provides a fixture for the agent runtime. +/// +/// +/// This fixture is used to provide a runtime for the agent tests. +/// However, it is shared between tests. So operations from one test can affect another. +/// +public sealed class GrpcRuntimeFixture +{ + public GrpcRuntimeFixture() + { + AppHost = StartAppHostAsync().GetAwaiter().GetResult(); + } + + private static async Task StartAppHostAsync() + { + return await AgentsApp.StartAsync().ConfigureAwait(false); + } + public IHost AppHost { get; } + + /// + /// Start - starts the agent + /// + /// IAgentWorker, TestAgent + public (IAgentWorker, TestAgent) Start() + { + var agent = ActivatorUtilities.CreateInstance(AppHost.Services); + var worker = AppHost.Services.GetRequiredService(); + Agent.Initialize(worker, agent); + return (worker, agent); + } + /// + /// Stop - stops the agent + /// + /// void + public void Stop() + { + IHostApplicationLifetime hostApplicationLifetime = AppHost.Services.GetRequiredService(); + hostApplicationLifetime.StopApplication(); + } +} + +[CollectionDefinition(Name)] +public sealed class GrpcClusterFixtureCollection : ICollectionFixture +{ + public const string Name = nameof(GrpcClusterFixtureCollection); +} diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj new file mode 100644 index 000000000000..a4e37298aee1 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj @@ -0,0 +1,16 @@ + + + + $(TestTargetFrameworks) + enable + enable + True + + + + + + + + + From bf907aacbd87d6837d917c7ff0cc7464a134d701 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 12:27:56 -0800 Subject: [PATCH 025/110] update AddGrpcAgentWorker --- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 2 +- .../GrpcAgentWorkerHostBuilderExtension.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index 922ef8a59500..378428ab7ec6 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -20,7 +20,7 @@ public static async ValueTask StartAsync(WebApplicationBuilder? { builder ??= WebApplication.CreateBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); - builder.AddAgentWorker() + builder.AddGrpcAgentWorker() .AddAgents(agentTypes); builder.AddServiceDefaults(); var app = builder.Build(); diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index 34e6276b52bb..657a42430f71 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -1,9 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // GrpcAgentWorkerHostBuilderExtension.cs +using System.Diagnostics; using Grpc.Core; using Grpc.Net.Client.Configuration; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; namespace Microsoft.AutoGen.Core.Grpc; @@ -43,7 +45,22 @@ public static IHostApplicationBuilder AddGrpcAgentWorker(this IHostApplicationBu channelOptions.ThrowOperationCanceledOnCancellation = true; }); }); + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.Services.AddSingleton(); + builder.Services.AddSingleton(sp => (IHostedService)sp.GetRequiredService()); + builder.Services.AddKeyedSingleton("AgentsMetadata", (sp, key) => + { + return ReflectionHelper.GetAgentsMetadata(assemblies); + }); + builder.Services.AddSingleton((s) => { + var worker = s.GetRequiredService(); + var client = ActivatorUtilities.CreateInstance(s); + Agent.Initialize(worker, client); + return client; + }); + builder.Services.AddSingleton(new AgentApplicationBuilder(builder)); + return builder; } } From a2e6ca02dd7a14da66bb2f617b923078b712ea58 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 17:44:49 -0800 Subject: [PATCH 026/110] starting to fix the grpcagentworker and gateway --- .../Core.Grpc/GrpcAgentWorker.cs | 10 ++-- .../Runtime.Grpc/Abstractions/IGateway.cs | 16 ++++--- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 35 ++++++++------ .../Services/Grpc/GrpcGatewayService.cs | 11 +++-- .../Services/Orleans/RegistryGrain.cs | 48 +++++++++++++++++-- .../AgentGrpcTests.cs | 2 +- protos/agent_worker.proto | 9 +++- 7 files changed, 96 insertions(+), 35 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 29d3be57d4c2..1bd282386ef3 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -399,17 +399,21 @@ public async ValueTask ReadAsync(AgentId agentId, CancellationToken public ValueTask> GetSubscriptionsAsync(Type type) { - throw new NotImplementedException(); + var agentId = new AgentId { Type = type.Name }; + var response = _client.GetSubscriptions(agentId); + return new ValueTask>([.. response.Subscriptions]); } public ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + var response = _client.Subscribe(request, null, null, cancellationToken); + return new ValueTask(response); } public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + var response = _client.Unsubscribe(request, null, null, cancellationToken); + return new ValueTask(response); } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs index 3d7044f96d87..d25c42b9dee6 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs @@ -6,11 +6,13 @@ namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; public interface IGateway : IGrainObserver { - ValueTask InvokeRequest(RpcRequest request); - ValueTask BroadcastEvent(CloudEvent evt); - ValueTask StoreAsync(Contracts.AgentState value); - ValueTask ReadAsync(AgentId agentId); - ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request); - ValueTask AddSubscriptionAsync(SubscriptionRequest request); - Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); + ValueTask InvokeRequestAsync(RpcRequest request, CancellationToken cancellationToken = default); + ValueTask BroadcastEventAsync(CloudEvent evt, CancellationToken cancellationToken = default); + ValueTask StoreAsync(Contracts.AgentState value, CancellationToken cancellationToken = default); + ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); + ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request, CancellationToken cancellationToken = default); + ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default); + Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index fe76aaa6fe99..a5b2610730d3 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -39,7 +39,7 @@ public GrpcGateway(IClusterClient clusterClient, ILogger logger) _gatewayRegistry = clusterClient.GetGrain(0); _subscriptions = clusterClient.GetGrain(0); } - public async ValueTask InvokeRequest(RpcRequest request, CancellationToken cancellationToken = default) + public async ValueTask InvokeRequestAsync(RpcRequest request, CancellationToken cancellationToken = default) { var agentId = (request.Target.Type, request.Target.Key); if (!_agentDirectory.TryGetValue(agentId, out var connection) || connection.Completion.IsCompleted == true) @@ -66,18 +66,18 @@ public async ValueTask InvokeRequest(RpcRequest request, Cancellati response.RequestId = originalRequestId; return response; } - public async ValueTask StoreAsync(AgentState value) + public async ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) { _ = value.AgentId ?? throw new ArgumentNullException(nameof(value.AgentId)); var agentState = _clusterClient.GetGrain($"{value.AgentId.Type}:{value.AgentId.Key}"); await agentState.WriteStateAsync(value, value.ETag); } - public async ValueTask ReadAsync(AgentId agentId) + public async ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default) { var agentState = _clusterClient.GetGrain($"{agentId.Type}:{agentId.Key}"); return await agentState.ReadStateAsync(); } - public async ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request) + public async ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request, CancellationToken cancellationToken = default) { try { @@ -102,7 +102,7 @@ public async ValueTask RegisterAgentTypeAsync(Registe }; } } - public async ValueTask AddSubscriptionAsync(SubscriptionRequest request) + public async ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) { try { @@ -280,7 +280,7 @@ await InvokeRequestDelegate(connection, request, async request => // TODO// Activate the worker: load state } // Forward the message to the gateway and return the result. - return await gateway.InvokeRequest(request).ConfigureAwait(true); + return await gateway.InvokeRequestAsync(request).ConfigureAwait(true); }).ConfigureAwait(false); } private static async Task InvokeRequestDelegate(GrpcWorkerConnection connection, RpcRequest request, Func> func) @@ -365,12 +365,7 @@ private async ValueTask DispatchEventToAgentsAsync(IEnumerable agentType } await Task.WhenAll(tasks).ConfigureAwait(false); } - - async ValueTask IGateway.InvokeRequest(RpcRequest request) - { - return await this.InvokeRequest(request).ConfigureAwait(false); - } - public async ValueTask BroadcastEvent(CloudEvent evt) + public async ValueTask BroadcastEventAsync(CloudEvent evt, CancellationToken cancellationToken = default) { var tasks = new List(_workers.Count); foreach (var (_, connection) in _supportedAgentTypes) @@ -380,13 +375,23 @@ public async ValueTask BroadcastEvent(CloudEvent evt) } await Task.WhenAll(tasks).ConfigureAwait(false); } - Task IGateway.SendMessageAsync(IConnection connection, CloudEvent cloudEvent) + Task IGateway.SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken) { - return this.SendMessageAsync(connection, cloudEvent); + return this.SendMessageAsync(connection, cloudEvent, cancellationToken); } - public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) + public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { var queue = (GrpcWorkerConnection)connection; await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); } + + public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public ValueTask GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index 56c5d919c3f3..276fb187df0e 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -42,14 +42,19 @@ public override async Task SaveState(AgentState request, Serv Success = true // TODO: Implement error handling }; } - public override async Task AddSubscription(SubscriptionRequest request, ServerCallContext context) + public override async Task Subscribe(SubscriptionRequest request, ServerCallContext context) { request.RequestId = context.Peer; - return await Gateway.AddSubscriptionAsync(request); + return await Gateway.SubscribeAsync(request).ConfigureAwait(true); + } + public override async Task Unsubscribe(SubscriptionRequest request, ServerCallContext context) + { + request.RequestId = context.Peer; + return await Gateway.UnsubscribeAsync(request).ConfigureAwait(true); } public override async Task RegisterAgent(RegisterAgentTypeRequest request, ServerCallContext context) { request.RequestId = context.Peer; - return await Gateway.RegisterAgentTypeAsync(request); + return await Gateway.RegisterAgentTypeAsync(request).ConfigureAwait(true); } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index fab3c8b6eb63..bcb30b637a8f 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -176,6 +176,7 @@ public async ValueTask SubscribeAsync(SubscriptionRequest sub) { switch (sub.Subscription.SubscriptionCase) { + //TODO: this doesnt look right case Subscription.SubscriptionOneofCase.TypePrefixSubscription: break; case Subscription.SubscriptionOneofCase.TypeSubscription: @@ -196,9 +197,7 @@ public async ValueTask SubscribeAsync(SubscriptionRequest sub) agents = new HashSet(); state.State.TopicToAgentTypesMap[sub.Subscription.TypeSubscription.TopicType] = agents; } - agents.Add(sub.Subscription.TypeSubscription.AgentType); - break; } default: @@ -208,12 +207,53 @@ public async ValueTask SubscribeAsync(SubscriptionRequest sub) } public async ValueTask UnsubscribeAsync(SubscriptionRequest request) { - throw new NotImplementedException(); + switch (request.Subscription.SubscriptionCase) + { + case Subscription.SubscriptionOneofCase.TypePrefixSubscription: + break; + case Subscription.SubscriptionOneofCase.TypeSubscription: + { + // remove the topic from the set of topics for the agent type + state.State.AgentsToTopicsMap.TryGetValue(request.Subscription.TypeSubscription.AgentType, out var topics); + if (topics is not null) + { + while(topics.Remove(request.Subscription.TypeSubscription.TopicType)) + { + // ensures all instances are removed + } + } + + // remove the agent type from the set of agent types for the topic + state.State.TopicToAgentTypesMap.TryGetValue(request.Subscription.TypeSubscription.TopicType, out var agents); + if (agents is not null) + { + while(agents.Remove(request.Subscription.TypeSubscription.AgentType)) + { + // ensures all instances are removed + } + } + break; + } + default: + throw new InvalidOperationException("Invalid subscription type"); + } + await state.WriteStateAsync().ConfigureAwait(false); } public ValueTask>> GetSubscriptions(string agentType) { - throw new NotImplementedException(); + var subscriptions = new Dictionary>(); + if (state.State.AgentsToTopicsMap.TryGetValue(agentType, out var topics)) + { + foreach (var topic in topics) + { + if (state.State.TopicToAgentTypesMap.TryGetValue(topic, out var agents)) + { + subscriptions[topic] = agents.ToList(); + } + } + } + return new(subscriptions); } private sealed class WorkerState diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 275b82e745e2..0b2aa05382af 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -47,7 +47,7 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() public async Task Agent_ShouldInitializeCorrectly() { var (worker, agent) = _fixture.Start(); - Assert.Equal("AgentWorker", worker.GetType().Name); + Assert.Equal("GrpcAgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); _fixture.Stop(); diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index 09eb1b3fb18e..543b3fba1321 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -77,6 +77,10 @@ message Subscription { } } +message SubscriptionList { + repeated Subscription subscriptions = 1; +} + message SubscriptionRequest { string request_id = 1; Subscription subscription = 2; @@ -93,8 +97,9 @@ service AgentRpc { rpc GetState(AgentId) returns (GetStateResponse); rpc SaveState(AgentState) returns (SaveStateResponse); rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse); - rpc AddSubscription(SubscriptionRequest) returns (SubscriptionResponse); - rpc RemoveSubscription(SubscriptionRequest) returns (SubscriptionResponse); + rpc Subscribe(SubscriptionRequest) returns (SubscriptionResponse); + rpc Unsubscribe(SubscriptionRequest) returns (SubscriptionResponse); + rpc GetSubscriptions(AgentId) returns (SubscriptionList); } message AgentState { From 9fc15f3ea9406008a8160f9193e1512c23c0a9ae Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 17:46:36 -0800 Subject: [PATCH 027/110] format --- .../dev-team/DevTeam.Backend/Program.cs | 14 ++++++------- .../Services/GithubWebHookProcessor.cs | 2 +- .../GrpcAgentWorkerHostBuilderExtension.cs | 3 ++- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 2 +- dotnet/src/Microsoft.AutoGen/Core/Client.cs | 2 +- .../Core/HostBuilderExtensions.cs | 3 ++- dotnet/src/Microsoft.AutoGen/Core/IHandle.cs | 2 +- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 4 ++-- .../Services/Orleans/AgentsRegistryState.cs | 2 +- .../Services/Orleans/RegistryGrain.cs | 4 ++-- .../Orleans/Surrogates/AgentStateSurrogate.cs | 21 +++++++++---------- .../AgentGrpcTests.cs | 8 +++---- .../AgentTests.cs | 8 +++---- .../GrpcGatewayServiceTests.cs | 2 +- .../Helpers/Grpc/TestGrpcClient.cs | 2 +- 15 files changed, 40 insertions(+), 39 deletions(-) diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs index a2ba9021c271..ee75f056c1cf 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Program.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Program.cs @@ -2,18 +2,18 @@ // Program.cs using Azure.Identity; +using DevTeam.Backend.Agents; +using DevTeam.Backend.Agents.Developer; +using DevTeam.Backend.Agents.DeveloperLead; +using DevTeam.Backend.Agents.ProductManager; +using DevTeam.Backend.Services; using DevTeam.Options; +using Microsoft.AutoGen.Core; +using Microsoft.AutoGen.Core.Grpc; using Microsoft.Extensions.Azure; using Microsoft.Extensions.Options; -using Microsoft.AutoGen.Core; using Octokit.Webhooks; using Octokit.Webhooks.AspNetCore; -using DevTeam.Backend.Services; -using DevTeam.Backend.Agents; -using DevTeam.Backend.Agents.ProductManager; -using DevTeam.Backend.Agents.DeveloperLead; -using DevTeam.Backend.Agents.Developer; -using Microsoft.AutoGen.Core.Grpc; var builder = WebApplication.CreateBuilder(args); diff --git a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs index 7264f5621311..b3d0b1aa2f5c 100644 --- a/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs +++ b/dotnet/samples/dev-team/DevTeam.Backend/Services/GithubWebHookProcessor.cs @@ -116,7 +116,7 @@ private async Task HandleClosingIssue(long issueNumber, string skillName, string IMessage evt = (skillName, functionName) switch { - ("PM", "Readme") => new ReadmeChainClosed { }, + ("PM", "Readme") => new ReadmeChainClosed { }, ("DevLead", "Plan") => new DevPlanChainClosed { }, ("Developer", "Implement") => new CodeChainClosed { }, _ => new CloudEvent() // TODO: default event diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index 657a42430f71..fe8aaefa484d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -53,7 +53,8 @@ public static IHostApplicationBuilder AddGrpcAgentWorker(this IHostApplicationBu { return ReflectionHelper.GetAgentsMetadata(assemblies); }); - builder.Services.AddSingleton((s) => { + builder.Services.AddSingleton((s) => + { var worker = s.GetRequiredService(); var client = ActivatorUtilities.CreateInstance(s); Agent.Initialize(worker, client); diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 9385d9fda223..c70f50446919 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -297,7 +297,7 @@ static async (state, ct) => /// The source of the message. /// A token to cancel the operation. /// A task representing the asynchronous operation. - public async ValueTask PublishMessageAsync(T @event, string? topic = null, string? key = null, CancellationToken token = default ) where T : IMessage + public async ValueTask PublishMessageAsync(T @event, string? topic = null, string? key = null, CancellationToken token = default) where T : IMessage { var k = string.IsNullOrWhiteSpace(key) ? AgentId.Key : key; var topicType = string.IsNullOrWhiteSpace(topic) ? "default" : topic; diff --git a/dotnet/src/Microsoft.AutoGen/Core/Client.cs b/dotnet/src/Microsoft.AutoGen/Core/Client.cs index f689751b4002..132dcd998c5c 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Client.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Client.cs @@ -6,4 +6,4 @@ namespace Microsoft.AutoGen.Core; public sealed class Client([FromKeyedServices("AgentsMetadata")] AgentsMetadata eventTypes) : Agent(eventTypes) { -} \ No newline at end of file +} diff --git a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs index e48195c63a6e..339ea6fd12b2 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/HostBuilderExtensions.cs @@ -35,7 +35,8 @@ public static IHostApplicationBuilder AddAgentWorker(this IHostApplicationBuilde { return ReflectionHelper.GetAgentsMetadata(assemblies); }); - builder.Services.AddSingleton((s) => { + builder.Services.AddSingleton((s) => + { var worker = s.GetRequiredService(); var client = ActivatorUtilities.CreateInstance(s); Agent.Initialize(worker, client); diff --git a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs index 0b91f4436d4c..cb1dd62de406 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IHandle.cs @@ -17,4 +17,4 @@ public interface IHandle where T : IMessage /// The item to be handled. /// A task that represents the asynchronous operation. Task Handle(T item, CancellationToken cancellationToken = default); -} \ No newline at end of file +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index a5b2610730d3..0303bb7b1d89 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -159,7 +159,7 @@ internal async Task ConnectToWorkerProcess(IAsyncStreamReader r { completion.SetResult(workerProcess.Connect()); }); - + await completion.Task; return connectionId; } @@ -197,7 +197,7 @@ private void DispatchResponse(GrpcWorkerConnection connection, RpcResponse respo { if (!_pendingRequests.TryRemove((connection, response.RequestId), out var completion)) { - _logger.LogWarning("Received response for unknown request id: {RequestId}.", response.RequestId); + _logger.LogWarning("Received response for unknown request id: {RequestId}.", response.RequestId); return; } // Complete the request. diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs index 122821270f65..3e69bd3cc3a9 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // AgentsRegistryState.cs namespace Microsoft.AutoGen.Runtime.Grpc; diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index bcb30b637a8f..81a551accd92 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -217,7 +217,7 @@ public async ValueTask UnsubscribeAsync(SubscriptionRequest request) state.State.AgentsToTopicsMap.TryGetValue(request.Subscription.TypeSubscription.AgentType, out var topics); if (topics is not null) { - while(topics.Remove(request.Subscription.TypeSubscription.TopicType)) + while (topics.Remove(request.Subscription.TypeSubscription.TopicType)) { // ensures all instances are removed } @@ -227,7 +227,7 @@ public async ValueTask UnsubscribeAsync(SubscriptionRequest request) state.State.TopicToAgentTypesMap.TryGetValue(request.Subscription.TypeSubscription.TopicType, out var agents); if (agents is not null) { - while(agents.Remove(request.Subscription.TypeSubscription.AgentType)) + while (agents.Remove(request.Subscription.TypeSubscription.AgentType)) { // ensures all instances are removed } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs index 1b1df59a91bc..a5291f942155 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AgentStateSurrogate.cs @@ -29,18 +29,17 @@ public sealed class AgentStateSurrogateConverter : { public AgentState ConvertFromSurrogate( in AgentStateSurrogate surrogate) + { + var agentState = new AgentState { - var agentState = new AgentState - { - AgentId = surrogate.AgentId, - BinaryData = surrogate.BinaryData, - TextData = surrogate.TextData, - ETag = surrogate.Etag - }; - //agentState.ProtoData = surrogate.ProtoData; - return agentState; - } - + AgentId = surrogate.AgentId, + BinaryData = surrogate.BinaryData, + TextData = surrogate.TextData, + ETag = surrogate.Etag + }; + //agentState.ProtoData = surrogate.ProtoData; + return agentState; + } public AgentStateSurrogate ConvertToSurrogate( in AgentState value) => diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 0b2aa05382af..d780af87e5bc 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -100,10 +100,10 @@ public async Task StoreAsync_and_ReadAsyncTest() { "testdata", "Active" } }; await agent.StoreAsync(new AgentState - { - AgentId = agent.AgentId, - TextData = JsonSerializer.Serialize(state) - }).ConfigureAwait(true); + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 02e927b072e9..1e7b5ff10166 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -102,10 +102,10 @@ public async Task StoreAsync_and_ReadAsyncTest() { "testdata", "Active" } }; await agent.StoreAsync(new AgentState - { - AgentId = agent.AgentId, - TextData = JsonSerializer.Serialize(state) - }).ConfigureAwait(true); + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 841264a1230a..12035da98144 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -29,7 +29,7 @@ public async Task Test_OpenChannel() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - + gateway.WorkersCount.Should().Be(0); await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); gateway.WorkersCount.Should().Be(1); diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs index 78724a43bf45..6795c9f9237f 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs @@ -4,7 +4,7 @@ using Microsoft.AutoGen.Contracts; namespace Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Grpc; -internal sealed class TestGrpcClient: IDisposable +internal sealed class TestGrpcClient : IDisposable { public TestAsyncStreamReader RequestStream { get; } public TestServerStreamWriter ResponseStream { get; } From d69a7da3ec5c0a93dbca50544b2252e3611f3490 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 17:47:10 -0800 Subject: [PATCH 028/110] format --- .../AgentGrpcTests.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index d780af87e5bc..eadfa88cbc7a 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -47,7 +47,8 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() public async Task Agent_ShouldInitializeCorrectly() { var (worker, agent) = _fixture.Start(); - Assert.Equal("GrpcAgentWorker", worker.GetType().Name); + Assert.Equal("Grpc + AgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); _fixture.Stop(); @@ -100,10 +101,10 @@ public async Task StoreAsync_and_ReadAsyncTest() { "testdata", "Active" } }; await agent.StoreAsync(new AgentState - { - AgentId = agent.AgentId, - TextData = JsonSerializer.Serialize(state) - }).ConfigureAwait(true); + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); From ad9450275c540b2fbd597fb6e31ce294e9bac886 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 7 Jan 2025 17:53:42 -0800 Subject: [PATCH 029/110] format --- .../Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index eadfa88cbc7a..9b5808318500 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -101,10 +101,10 @@ public async Task StoreAsync_and_ReadAsyncTest() { "testdata", "Active" } }; await agent.StoreAsync(new AgentState - { - AgentId = agent.AgentId, - TextData = JsonSerializer.Serialize(state) - }).ConfigureAwait(true); + { + AgentId = agent.AgentId, + TextData = JsonSerializer.Serialize(state) + }).ConfigureAwait(true); var readState = await agent.ReadAsync(agent.AgentId).ConfigureAwait(true); var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); From 11558c2ad4ff21e579af4787f5fb71b71762b598 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 8 Jan 2025 07:46:31 -0800 Subject: [PATCH 030/110] seems like there was a typo --- .../test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 9b5808318500..d780af87e5bc 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -47,8 +47,7 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() public async Task Agent_ShouldInitializeCorrectly() { var (worker, agent) = _fixture.Start(); - Assert.Equal("Grpc - AgentWorker", worker.GetType().Name); + Assert.Equal("GrpcAgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); _fixture.Stop(); From c3de0ad277ef926bbbe6c9c8147a865f92570a45 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 10 Jan 2025 09:23:28 -0800 Subject: [PATCH 031/110] interim - trying to fix DI error --- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 2 ++ .../Core.Grpc/Microsoft.AutoGen.Core.Grpc.csproj | 1 + .../Orleans/OrleansRuntimeHostingExtenions.cs | 2 +- .../Properties/launchSettings.json | 13 +++++++++++++ .../appsettings.json | 15 +++++++++++++++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Properties/launchSettings.json create mode 100644 dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index 378428ab7ec6..6f9645146265 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; +using Microsoft.AutoGen.Runtime.Grpc; namespace Microsoft.AutoGen.Core.Grpc; @@ -20,6 +21,7 @@ public static async ValueTask StartAsync(WebApplicationBuilder? { builder ??= WebApplication.CreateBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); + builder.AddOrleans(); builder.AddGrpcAgentWorker() .AddAgents(agentTypes); builder.AddServiceDefaults(); diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/Microsoft.AutoGen.Core.Grpc.csproj b/dotnet/src/Microsoft.AutoGen/Core.Grpc/Microsoft.AutoGen.Core.Grpc.csproj index a56f306d04b6..9ab2d7419faf 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/Microsoft.AutoGen.Core.Grpc.csproj +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/Microsoft.AutoGen.Core.Grpc.csproj @@ -9,6 +9,7 @@ + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs index 68e0c7af745c..fe2ae54d3b07 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs @@ -17,7 +17,6 @@ public static class OrleansRuntimeHostingExtenions public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builder) { builder.Services.AddSerializer(serializer => serializer.AddProtobufSerializer()); - builder.Services.AddSingleton(); // Ensure Orleans is added before the hosted service to guarantee that it starts first. //TODO: make all of this configurable @@ -86,6 +85,7 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde .AddMemoryGrainStorage("PubSubStore"); } }); + builder.Services.AddSingleton(); return builder; } diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Properties/launchSettings.json b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Properties/launchSettings.json new file mode 100644 index 000000000000..cfddee319d65 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "AgentHost": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:50670;http://localhost:50673", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json new file mode 100644 index 000000000000..ae32fe371a70 --- /dev/null +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning", + "Microsoft": "Warning", + "Microsoft.Orleans": "Warning" + } + }, + "AllowedHosts": "*", + "Kestrel": { + "EndpointDefaults": { + "Protocols": "Http2" + } + } +} From 5ecf4a59b554a6132b66cd64d97eb0c7aed5fb2a Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 14 Jan 2025 13:56:04 -0800 Subject: [PATCH 032/110] attempting fix --- .../Services/Orleans/OrleansRuntimeHostingExtenions.cs | 1 + .../Runtime.Grpc/Services/Orleans/RegistryGrain.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs index fe2ae54d3b07..5b1abc477a1a 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs @@ -28,6 +28,7 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde siloBuilder.UseLocalhostClustering() .AddMemoryStreams("StreamProvider") .AddMemoryGrainStorage("PubSubStore") + .AddMemoryGrainStorage("AgentRegistryStore") .AddMemoryGrainStorage("AgentStateStore"); siloBuilder.UseInMemoryReminderService(); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 81a551accd92..ea9b463d2152 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -5,7 +5,7 @@ using Microsoft.AutoGen.Runtime.Grpc.Abstractions; namespace Microsoft.AutoGen.Runtime.Grpc; -internal sealed class RegistryGrain([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IRegistryGrain +internal sealed class RegistryGrain([PersistentState("state", "AgentRegistryStore")] IPersistentState state) : Grain, IRegistryGrain { // TODO: use persistent state for some of these or (better) extend Orleans to implement some of this natively. private readonly Dictionary _workerStates = new(); From 3f29976703acbea2b1dcc6dc5be1e856d2c307e3 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 14 Jan 2025 15:56:52 -0800 Subject: [PATCH 033/110] ok, resolve the startup errors finally --- .../Runtime.Grpc/Abstractions/IGateway.cs | 18 ++--- .../Runtime.Grpc/Abstractions/IRegistry.cs | 2 +- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 70 +++++++++++++++++-- .../Orleans/OrleansRuntimeHostingExtenions.cs | 9 +-- .../Services/Orleans/RegistryGrain.cs | 14 ++-- 5 files changed, 83 insertions(+), 30 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs index d25c42b9dee6..02aeb6bf0c3f 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs @@ -6,13 +6,13 @@ namespace Microsoft.AutoGen.Runtime.Grpc.Abstractions; public interface IGateway : IGrainObserver { - ValueTask InvokeRequestAsync(RpcRequest request, CancellationToken cancellationToken = default); - ValueTask BroadcastEventAsync(CloudEvent evt, CancellationToken cancellationToken = default); - ValueTask StoreAsync(Contracts.AgentState value, CancellationToken cancellationToken = default); - ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); - ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request, CancellationToken cancellationToken = default); - ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); - ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); - ValueTask GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default); - Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default); + ValueTask InvokeRequestAsync(RpcRequest request); + ValueTask BroadcastEventAsync(CloudEvent evt); + ValueTask StoreAsync(Contracts.AgentState value); + ValueTask ReadAsync(AgentId agentId); + ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request); + ValueTask SubscribeAsync(SubscriptionRequest request); + ValueTask UnsubscribeAsync(SubscriptionRequest request); + ValueTask> GetSubscriptionsAsync(Type type); + Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs index 31ff29a0600e..08007dd4ad62 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs @@ -81,5 +81,5 @@ public interface IRegistry /// /// The type of the agent. /// A task representing the asynchronous operation, with the subscriptions as the result. - ValueTask>> GetSubscriptions(string agentType); + ValueTask> GetSubscriptions(string agentType); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 0303bb7b1d89..f423e712bdf1 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -349,7 +349,6 @@ private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, Su }; await connection.ResponseStream.WriteAsync(response).ConfigureAwait(false); } - private async ValueTask DispatchEventToAgentsAsync(IEnumerable agentTypes, CloudEvent evt) { var tasks = new List(agentTypes.Count()); @@ -375,9 +374,9 @@ public async ValueTask BroadcastEventAsync(CloudEvent evt, CancellationToken can } await Task.WhenAll(tasks).ConfigureAwait(false); } - Task IGateway.SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken) + Task IGateway.SendMessageAsync(IConnection connection, CloudEvent cloudEvent) { - return this.SendMessageAsync(connection, cloudEvent, cancellationToken); + return this.SendMessageAsync(connection, cloudEvent, default); } public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { @@ -385,13 +384,70 @@ public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); } - public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public async ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + { + try + { + await _gatewayRegistry.UnsubscribeAsync(request).ConfigureAwait(true); + return new SubscriptionResponse + { + Success = true, + RequestId = request.RequestId + }; + } + catch (Exception ex) + { + return new SubscriptionResponse + { + Success = false, + RequestId = request.RequestId, + Error = ex.Message + }; + } + } + + public ValueTask> GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default) + { + return _gatewayRegistry.GetSubscriptions(nameof(type)); + } + + async ValueTask IGateway.InvokeRequestAsync(RpcRequest request) + { + return await InvokeRequestAsync(request, default).ConfigureAwait(false); + } + + async ValueTask IGateway.BroadcastEventAsync(CloudEvent evt) + { + await BroadcastEventAsync(evt, default).ConfigureAwait(false); + } + + ValueTask IGateway.StoreAsync(AgentState value) + { + return StoreAsync(value, default); + } + + ValueTask IGateway.ReadAsync(AgentId agentId) + { + return ReadAsync(agentId, default); + } + + ValueTask IGateway.RegisterAgentTypeAsync(RegisterAgentTypeRequest request) + { + return RegisterAgentTypeAsync(request, default); + } + + ValueTask IGateway.SubscribeAsync(SubscriptionRequest request) + { + return SubscribeAsync(request, default); + } + + ValueTask IGateway.UnsubscribeAsync(SubscriptionRequest request) { - throw new NotImplementedException(); + return UnsubscribeAsync(request, default); } - public ValueTask GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default) + ValueTask> IGateway.GetSubscriptionsAsync(Type type) { - throw new NotImplementedException(); + return GetSubscriptionsAsync(type, default); } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs index 5b1abc477a1a..e83db26ad0b7 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/OrleansRuntimeHostingExtenions.cs @@ -3,7 +3,6 @@ using System.Configuration; using Microsoft.AspNetCore.Builder; -using Microsoft.AutoGen.Runtime.Grpc.Abstractions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -41,12 +40,7 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde var cosmosDbconnectionString = builder.Configuration.GetValue("Orleans:CosmosDBConnectionString") ?? throw new ConfigurationErrorsException( "Orleans:CosmosDBConnectionString is missing from configuration. This is required for persistence in production environments."); - siloBuilder.Configure(options => - { - //TODO: make this configurable - options.ClusterId = "AutoGen-cluster"; - options.ServiceId = "AutoGen-cluster"; - }); + siloBuilder.Configure(options => { options.ResponseTimeout = TimeSpan.FromMinutes(3); @@ -86,7 +80,6 @@ public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builde .AddMemoryGrainStorage("PubSubStore"); } }); - builder.Services.AddSingleton(); return builder; } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index ea9b463d2152..c3fbd58dbd43 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -240,17 +240,21 @@ public async ValueTask UnsubscribeAsync(SubscriptionRequest request) await state.WriteStateAsync().ConfigureAwait(false); } - public ValueTask>> GetSubscriptions(string agentType) + public ValueTask> GetSubscriptions(string agentType) { - var subscriptions = new Dictionary>(); + var subscriptions = new List(); if (state.State.AgentsToTopicsMap.TryGetValue(agentType, out var topics)) { foreach (var topic in topics) { - if (state.State.TopicToAgentTypesMap.TryGetValue(topic, out var agents)) + subscriptions.Add(new Subscription { - subscriptions[topic] = agents.ToList(); - } + TypeSubscription = new TypeSubscription + { + AgentType = agentType, + TopicType = topic + } + }); } } return new(subscriptions); From 7aee5c9c7e3eadd8e0153c9cdfa4b45544ffe7f0 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 14 Jan 2025 15:59:04 -0800 Subject: [PATCH 034/110] format --- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index 6f9645146265..d453606146a9 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -4,10 +4,10 @@ using System.Diagnostics.CodeAnalysis; using Google.Protobuf; using Microsoft.AspNetCore.Builder; +using Microsoft.AutoGen.Runtime.Grpc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; -using Microsoft.AutoGen.Runtime.Grpc; namespace Microsoft.AutoGen.Core.Grpc; From 632e934778ca237fe3aa54f5e3daf21e7a55f065 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 15 Jan 2025 11:24:36 -0800 Subject: [PATCH 035/110] set Dev env for tests --- dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index d780af87e5bc..383de27c6ef7 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -216,6 +216,7 @@ public sealed class GrpcRuntimeFixture { public GrpcRuntimeFixture() { + Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); AppHost = StartAppHostAsync().GetAwaiter().GetResult(); } From 0d9bf518dfe342583c08bc2c11d5c29f4e139a81 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 15 Jan 2025 13:31:40 -0800 Subject: [PATCH 036/110] checkpoint --- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 3 --- .../Microsoft.AutoGen.Runtime.Grpc.csproj | 1 + .../Services/AgentWorkerHostingExtensions.cs | 5 +++++ .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 4 ++++ .../Services/Grpc/GrpcGatewayService.cs | 5 +++++ .../AgentGrpcTests.cs | 16 +++++++++++++--- .../Microsoft.AutoGen.Core.Grpc.Tests.csproj | 1 + 7 files changed, 29 insertions(+), 6 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index d453606146a9..5d72bc5eda5e 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis; using Google.Protobuf; using Microsoft.AspNetCore.Builder; -using Microsoft.AutoGen.Runtime.Grpc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -21,12 +20,10 @@ public static async ValueTask StartAsync(WebApplicationBuilder? { builder ??= WebApplication.CreateBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); - builder.AddOrleans(); builder.AddGrpcAgentWorker() .AddAgents(agentTypes); builder.AddServiceDefaults(); var app = builder.Build(); - app.MapDefaultEndpoints(); Host = app; await app.StartAsync().ConfigureAwait(false); return Host; diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Microsoft.AutoGen.Runtime.Grpc.csproj b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Microsoft.AutoGen.Runtime.Grpc.csproj index 27474cef7900..b874a657d8f2 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Microsoft.AutoGen.Runtime.Grpc.csproj +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Microsoft.AutoGen.Runtime.Grpc.csproj @@ -6,6 +6,7 @@ + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs index bd2ecfa9a8a7..4c1ec149ab8a 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; +using Microsoft.AutoGen.Core; namespace Microsoft.AutoGen.Runtime.Grpc; public static class AgentWorkerHostingExtensions @@ -17,6 +18,10 @@ public static WebApplicationBuilder AddAgentService(this WebApplicationBuilder b builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.Services.AddGrpc(); + builder.Services.AddKeyedSingleton("AgentsMetadata", (sp, key) => + { + return ReflectionHelper.GetAgentsMetadata(AppDomain.CurrentDomain.GetAssemblies()); + }); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => (IHostedService)sp.GetRequiredService()); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index f423e712bdf1..cc66529083d9 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -410,6 +410,10 @@ public ValueTask> GetSubscriptionsAsync(Type type, Cancellati { return _gatewayRegistry.GetSubscriptions(nameof(type)); } + public ValueTask> GetSubscriptionsAsync(string type, CancellationToken cancellationToken = default) + { + return _gatewayRegistry.GetSubscriptions(type); + } async ValueTask IGateway.InvokeRequestAsync(RpcRequest request) { diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index 276fb187df0e..18ca0b407a9a 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -52,6 +52,11 @@ public override async Task Unsubscribe(SubscriptionRequest request.RequestId = context.Peer; return await Gateway.UnsubscribeAsync(request).ConfigureAwait(true); } + public override async Task GetSubscriptions(AgentId request, ServerCallContext context) + { + var subscriptions = await Gateway.GetSubscriptionsAsync(request.Type); + return new SubscriptionList { Subscriptions = { subscriptions } }; + } public override async Task RegisterAgent(RegisterAgentTypeRequest request, ServerCallContext context) { request.RequestId = context.Peer; diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 383de27c6ef7..505a32cdc18d 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -217,13 +217,23 @@ public sealed class GrpcRuntimeFixture public GrpcRuntimeFixture() { Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); + Environment.SetEnvironmentVariable("ASPNETCORE_HTTPS_PORTS", "53071"); + Environment.SetEnvironmentVariable("AGENT_HOST", "https://localhost:53071"); AppHost = StartAppHostAsync().GetAwaiter().GetResult(); + Environment.SetEnvironmentVariable("ASPNETCORE_URLS", "https://+;http://+"); + Client = StartClientAsync().GetAwaiter().GetResult(); } - private static async Task StartAppHostAsync() + private static async Task StartClientAsync() { return await AgentsApp.StartAsync().ConfigureAwait(false); } + private static async Task StartAppHostAsync() + { + return await Microsoft.AutoGen.Runtime.Grpc.Host.StartAsync(local: false, useGrpc: true).ConfigureAwait(false); + + } + public IHost Client { get; } public IHost AppHost { get; } /// @@ -232,8 +242,8 @@ private static async Task StartAppHostAsync() /// IAgentWorker, TestAgent public (IAgentWorker, TestAgent) Start() { - var agent = ActivatorUtilities.CreateInstance(AppHost.Services); - var worker = AppHost.Services.GetRequiredService(); + var agent = ActivatorUtilities.CreateInstance(Client.Services); + var worker = Client.Services.GetRequiredService(); Agent.Initialize(worker, agent); return (worker, agent); } diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj index a4e37298aee1..f14497e75fbc 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/Microsoft.AutoGen.Core.Grpc.Tests.csproj @@ -10,6 +10,7 @@ + From 1e06db2f9564c02215a24adb25c20855d71de3c3 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 15 Jan 2025 13:51:37 -0800 Subject: [PATCH 037/110] cleanup --- .../Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 3 +-- .../Services/Orleans/AgentStateGrain.cs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 1bd282386ef3..7292549312fd 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -40,8 +40,7 @@ public sealed class GrpcAgentWorker( private Task? _readTask; private Task? _writeTask; - IServiceProvider IAgentWorker.ServiceProvider => throw new NotImplementedException(); - + IServiceProvider IAgentWorker.ServiceProvider => ServiceProvider; public void Dispose() { _outboundMessagesChannel.Writer.TryComplete(); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentStateGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentStateGrain.cs index 9d46be929ea9..e926f374a61e 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentStateGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentStateGrain.cs @@ -2,10 +2,11 @@ // AgentStateGrain.cs using Microsoft.AutoGen.Contracts; +using Microsoft.AutoGen.Runtime.Grpc.Abstractions; namespace Microsoft.AutoGen.Runtime.Grpc; -internal sealed class AgentStateGrain([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IAgentState +internal sealed class AgentStateGrain([PersistentState("state", "AgentStateStore")] IPersistentState state) : Grain, IAgentState, IAgentGrain { /// public async ValueTask WriteStateAsync(AgentState newState, string eTag, CancellationToken cancellationToken = default) @@ -33,4 +34,14 @@ public ValueTask ReadStateAsync(CancellationToken cancellationToken { return ValueTask.FromResult(state.State); } + + ValueTask IAgentGrain.ReadStateAsync() + { + return ReadStateAsync(); + } + + ValueTask IAgentGrain.WriteStateAsync(AgentState state, string eTag) + { + return WriteStateAsync(state, eTag); + } } From 6ae606733b01725c061ba9ec74d5feae8fb25bfe Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 11:53:39 -0800 Subject: [PATCH 038/110] stashy --- dotnet/samples/Hello/Hello.AppHost/Program.cs | 2 +- .../AgentHost/Properties/launchSettings.json | 2 +- .../AgentHost/appsettings.json | 5 ++++- .../AgentGrpcTests.cs | 17 +++++++++++------ 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dotnet/samples/Hello/Hello.AppHost/Program.cs b/dotnet/samples/Hello/Hello.AppHost/Program.cs index 8230a5b7c2d9..31dbeb8c2db7 100644 --- a/dotnet/samples/Hello/Hello.AppHost/Program.cs +++ b/dotnet/samples/Hello/Hello.AppHost/Program.cs @@ -12,7 +12,7 @@ .WaitFor(backend); #pragma warning disable ASPIREHOSTINGPYTHON001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. // xlang is over http for now - in prod use TLS between containers -builder.AddPythonApp("HelloAgentsPython", "../../../../python/packages/autogen-core/samples/xlang/hello_python_agent", "hello_python_agent.py", "../../../../../.venv") +builder.AddPythonApp("HelloAgentsPython", "../../../../python/samples/core_xlang_hello_python_agent", "hello_python_agent.py", "../../.venv") .WithReference(backend) .WithEnvironment("AGENT_HOST", backend.GetEndpoint("http")) .WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true") diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/Properties/launchSettings.json b/dotnet/src/Microsoft.AutoGen/AgentHost/Properties/launchSettings.json index cfddee319d65..796802878eb5 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentHost/Properties/launchSettings.json +++ b/dotnet/src/Microsoft.AutoGen/AgentHost/Properties/launchSettings.json @@ -4,7 +4,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:50670;http://localhost:50673", + "applicationUrl": "https://localhost:53071;http://localhost:50673", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json index ae32fe371a70..1739187e77b2 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json +++ b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json @@ -3,7 +3,10 @@ "LogLevel": { "Default": "Warning", "Microsoft": "Warning", - "Microsoft.Orleans": "Warning" + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore": "Information", + "Microsoft.Orleans": "Warning", + "Orleans.Runtime": "Warning" } }, "AllowedHosts": "*", diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 505a32cdc18d..fd825d93cc65 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -18,7 +18,6 @@ namespace Microsoft.AutoGen.Core.Grpc.Tests; [Collection(GrpcClusterFixtureCollection.Name)] public class AgentGrpcTests(GrpcRuntimeFixture fixture) { - private readonly IServiceProvider _serviceProvider = fixture.AppHost.Services; private readonly GrpcRuntimeFixture _fixture = fixture; // need a variable to store the runtime instance public static WebApplication? Host { get; private set; } @@ -30,7 +29,7 @@ public class AgentGrpcTests(GrpcRuntimeFixture fixture) [Fact] public async Task Agent_ShouldThrowException_WhenNotInitialized() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + var agent = ActivatorUtilities.CreateInstance(_fixture.Client.Services); await Assert.ThrowsAsync( async () => { @@ -130,12 +129,18 @@ public async Task PublishMessageAsync_and_ReceiveMessageTest() } } Assert.True(found); +/* await AgentsApp.PublishMessageAsync("TestEvent", new TextMessage() + { + Source = "TestEvent", + TextMessage_ = "buffer" + }, local: false).ConfigureAwait(true); + */ await agent.PublishMessageAsync(new TextMessage() { Source = "TestEvent", TextMessage_ = "buffer" }).ConfigureAwait(true); - await Task.Delay(100); + await Task.Delay(10000); Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); _fixture.Stop(); } @@ -156,7 +161,7 @@ public async Task InvokeCorrectHandler() [Fact] public async Task DelegateMessageToTestAgentAsync() { - var client = _fixture.AppHost.Services.GetRequiredService(); + var client = _fixture.Client.Services.GetRequiredService(); await client.PublishMessageAsync(new TextMessage() { Source = nameof(DelegateMessageToTestAgentAsync), @@ -234,7 +239,7 @@ private static async Task StartAppHostAsync() } public IHost Client { get; } - public IHost AppHost { get; } + public IHost? AppHost { get; } /// /// Start - starts the agent @@ -253,7 +258,7 @@ private static async Task StartAppHostAsync() /// void public void Stop() { - IHostApplicationLifetime hostApplicationLifetime = AppHost.Services.GetRequiredService(); + IHostApplicationLifetime hostApplicationLifetime = Client.Services.GetRequiredService(); hostApplicationLifetime.StopApplication(); } } From 6215c5d089190613afcd484773175ee745aea002 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 14:58:05 -0800 Subject: [PATCH 039/110] remove failed experiment --- .../Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index fd825d93cc65..f6005d1c8053 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -129,12 +129,7 @@ public async Task PublishMessageAsync_and_ReceiveMessageTest() } } Assert.True(found); -/* await AgentsApp.PublishMessageAsync("TestEvent", new TextMessage() - { - Source = "TestEvent", - TextMessage_ = "buffer" - }, local: false).ConfigureAwait(true); - */ + await agent.PublishMessageAsync(new TextMessage() { Source = "TestEvent", From 709303417865d64b8fb6208c8304bd2d9c727c68 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 15:21:27 -0800 Subject: [PATCH 040/110] back AgentsApp off of ASPNET --- dotnet/src/Microsoft.AutoGen/Core/App.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/App.cs b/dotnet/src/Microsoft.AutoGen/Core/App.cs index f0850e29ed3a..e8d84789f71b 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/App.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Google.Protobuf; -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -13,27 +12,25 @@ namespace Microsoft.AutoGen.Core; public static class AgentsApp { // need a variable to store the runtime instance - public static WebApplication? Host { get; private set; } + public static IHost? Host { get; private set; } [MemberNotNull(nameof(Host))] - public static async ValueTask StartAsync(WebApplicationBuilder? builder = null, AgentTypes? agentTypes = null) + public static async ValueTask StartAsync(HostApplicationBuilder? builder = null, AgentTypes? agentTypes = null) { - builder ??= WebApplication.CreateBuilder(); + builder ??= new HostApplicationBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.AddAgentWorker() .AddAgents(agentTypes); - builder.AddServiceDefaults(); var app = builder.Build(); - app.MapDefaultEndpoints(); Host = app; await app.StartAsync().ConfigureAwait(false); return Host; } - public static async ValueTask PublishMessageAsync( + public static async ValueTask PublishMessageAsync( string topic, IMessage message, - WebApplicationBuilder? builder = null, + HostApplicationBuilder? builder = null, AgentTypes? agents = null, bool local = false) { From 5b297fb4921d3077c8f498a1d923e8d289238a1c Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 15:44:36 -0800 Subject: [PATCH 041/110] back off of aspnet --- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index 5d72bc5eda5e..5a38b0f3c4af 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Google.Protobuf; -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; @@ -13,25 +12,24 @@ namespace Microsoft.AutoGen.Core.Grpc; public static class AgentsApp { // need a variable to store the runtime instance - public static WebApplication? Host { get; private set; } + public static IHost? Host { get; private set; } [MemberNotNull(nameof(Host))] - public static async ValueTask StartAsync(WebApplicationBuilder? builder = null, AgentTypes? agentTypes = null, bool local = false) + public static async ValueTask StartAsync(HostApplicationBuilder? builder = null, AgentTypes? agentTypes = null, bool local = false) { - builder ??= WebApplication.CreateBuilder(); + builder ??= new HostApplicationBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.AddGrpcAgentWorker() .AddAgents(agentTypes); - builder.AddServiceDefaults(); var app = builder.Build(); Host = app; await app.StartAsync().ConfigureAwait(false); return Host; } - public static async ValueTask PublishMessageAsync( + public static async ValueTask PublishMessageAsync( string topic, IMessage message, - WebApplicationBuilder? builder = null, + HostApplicationBuilder? builder = null, AgentTypes? agents = null, bool local = false) { From 0d1e1240064d721b8c4a4dd0680f4051ec3b7b5a Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 19:55:32 -0800 Subject: [PATCH 042/110] fixing HelloAgent so that it works with GRPC as well now --- .../Hello/HelloAgent/HelloAgent.csproj | 1 + dotnet/samples/Hello/HelloAgent/Program.cs | 2 +- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 8 ++- .../Core.Grpc/GrpcAgentWorker.cs | 54 ++++++++++--------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj b/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj index 5067a673df4b..73d3f43dc0e4 100644 --- a/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj +++ b/dotnet/samples/Hello/HelloAgent/HelloAgent.csproj @@ -15,6 +15,7 @@ + diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index 980c34f8617c..70c3fde7a3e7 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -8,7 +8,7 @@ var local = true; if (Environment.GetEnvironmentVariable("AGENT_HOST") != null) { local = false; } -var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var app = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" }, local: local).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index 5a38b0f3c4af..ad4db0f38295 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -19,8 +19,14 @@ public static async ValueTask StartAsync(HostApplicationBuilder? builder { builder ??= new HostApplicationBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); - builder.AddGrpcAgentWorker() + if (! local) + { + builder.AddGrpcAgentWorker() + .AddAgents(agentTypes); + } else { + builder.AddAgentWorker() .AddAgents(agentTypes); + } var app = builder.Build(); Host = app; await app.StartAsync().ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 7292549312fd..7682bc864692 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -24,6 +24,7 @@ public sealed class GrpcAgentWorker( private readonly ConcurrentDictionary _agentTypes = new(); private readonly ConcurrentDictionary<(string Type, string Key), Agent> _agents = new(); private readonly ConcurrentDictionary _pendingRequests = new(); + private readonly ConcurrentDictionary> _agentsForEvent = new(); private readonly Channel<(Message Message, TaskCompletionSource WriteCompletionSource)> _outboundMessagesChannel = Channel.CreateBounded<(Message, TaskCompletionSource)>(new BoundedChannelOptions(1024) { AllowSynchronousContinuations = true, @@ -76,20 +77,19 @@ private async Task RunReadPump() break; case Message.MessageOneofCase.CloudEvent: - - // HACK: Send the message to an instance of each agent type - // where AgentId = (namespace: event.Namespace, name: agentType) - // i.e, assume each agent type implicitly subscribes to each event. - var item = message.CloudEvent; - - foreach (var (typeName, _) in _agentTypes) + if (!_agentsForEvent.TryGetValue(item.Type, out var agents)) { - var agent = GetOrActivateAgent(new AgentId { Type = typeName, Key = item.Source }); + _logger.LogError($"This worker can't handle the event type '{item.Type}'."); + break; + } + foreach (var a in agents) + { + var agent = GetOrActivateAgent(new AgentId { Type = a.Name, Key = item.GetSubject() }); agent.ReceiveMessage(message); } - break; + default: throw new InvalidOperationException($"Unexpected message '{message}'."); } @@ -147,7 +147,7 @@ private async Task RunWritePump() { // we could not connect to the endpoint - most likely we have the wrong port or failed ssl // we need to let the user know what port we tried to connect to and then do backoff and retry - _logger.LogError(ex, "Error connecting to GRPC endpoint {Endpoint}.", channel.ToString()); + _logger.LogError(ex, "Error connecting to GRPC endpoint {Endpoint}. Check port and SSL settings.", channel.ToString()); break; } catch (Exception ex) when (!_shutdownCts.IsCancellationRequested) @@ -177,6 +177,7 @@ private Agent GetOrActivateAgent(AgentId agentId) if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); + Agent.Initialize(this, agent); _agents.TryAdd((agentId.Type, agentId.Key), agent); } else @@ -195,21 +196,24 @@ private async ValueTask RegisterAgentTypeAsync(string type, Type agentType, Canc var events = agentType.GetInterfaces() .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandle<>)) .Select(i => ReflectionHelper.GetMessageDescriptor(i.GetGenericArguments().First())?.FullName); - //var state = agentType.BaseType?.GetGenericArguments().First(); - var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic); - - //TODO: do something with the response (like retry on error) - await WriteChannelAsync(new Message + // add the agentType to the list of agent types that handle the event + foreach (var evt in events) { - RegisterAgentTypeRequest = new RegisterAgentTypeRequest + if (!_agentsForEvent.TryGetValue(evt!, out var agents)) { - Type = type, - RequestId = Guid.NewGuid().ToString(), - //TopicTypes = { topicTypes }, - //StateType = state?.Name, - //Events = { events } + agents = new HashSet(); + _agentsForEvent[evt!] = agents; } - }, cancellationToken).ConfigureAwait(false); + + agents.Add(agentType); + } + var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic); + var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest + { + Type = type, + Topics = { topicTypes }, + Events = { events } + }, null, null, cancellationToken); foreach (var topic in topicTypes) { @@ -228,7 +232,8 @@ await WriteChannelAsync(new Message } } }; - await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); + await _client.SubscribeAsync(subscriptionRequest.SubscriptionRequest, null, null, cancellationToken); + //await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); foreach (var e in events) { subscriptionRequest = new Message @@ -246,7 +251,8 @@ await WriteChannelAsync(new Message } } }; - await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); + await _client.SubscribeAsync(subscriptionRequest.SubscriptionRequest, null, null, cancellationToken); + //await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); } } } From 3fdd78e098607692b8a915c27479b58bd1a53138 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 17 Jan 2025 22:55:30 -0800 Subject: [PATCH 043/110] cleanup trying to get grpc to work --- .../Core.Grpc/GrpcAgentWorker.cs | 21 ++++++++++++++++--- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 16 +++----------- .../GrpcGatewayServiceTests.cs | 4 ++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 7682bc864692..d9d1e681fd07 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -150,10 +150,15 @@ private async Task RunWritePump() _logger.LogError(ex, "Error connecting to GRPC endpoint {Endpoint}. Check port and SSL settings.", channel.ToString()); break; } + catch (RpcException ex) when (ex.StatusCode == StatusCode.OK) + { + _logger.LogError(ex, "Error writing to channel, continuing (Status OK). {ex}", channel.ToString()); + break; + } catch (Exception ex) when (!_shutdownCts.IsCancellationRequested) { item.WriteCompletionSource?.TrySetException(ex); - _logger.LogError(ex, "Error writing to channel."); + _logger.LogError(ex, $"Error writing to channel.{ex}"); channel = RecreateChannel(channel); continue; } @@ -208,12 +213,22 @@ private async ValueTask RegisterAgentTypeAsync(string type, Type agentType, Canc agents.Add(agentType); } var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic); - var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest +/* var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest { Type = type, Topics = { topicTypes }, Events = { events } - }, null, null, cancellationToken); + }, null, null, cancellationToken); */ + await WriteChannelAsync(new Message + { + RegisterAgentTypeRequest = new RegisterAgentTypeRequest + { + RequestId = Guid.NewGuid().ToString(), + Type = type, + Topics = { topicTypes }, + Events = { events } + } + }, cancellationToken).ConfigureAwait(false); foreach (var topic in topicTypes) { diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index cc66529083d9..57df08bf327b 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -30,7 +30,6 @@ public sealed class GrpcGateway : BackgroundService, IGateway private readonly ConcurrentDictionary<(string Type, string Key), GrpcWorkerConnection> _agentDirectory = new(); // RPC private readonly ConcurrentDictionary<(GrpcWorkerConnection, string), TaskCompletionSource> _pendingRequests = new(); - public int WorkersCount => _workers.Count; public GrpcGateway(IClusterClient clusterClient, ILogger logger) { _logger = logger; @@ -146,22 +145,13 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) _logger.LogWarning(exception, "Error removing worker from registry."); } } - internal async Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + internal Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) { _logger.LogInformation("Received new connection from {Peer}.", context.Peer); var workerProcess = new GrpcWorkerConnection(this, requestStream, responseStream, context); - var connectionId = Guid.NewGuid().ToString(); _workers[workerProcess] = workerProcess; - _workersByConnection[connectionId] = workerProcess; - - var completion = new TaskCompletionSource(); - var _ = Task.Run(() => - { - completion.SetResult(workerProcess.Connect()); - }); - - await completion.Task; - return connectionId; + _workersByConnection[context.Peer] = workerProcess; + return workerProcess.Completion; } internal async Task SendMessageAsync(GrpcWorkerConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 12035da98144..5be9404adc66 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -30,9 +30,9 @@ public async Task Test_OpenChannel() var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - gateway.WorkersCount.Should().Be(0); + gateway._workers.Count.Should().Be(0); await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - gateway.WorkersCount.Should().Be(1); + gateway._workers.Count.Should().Be(1); } [Fact] From 9cf866ae9715d085ce3d6c4a4552de40e3ad537e Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 18 Jan 2025 11:09:31 -0800 Subject: [PATCH 044/110] host changes broke this --- dotnet/samples/Hello/HelloAIAgents/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Hello/HelloAIAgents/Program.cs b/dotnet/samples/Hello/HelloAIAgents/Program.cs index a5bf4b68ee46..035da0353f85 100644 --- a/dotnet/samples/Hello/HelloAIAgents/Program.cs +++ b/dotnet/samples/Hello/HelloAIAgents/Program.cs @@ -7,7 +7,7 @@ using Microsoft.AutoGen.Core; // send a message to the agent -var builder = WebApplication.CreateBuilder(); +var builder = new HostApplicationBuilder(); // put these in your environment or appsettings.json builder.Configuration["HelloAIAgents:ModelType"] = "azureopenai"; builder.Configuration["HelloAIAgents:LlmModelName"] = "gpt-3.5-turbo"; From fef95b74174a6f867f79194dfa9b4b2466672d45 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 18 Jan 2025 11:44:45 -0800 Subject: [PATCH 045/110] error handling for registeragenttyperesponse --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index d9d1e681fd07..05db2e1e3700 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -75,7 +75,11 @@ private async Task RunReadPump() message.Response.RequestId = request.OriginalRequestId; request.Agent.ReceiveMessage(message); break; - + case Message.MessageOneofCase.RegisterAgentTypeResponse: + if (!message.RegisterAgentTypeResponse.Success){ + _logger.LogError($"Failed to register agent type '{message.RegisterAgentTypeResponse.Error}'"); + } + break; case Message.MessageOneofCase.CloudEvent: var item = message.CloudEvent; if (!_agentsForEvent.TryGetValue(item.Type, out var agents)) From 6053f92136ec7ac2ae027f550b877153668e1647 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sat, 18 Jan 2025 11:48:15 -0800 Subject: [PATCH 046/110] error handling for subscriptionresponse --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 05db2e1e3700..398c98febc84 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -80,6 +80,11 @@ private async Task RunReadPump() _logger.LogError($"Failed to register agent type '{message.RegisterAgentTypeResponse.Error}'"); } break; + case Message.MessageOneofCase.SubscriptionResponse: + if (!message.SubscriptionResponse.Success){ + _logger.LogError($"Failed to add subscription '{message.SubscriptionResponse.Error}'"); + } + break; case Message.MessageOneofCase.CloudEvent: var item = message.CloudEvent; if (!_agentsForEvent.TryGetValue(item.Type, out var agents)) From 6824bb32d97a7b90ac3c4cac99805ceb60c6c7c5 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:18:59 -0800 Subject: [PATCH 047/110] updating publish message with topics --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index c70f50446919..310fac7f78f0 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -293,16 +293,23 @@ static async (state, ct) => /// Publishes a message asynchronously. /// /// The type of the message. - /// The message to publish. - /// The source of the message. /// A token to cancel the operation. /// A task representing the asynchronous operation. - public async ValueTask PublishMessageAsync(T @event, string? topic = null, string? key = null, CancellationToken token = default) where T : IMessage + public async ValueTask PublishMessageAsync(T message, string? source = null, CancellationToken token = default) where T : IMessage { - var k = string.IsNullOrWhiteSpace(key) ? AgentId.Key : key; - var topicType = string.IsNullOrWhiteSpace(topic) ? "default" : topic; - var evt = @event.ToCloudEvent(k, topicType); - await PublishEventAsync(evt, token).ConfigureAwait(false); + var topicTypes = this.GetType().GetCustomAttributes().Select(t => t.Topic); + if (!topicTypes.Any()) + { + topicTypes = topicTypes.Append(string.IsNullOrWhiteSpace(source) ? this.AgentId.Type + "." + this.AgentId.Key : source); + } + foreach (var topic in topicTypes) + { + await PublishMessageAsync(topic, message, source, token).ConfigureAwait(false); + } + } + public async ValueTask PublishMessageAsync(string topic, T message, string? source = null, CancellationToken token = default) where T : IMessage + { + await PublishEventAsync(topic, message, token).ConfigureAwait(false); } public async ValueTask PublishEventAsync(CloudEvent item, CancellationToken cancellationToken = default) { From 0abb6a391140addce74c3990cdf448509d6bd051 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:21:27 -0800 Subject: [PATCH 048/110] Orleans runtime logs to error only --- dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json index 1739187e77b2..484ba49169df 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json +++ b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json @@ -6,7 +6,7 @@ "Microsoft.Hosting.Lifetime": "Information", "Microsoft.AspNetCore": "Information", "Microsoft.Orleans": "Warning", - "Orleans.Runtime": "Warning" + "Orleans.Runtime": "Error" } }, "AllowedHosts": "*", From 3aa7838ea5fa279a594a765bc834e127d0b7dc05 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:23:04 -0800 Subject: [PATCH 049/110] add log message on new connection --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 398c98febc84..aed6b78de10e 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -347,6 +347,8 @@ private AsyncDuplexStreamingCall RecreateChannel(AsyncDuplexSt public async Task StartAsync(CancellationToken cancellationToken) { _channel = GetChannel(); + _logger.LogInformation("Starting GrpcAgentWorker, connecting to gRPC endpoint "+ _client.ToString()); + StartCore(); var tasks = new List(_agentTypes.Count); From 00d9caf44d7a9dd1a9b26fb4defc80c235be9f54 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:23:48 -0800 Subject: [PATCH 050/110] improve log message --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index aed6b78de10e..486e6ec22a94 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -347,7 +347,7 @@ private AsyncDuplexStreamingCall RecreateChannel(AsyncDuplexSt public async Task StartAsync(CancellationToken cancellationToken) { _channel = GetChannel(); - _logger.LogInformation("Starting GrpcAgentWorker, connecting to gRPC endpoint "+ _client.ToString()); + _logger.LogInformation("Starting GrpcAgentWorker, connecting to gRPC endpoint "+ Environment.GetEnvironmentVariable("AGENT_HOST")); StartCore(); From 518ad1535f4a8f4405973495b9821dcaf85157c5 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:24:58 -0800 Subject: [PATCH 051/110] improve log message --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 486e6ec22a94..ff075f3a20f0 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -156,7 +156,7 @@ private async Task RunWritePump() { // we could not connect to the endpoint - most likely we have the wrong port or failed ssl // we need to let the user know what port we tried to connect to and then do backoff and retry - _logger.LogError(ex, "Error connecting to GRPC endpoint {Endpoint}. Check port and SSL settings.", channel.ToString()); + _logger.LogError(ex, "Error connecting to GRPC endpoint {Endpoint}.", Environment.GetEnvironmentVariable("AGENT_HOST")); break; } catch (RpcException ex) when (ex.StatusCode == StatusCode.OK) From b6915acc10e92e2594d1899d6519d52aed971458 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:29:04 -0800 Subject: [PATCH 052/110] consistent updates to Hello Samples --- .../samples/Hello/HelloAIAgents/HelloAIAgents.csproj | 1 + dotnet/samples/Hello/HelloAIAgents/Program.cs | 10 +++++----- dotnet/samples/Hello/HelloAgent/Program.cs | 2 +- .../Hello/HelloAgentState/HelloAgentState.csproj | 1 + dotnet/samples/Hello/HelloAgentState/Program.cs | 8 +++++--- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/dotnet/samples/Hello/HelloAIAgents/HelloAIAgents.csproj b/dotnet/samples/Hello/HelloAIAgents/HelloAIAgents.csproj index f557ce91a0e3..722ef1d97635 100644 --- a/dotnet/samples/Hello/HelloAIAgents/HelloAIAgents.csproj +++ b/dotnet/samples/Hello/HelloAIAgents/HelloAIAgents.csproj @@ -11,6 +11,7 @@ + diff --git a/dotnet/samples/Hello/HelloAIAgents/Program.cs b/dotnet/samples/Hello/HelloAIAgents/Program.cs index 035da0353f85..2c35049e7099 100644 --- a/dotnet/samples/Hello/HelloAIAgents/Program.cs +++ b/dotnet/samples/Hello/HelloAIAgents/Program.cs @@ -22,16 +22,16 @@ { { "HelloAIAgents", typeof(HelloAIAgent) } }); -var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var local = true; +if (Environment.GetEnvironmentVariable("AGENT_HOST") != null) { local = false; } +var app = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" -}, builder, agentTypes, local: true); - -await app.WaitForShutdownAsync(); +}, local: local).ConfigureAwait(false); namespace Hello { - [TopicSubscription("agents")] + [TopicSubscription("HelloAgents")] public class HelloAgent( [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry, IHostApplicationLifetime hostApplicationLifetime) : ConsoleAgent( diff --git a/dotnet/samples/Hello/HelloAgent/Program.cs b/dotnet/samples/Hello/HelloAgent/Program.cs index 70c3fde7a3e7..dde48423d765 100644 --- a/dotnet/samples/Hello/HelloAgent/Program.cs +++ b/dotnet/samples/Hello/HelloAgent/Program.cs @@ -16,7 +16,7 @@ namespace Hello { - [TopicSubscription("agents")] + [TopicSubscription("HelloAgents")] public class HelloAgent( IHostApplicationLifetime hostApplicationLifetime, [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : Agent( diff --git a/dotnet/samples/Hello/HelloAgentState/HelloAgentState.csproj b/dotnet/samples/Hello/HelloAgentState/HelloAgentState.csproj index 5dc534a4e435..343ea8eb8573 100644 --- a/dotnet/samples/Hello/HelloAgentState/HelloAgentState.csproj +++ b/dotnet/samples/Hello/HelloAgentState/HelloAgentState.csproj @@ -12,6 +12,7 @@ + diff --git a/dotnet/samples/Hello/HelloAgentState/Program.cs b/dotnet/samples/Hello/HelloAgentState/Program.cs index 013d70786551..f81ecdad977b 100644 --- a/dotnet/samples/Hello/HelloAgentState/Program.cs +++ b/dotnet/samples/Hello/HelloAgentState/Program.cs @@ -7,16 +7,18 @@ using Microsoft.AutoGen.Core; // send a message to the agent -var app = await AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var local = true; +if (Environment.GetEnvironmentVariable("AGENT_HOST") != null) { local = false; } +var app = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" -}, local: false); +}, local: local).ConfigureAwait(false); await app.WaitForShutdownAsync(); namespace Hello { - [TopicSubscription("agents")] + [TopicSubscription("HelloAgents")] public class HelloAgent( IHostApplicationLifetime hostApplicationLifetime, [FromKeyedServices("AgentsMetadata")] AgentsMetadata typeRegistry) : Agent( From 281bff286462f40f68483314f883a5e163a970fa Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Sun, 19 Jan 2025 15:31:25 -0800 Subject: [PATCH 053/110] setup dotnet 8 version --- .github/workflows/dotnet-build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index f9683527f38e..a8f7eae1bf71 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -132,6 +132,10 @@ jobs: - name: Prepare python venv run: | source ${{ github.workspace }}/python/.venv/bin/activate + - name: Setup .NET 8.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' - name: Setup .NET 9.0 uses: actions/setup-dotnet@v4 with: From 5f133a88556063c56b9398b819de7c31ae8d46b5 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 10:37:36 -0800 Subject: [PATCH 054/110] interim commit - expanding the range of publishmessage available --- dotnet/samples/Hello/HelloAIAgents/Program.cs | 4 +- .../IOAgent/ConsoleAgent/IHandleConsole.cs | 2 +- dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs | 6 ++- .../Core.Grpc/GrpcAgentWorker.cs | 20 +++++---- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 45 +++++++++++++++---- .../Services/AgentWorkerHostingExtensions.cs | 2 +- .../AgentGrpcTests.cs | 2 +- 7 files changed, 56 insertions(+), 25 deletions(-) diff --git a/dotnet/samples/Hello/HelloAIAgents/Program.cs b/dotnet/samples/Hello/HelloAIAgents/Program.cs index 2c35049e7099..f49f5fcfb3e3 100644 --- a/dotnet/samples/Hello/HelloAIAgents/Program.cs +++ b/dotnet/samples/Hello/HelloAIAgents/Program.cs @@ -18,13 +18,13 @@ } builder.Configuration["ConectionStrings:HelloAIAgents"] = Environment.GetEnvironmentVariable("AZURE_OPENAI_CONNECTION_STRING"); builder.AddChatCompletionService("HelloAIAgents"); -var agentTypes = new AgentTypes(new Dictionary +var _ = new AgentTypes(new Dictionary { { "HelloAIAgents", typeof(HelloAIAgent) } }); var local = true; if (Environment.GetEnvironmentVariable("AGENT_HOST") != null) { local = false; } -var app = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var _ = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" }, local: local).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs index cd0fa71eca0d..f73a9a6c71ee 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs @@ -10,7 +10,7 @@ namespace Microsoft.AutoGen.Agents; public interface IHandleConsole : IHandle, IHandle { AgentId AgentId { get; } - ValueTask PublishMessageAsync(T message, string? source = null, string? key = null, CancellationToken token = default) where T : IMessage; + ValueTask PublishMessageAsync(T message, string? topic = null, string? source = null, string? key = null, CancellationToken token = default) where T : IMessage; async Task IHandle.Handle(Output item, CancellationToken cancellationToken) { diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs index ad4db0f38295..f5c0dabe8227 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/App.cs @@ -19,11 +19,13 @@ public static async ValueTask StartAsync(HostApplicationBuilder? builder { builder ??= new HostApplicationBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); - if (! local) + if (!local) { builder.AddGrpcAgentWorker() .AddAgents(agentTypes); - } else { + } + else + { builder.AddAgentWorker() .AddAgents(agentTypes); } diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index ff075f3a20f0..d4b6b2ed4ac5 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -76,12 +76,14 @@ private async Task RunReadPump() request.Agent.ReceiveMessage(message); break; case Message.MessageOneofCase.RegisterAgentTypeResponse: - if (!message.RegisterAgentTypeResponse.Success){ + if (!message.RegisterAgentTypeResponse.Success) + { _logger.LogError($"Failed to register agent type '{message.RegisterAgentTypeResponse.Error}'"); } break; case Message.MessageOneofCase.SubscriptionResponse: - if (!message.SubscriptionResponse.Success){ + if (!message.SubscriptionResponse.Success) + { _logger.LogError($"Failed to add subscription '{message.SubscriptionResponse.Error}'"); } break; @@ -222,12 +224,12 @@ private async ValueTask RegisterAgentTypeAsync(string type, Type agentType, Canc agents.Add(agentType); } var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic); -/* var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest - { - Type = type, - Topics = { topicTypes }, - Events = { events } - }, null, null, cancellationToken); */ + /* var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest + { + Type = type, + Topics = { topicTypes }, + Events = { events } + }, null, null, cancellationToken); */ await WriteChannelAsync(new Message { RegisterAgentTypeRequest = new RegisterAgentTypeRequest @@ -347,7 +349,7 @@ private AsyncDuplexStreamingCall RecreateChannel(AsyncDuplexSt public async Task StartAsync(CancellationToken cancellationToken) { _channel = GetChannel(); - _logger.LogInformation("Starting GrpcAgentWorker, connecting to gRPC endpoint "+ Environment.GetEnvironmentVariable("AGENT_HOST")); + _logger.LogInformation("Starting GrpcAgentWorker, connecting to gRPC endpoint " + Environment.GetEnvironmentVariable("AGENT_HOST")); StartCore(); diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 310fac7f78f0..957ee5828bec 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -289,27 +289,58 @@ static async (state, ct) => // Return the result from the already-completed task return await completion.Task.ConfigureAwait(false); } + + private string SetTopic(string? topic = null , string? source = null, string? key = null) + { + if (string.IsNullOrWhiteSpace(topic)) + { + topic = this.AgentId.Type + "." + this.AgentId.Key; + } + topic = topic + "." + source + "." + key; + return topic; + } + /// /// Publishes a message asynchronously. /// /// The type of the message. /// A token to cancel the operation. /// A task representing the asynchronous operation. - public async ValueTask PublishMessageAsync(T message, string? source = null, CancellationToken token = default) where T : IMessage + public async ValueTask PublishMessageAsync(T message, string topic, string source, string key, CancellationToken token = default) where T : IMessage { + var topicTypes = this.GetType().GetCustomAttributes().Select(t => t.Topic); if (!topicTypes.Any()) { topicTypes = topicTypes.Append(string.IsNullOrWhiteSpace(source) ? this.AgentId.Type + "." + this.AgentId.Key : source); } - foreach (var topic in topicTypes) + topicTypes = topicTypes.Append(SetTopic(topic, source, key)); + foreach (var t in topicTypes) { - await PublishMessageAsync(topic, message, source, token).ConfigureAwait(false); + await PublishEventAsync(t, message, token).ConfigureAwait(false); } } - public async ValueTask PublishMessageAsync(string topic, T message, string? source = null, CancellationToken token = default) where T : IMessage + public async ValueTask PublishMessageAsync(T message, string topic, string source, CancellationToken token = default) where T : IMessage + { + string key = this.AgentId.Key; + await PublishMessageAsync(message, topic, source, key, token).ConfigureAwait(false); + } + public async ValueTask PublishMessageAsync(T message, string topic, CancellationToken token = default) where T : IMessage + { + string source = this.AgentId.Type; + string key = this.AgentId.Key; + await PublishMessageAsync(message, topic, source, key, token).ConfigureAwait(false); + } + public async ValueTask PublishMessageAsync(T message, CancellationToken token = default) where T : IMessage { - await PublishEventAsync(topic, message, token).ConfigureAwait(false); + string topic = ""; + string source = this.AgentId.Type; + string key = this.AgentId.Key; + await PublishMessageAsync(message, topic, source, key, token).ConfigureAwait(false); + } + public async ValueTask PublishEventAsync(string topic, IMessage message, CancellationToken cancellationToken = default) + { + await PublishEventAsync(message.ToCloudEvent(key: GetType().Name, topic: topic), cancellationToken).ConfigureAwait(false); } public async ValueTask PublishEventAsync(CloudEvent item, CancellationToken cancellationToken = default) { @@ -391,8 +422,4 @@ public virtual async Task HandleObjectAsync(object item, CancellationToken cance // otherwise, complain _logger.LogError($"No handler found for type {item.GetType().FullName}"); } - public async ValueTask PublishEventAsync(string topic, IMessage evt, CancellationToken cancellationToken = default) - { - await PublishEventAsync(evt.ToCloudEvent(key: GetType().Name, topic: topic), cancellationToken).ConfigureAwait(false); - } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs index 4c1ec149ab8a..3b130ca4bed5 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/AgentWorkerHostingExtensions.cs @@ -3,10 +3,10 @@ using System.Diagnostics; using Microsoft.AspNetCore.Builder; +using Microsoft.AutoGen.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; -using Microsoft.AutoGen.Core; namespace Microsoft.AutoGen.Runtime.Grpc; public static class AgentWorkerHostingExtensions diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index f6005d1c8053..6fd2d495d7a8 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -129,7 +129,7 @@ public async Task PublishMessageAsync_and_ReceiveMessageTest() } } Assert.True(found); - + await agent.PublishMessageAsync(new TextMessage() { Source = "TestEvent", From 05e141a4b4c7b05fa29c06c5a88dc0d8fa552920 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 10:42:51 -0800 Subject: [PATCH 055/110] fix interface in Ihandleconsole and cleanup in HelloAIAgent --- dotnet/samples/Hello/HelloAIAgents/Program.cs | 3 ++- .../Agents/IOAgent/ConsoleAgent/IHandleConsole.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dotnet/samples/Hello/HelloAIAgents/Program.cs b/dotnet/samples/Hello/HelloAIAgents/Program.cs index f49f5fcfb3e3..541539fb6786 100644 --- a/dotnet/samples/Hello/HelloAIAgents/Program.cs +++ b/dotnet/samples/Hello/HelloAIAgents/Program.cs @@ -24,10 +24,11 @@ }); var local = true; if (Environment.GetEnvironmentVariable("AGENT_HOST") != null) { local = false; } -var _ = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived +var app = await Microsoft.AutoGen.Core.Grpc.AgentsApp.PublishMessageAsync("HelloAgents", new NewMessageReceived { Message = "World" }, local: local).ConfigureAwait(false); +await app.WaitForShutdownAsync(); namespace Hello { diff --git a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs index f73a9a6c71ee..21ec69d42080 100644 --- a/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs +++ b/dotnet/src/Microsoft.AutoGen/Agents/IOAgent/ConsoleAgent/IHandleConsole.cs @@ -10,7 +10,7 @@ namespace Microsoft.AutoGen.Agents; public interface IHandleConsole : IHandle, IHandle { AgentId AgentId { get; } - ValueTask PublishMessageAsync(T message, string? topic = null, string? source = null, string? key = null, CancellationToken token = default) where T : IMessage; + ValueTask PublishMessageAsync(T message, CancellationToken token = default) where T : IMessage; async Task IHandle.Handle(Output item, CancellationToken cancellationToken) { From 8bdffec0988ae6f5b36c5989ba0f7b773a44610b Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 10:54:32 -0800 Subject: [PATCH 056/110] format --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 957ee5828bec..e5e0292556a5 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -290,7 +290,7 @@ static async (state, ct) => return await completion.Task.ConfigureAwait(false); } - private string SetTopic(string? topic = null , string? source = null, string? key = null) + private string SetTopic(string? topic = null, string? source = null, string? key = null) { if (string.IsNullOrWhiteSpace(topic)) { @@ -308,7 +308,7 @@ private string SetTopic(string? topic = null , string? source = null, string? ke /// A task representing the asynchronous operation. public async ValueTask PublishMessageAsync(T message, string topic, string source, string key, CancellationToken token = default) where T : IMessage { - + var topicTypes = this.GetType().GetCustomAttributes().Select(t => t.Topic); if (!topicTypes.Any()) { From 5180dee93a039ab960f613f4c9395da9c8121ea1 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 11:06:48 -0800 Subject: [PATCH 057/110] rename files --- ...PrefixSubscription.cs => TypePrefixSubscriptionSurrogate.cs} | 2 +- .../{TypeSubscription.cs => TypeSubscriptionSurrogate.cs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{TypePrefixSubscription.cs => TypePrefixSubscriptionSurrogate.cs} (96%) rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{TypeSubscription.cs => TypeSubscriptionSurrogate.cs} (96%) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscriptionSurrogate.cs similarity index 96% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscriptionSurrogate.cs index c5427d7bf972..ca4d721315e8 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscription.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypePrefixSubscriptionSurrogate.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// TypePrefixSubscription.cs +// TypePrefixSubscriptionSurrogate.cs using Microsoft.AutoGen.Contracts; diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscriptionSurrogate.cs similarity index 96% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscriptionSurrogate.cs index df38462d044a..57fa202ebfc3 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscription.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/TypeSubscriptionSurrogate.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// TypeSubscription.cs +// TypeSubscriptionSurrogate.cs using Microsoft.AutoGen.Contracts; From e26cd1d54b620d21acffe8a2641f942b875b31d3 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 11:17:26 -0800 Subject: [PATCH 058/110] add surrogate for Subscription type --- .../Surrogates/SubscriptionSurrogate.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs new file mode 100644 index 000000000000..abf18143929d --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SubscriptionSurrogate.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct SubscriptionSurrogate +{ + [Id(0)] + public TypeSubscription? TypeSubscription; + [Id(1)] + public TypePrefixSubscription? TypePrefixSubscription; +} + +[RegisterConverter] +public sealed class SubscriptionSurrogateConverter : + IConverter +{ + public Subscription ConvertFromSurrogate( + in SubscriptionSurrogate surrogate) + { + if (surrogate.TypeSubscription is not null) + { + return new Subscription + { + TypeSubscription = surrogate.TypeSubscription + }; + } + else + { + return new Subscription + { + TypePrefixSubscription = surrogate.TypePrefixSubscription + }; + } + } + + public SubscriptionSurrogate ConvertToSurrogate( + in Subscription value) + { + return new SubscriptionSurrogate + { + TypeSubscription = value.TypeSubscription, + TypePrefixSubscription = value.TypePrefixSubscription + }; + } +} From 9c7d2bd8b9d473ce52bb34d1f71de35f14d5eaf6 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 19:41:54 -0800 Subject: [PATCH 059/110] Update dotnet/samples/Hello/HelloAgentState/Program.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- dotnet/samples/Hello/HelloAgentState/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Hello/HelloAgentState/Program.cs b/dotnet/samples/Hello/HelloAgentState/Program.cs index f81ecdad977b..87d39f0461c8 100644 --- a/dotnet/samples/Hello/HelloAgentState/Program.cs +++ b/dotnet/samples/Hello/HelloAgentState/Program.cs @@ -29,7 +29,7 @@ public class HelloAgent( IHandle { private AgentState? State { get; set; } - public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) + var response = await SayHello(item.Message, cancellationToken).ConfigureAwait(false); { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output From d411001a6ea2e30ea9a6e001d790383efe546ec3 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Mon, 20 Jan 2025 19:45:35 -0800 Subject: [PATCH 060/110] revert dumb copilot change --- dotnet/samples/Hello/HelloAgentState/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Hello/HelloAgentState/Program.cs b/dotnet/samples/Hello/HelloAgentState/Program.cs index 87d39f0461c8..f81ecdad977b 100644 --- a/dotnet/samples/Hello/HelloAgentState/Program.cs +++ b/dotnet/samples/Hello/HelloAgentState/Program.cs @@ -29,7 +29,7 @@ public class HelloAgent( IHandle { private AgentState? State { get; set; } - var response = await SayHello(item.Message, cancellationToken).ConfigureAwait(false); + public async Task Handle(NewMessageReceived item, CancellationToken cancellationToken = default) { var response = await SayHello(item.Message).ConfigureAwait(false); var evt = new Output From 76678e87b36dc8c83e154905f43c049e4487165e Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 06:58:19 -0800 Subject: [PATCH 061/110] remove unnecessary inserted using --- .../Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index fdca333c5534..722b38a3fb21 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -2,7 +2,6 @@ // GrpcAgentWorkerHostBuilderExtension.cs using System.Diagnostics; using System.Reflection; -using Google.Protobuf; using Google.Protobuf.Reflection; using Grpc.Core; using Grpc.Net.Client.Configuration; From cafb7999364ced9a13928056b9ed1c73bae31834 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 06:59:13 -0800 Subject: [PATCH 062/110] use primary constructor --- .../Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index 18ca0b407a9a..5c33e90e164e 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -7,13 +7,10 @@ namespace Microsoft.AutoGen.Runtime.Grpc; // gRPC service which handles communication between the agent worker and the cluster. -public sealed class GrpcGatewayService : AgentRpc.AgentRpcBase +public sealed class GrpcGatewayService(GrpcGateway gateway) : AgentRpc.AgentRpcBase { - private readonly GrpcGateway Gateway; - public GrpcGatewayService(GrpcGateway gateway) - { - Gateway = (GrpcGateway)gateway; - } + private readonly GrpcGateway Gateway = (GrpcGateway)gateway; + public override async Task OpenChannel(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) { try From ccfd0cc4f55a4123bf05cea10b52cb5c99e84b6d Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 07:21:38 -0800 Subject: [PATCH 063/110] turning up the logging --- dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json | 3 ++- .../test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json index f07608ca0aa0..1b15783f8fdd 100644 --- a/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json +++ b/dotnet/src/Microsoft.AutoGen/AgentHost/appsettings.json @@ -6,7 +6,8 @@ "Microsoft.AspNetCore": "Information", "Microsoft": "Information", "Microsoft.Orleans": "Warning", - "Orleans.Runtime": "Error" + "Orleans.Runtime": "Error", + "Grpc": "Information" } }, "AllowedHosts": "*", diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json index ae32fe371a70..3a7561374661 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/appsettings.json @@ -3,7 +3,9 @@ "LogLevel": { "Default": "Warning", "Microsoft": "Warning", - "Microsoft.Orleans": "Warning" + "Microsoft.Orleans": "Warning", + "Orleans.Runtime": "Debug", + "Grpc": "Information" } }, "AllowedHosts": "*", From 740047fb0f079cb3e64a44e7a23b4d5131578250 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 08:41:57 -0800 Subject: [PATCH 064/110] add client logging --- .../GrpcAgentWorkerHostBuilderExtension.cs | 3 +- python/uv.lock | 2325 +---------------- 2 files changed, 99 insertions(+), 2229 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index 722b38a3fb21..e91f7ee28752 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; namespace Microsoft.AutoGen.Core.Grpc; public static class GrpcAgentWorkerHostBuilderExtensions @@ -21,7 +22,7 @@ public static IHostApplicationBuilder AddGrpcAgentWorker(this IHostApplicationBu options.Address = new Uri(agentServiceAddress ?? builder.Configuration["AGENT_HOST"] ?? _defaultAgentServiceAddress); options.ChannelOptionsActions.Add(channelOptions => { - + LoggerFactory loggerFactory = new LoggerFactory(); channelOptions.HttpHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true, diff --git a/python/uv.lock b/python/uv.lock index e8a07804e93d..84bfac995e61 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -1,18 +1,42 @@ version = 1 requires-python = ">=3.10, <3.13" resolution-markers = [ - "python_full_version >= '3.12.4' and sys_platform == 'darwin'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and sys_platform == 'darwin'", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12.4' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.12.4' and platform_system == 'Darwin' and sys_platform == 'darwin'", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", + "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version >= '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system == 'Darwin' and sys_platform == 'darwin'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", + "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", + "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12.4' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", + "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", + "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", + "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and platform_system == 'Darwin' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version == '3.11.*' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version == '3.11.*' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version == '3.11.*' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11' and platform_system == 'Darwin' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", + "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version < '3.11' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version < '3.11' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", ] [manifest] @@ -34,29 +58,6 @@ overrides = [ { name = "tenacity", specifier = ">=9.0.0" }, ] -[manifest.dependency-groups] -dev = [ - { name = "chainlit" }, - { name = "cookiecutter" }, - { name = "grpcio-tools", specifier = "~=1.62.0" }, - { name = "mypy", specifier = "==1.13.0" }, - { name = "mypy-protobuf" }, - { name = "packaging" }, - { name = "poethepoet" }, - { name = "polars" }, - { name = "pyright", specifier = "==1.1.389" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "pytest-cov" }, - { name = "pytest-mock" }, - { name = "pytest-xdist" }, - { name = "rich" }, - { name = "ruff", specifier = "==0.4.8" }, - { name = "tomli" }, - { name = "tomli-w" }, - { name = "typer" }, -] - [[package]] name = "accelerate" version = "1.3.0" @@ -75,18 +76,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/de/64508cb91af013aaba214752309c0967568a4219d50a4ea30e822af3c976/accelerate-1.3.0-py3-none-any.whl", hash = "sha256:5788d9e6a7a9f80fed665cf09681c4dddd9dc056bea656db4140ffc285ce423e", size = 336647 }, ] -[[package]] -name = "accessible-pygments" -version = "0.0.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903 }, -] - [[package]] name = "agbench" version = "0.0.1a1" @@ -101,12 +90,6 @@ dependencies = [ { name = "tabulate" }, ] -[package.dev-dependencies] -dev = [ - { name = "types-docker" }, - { name = "types-tabulate" }, -] - [package.metadata] requires-dist = [ { name = "azure-identity" }, @@ -118,12 +101,6 @@ requires-dist = [ { name = "tabulate" }, ] -[package.metadata.requires-dev] -dev = [ - { name = "types-docker" }, - { name = "types-tabulate" }, -] - [[package]] name = "aiofiles" version = "24.1.0" @@ -149,7 +126,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, - { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, @@ -205,19 +182,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/23/cc36d9c398980acaeeb443100f0216f50a7cfe20c67a9fd0a2f1a5a846de/aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", size = 437666 }, ] -[[package]] -name = "aiohttp-jinja2" -version = "1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "jinja2" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e6/39/da5a94dd89b1af7241fb7fc99ae4e73505b5f898b540b6aba6dc7afe600e/aiohttp-jinja2-1.6.tar.gz", hash = "sha256:a3a7ff5264e5bca52e8ae547bbfd0761b72495230d438d05b6c0915be619b0e2", size = 53057 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/90/65238d4246307195411b87a07d03539049819b022c01bcc773826f600138/aiohttp_jinja2-1.6-py3-none-any.whl", hash = "sha256:0df405ee6ad1b58e5a068a105407dc7dcc1704544c559f1938babde954f945c7", size = 11736 }, -] - [[package]] name = "aiolimiter" version = "1.2.1" @@ -239,15 +203,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 }, ] -[[package]] -name = "alabaster" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929 }, -] - [[package]] name = "alembic" version = "1.14.0" @@ -325,19 +280,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, ] -[[package]] -name = "arrow" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "python-dateutil" }, - { name = "types-python-dateutil" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, -] - [[package]] name = "asttokens" version = "2.4.1" @@ -354,51 +296,11 @@ wheels = [ name = "async-timeout" version = "4.0.3" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", -] sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, ] -[[package]] -name = "async-timeout" -version = "5.0.1" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", -] -sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233 }, -] - -[[package]] -name = "asyncer" -version = "0.0.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/39/29/245ba9fa5769a1e3226c1157aedb372fe9dab28c4e1dcf6911d84d3a5e04/asyncer-0.0.7.tar.gz", hash = "sha256:d5e563fb0f56eb87b97257984703658a4f5bbdb52ff851b3e8ed864cc200b1d2", size = 14437 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/4b/40a1dc52fc26695b1e80a9e67dfb0fe7e6ddc57bbc5b61348e40c0045abb/asyncer-0.0.7-py3-none-any.whl", hash = "sha256:f0d579d4f67c4ead52ede3a45c854f462cae569058a8a6a68a4ebccac1c335d8", size = 8476 }, -] - -[[package]] -name = "asyncio-atexit" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/22/d3/dd2974be3f67c7ec96e0d6ab454429d0372cb7c7bffa3d0ac67a483cb801/asyncio-atexit-1.0.1.tar.gz", hash = "sha256:1d0c71544b8ee2c484d322844ee72c0875dde6f250c0ed5b6993592ab9f7d436", size = 4373 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/65/10/d6abaefa57a52646651fd0383c056280b0853c0106229ece6bb38cd14463/asyncio_atexit-1.0.1-py3-none-any.whl", hash = "sha256:d93d5f7d5633a534abd521ce2896ed0fbe8de170bb1e65ec871d1c20eac9d376", size = 3752 }, -] - [[package]] name = "attrs" version = "24.3.0" @@ -408,19 +310,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 }, ] -[[package]] -name = "autodoc-pydantic" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "pydantic-settings" }, - { name = "sphinx" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/df/87120e2195f08d760bc5cf8a31cfa2381a6887517aa89453b23f1ae3354f/autodoc_pydantic-2.2.0-py3-none-any.whl", hash = "sha256:8c6a36fbf6ed2700ea9c6d21ea76ad541b621fbdf16b5a80ee04673548af4d95", size = 34001 }, -] - [[package]] name = "autogen-agentchat" version = "0.4.3" @@ -445,54 +334,6 @@ dependencies = [ { name = "typing-extensions" }, ] -[package.dev-dependencies] -dev = [ - { name = "aiofiles" }, - { name = "asyncio-atexit" }, - { name = "autodoc-pydantic" }, - { name = "autogen-ext" }, - { name = "autogen-test-utils" }, - { name = "azure-identity" }, - { name = "chess" }, - { name = "colorama" }, - { name = "diskcache" }, - { name = "langchain-openai" }, - { name = "langgraph" }, - { name = "llama-index" }, - { name = "llama-index-embeddings-azure-openai" }, - { name = "llama-index-llms-azure-openai" }, - { name = "llama-index-readers-web" }, - { name = "llama-index-readers-wikipedia" }, - { name = "llama-index-tools-wikipedia" }, - { name = "markdownify" }, - { name = "myst-nb" }, - { name = "nbqa" }, - { name = "opentelemetry-sdk" }, - { name = "pip" }, - { name = "polars" }, - { name = "pydata-sphinx-theme" }, - { name = "pygments" }, - { name = "python-dotenv" }, - { name = "redis" }, - { name = "requests" }, - { name = "sphinx" }, - { name = "sphinx-autobuild" }, - { name = "sphinx-copybutton" }, - { name = "sphinx-design" }, - { name = "sphinxcontrib-apidoc" }, - { name = "sphinxext-rediraffe" }, - { name = "tavily-python" }, - { name = "textual" }, - { name = "textual-dev" }, - { name = "textual-imageview" }, - { name = "types-aiofiles" }, - { name = "types-docker" }, - { name = "types-pillow" }, - { name = "types-protobuf" }, - { name = "types-requests" }, - { name = "wikipedia" }, -] - [package.metadata] requires-dist = [ { name = "jsonref", specifier = "~=1.1.0" }, @@ -503,54 +344,6 @@ requires-dist = [ { name = "typing-extensions", specifier = ">=4.0.0" }, ] -[package.metadata.requires-dev] -dev = [ - { name = "aiofiles" }, - { name = "asyncio-atexit" }, - { name = "autodoc-pydantic", specifier = "~=2.2" }, - { name = "autogen-ext", editable = "packages/autogen-ext" }, - { name = "autogen-test-utils", editable = "packages/autogen-test-utils" }, - { name = "azure-identity" }, - { name = "chess" }, - { name = "colorama" }, - { name = "diskcache" }, - { name = "langchain-openai" }, - { name = "langgraph" }, - { name = "llama-index" }, - { name = "llama-index-embeddings-azure-openai" }, - { name = "llama-index-llms-azure-openai" }, - { name = "llama-index-readers-web" }, - { name = "llama-index-readers-wikipedia" }, - { name = "llama-index-tools-wikipedia" }, - { name = "markdownify" }, - { name = "myst-nb", specifier = "==1.1.2" }, - { name = "nbqa" }, - { name = "opentelemetry-sdk", specifier = ">=1.27.0" }, - { name = "pip" }, - { name = "polars" }, - { name = "pydata-sphinx-theme", specifier = "==0.15.4" }, - { name = "pygments" }, - { name = "python-dotenv" }, - { name = "redis" }, - { name = "requests" }, - { name = "sphinx" }, - { name = "sphinx-autobuild" }, - { name = "sphinx-copybutton" }, - { name = "sphinx-design" }, - { name = "sphinxcontrib-apidoc" }, - { name = "sphinxext-rediraffe" }, - { name = "tavily-python" }, - { name = "textual" }, - { name = "textual-dev" }, - { name = "textual-imageview" }, - { name = "types-aiofiles" }, - { name = "types-docker" }, - { name = "types-pillow" }, - { name = "types-protobuf" }, - { name = "types-requests" }, - { name = "wikipedia" }, -] - [[package]] name = "autogen-ext" version = "0.4.3" @@ -647,13 +440,6 @@ web-surfer = [ { name = "playwright" }, ] -[package.dev-dependencies] -dev = [ - { name = "autogen-test-utils" }, - { name = "langchain-experimental" }, - { name = "pandas-stubs" }, -] - [package.metadata] requires-dist = [ { name = "aiofiles", marker = "extra == 'openai'" }, @@ -697,13 +483,6 @@ requires-dist = [ { name = "tiktoken", marker = "extra == 'openai'", specifier = ">=0.8.0" }, ] -[package.metadata.requires-dev] -dev = [ - { name = "autogen-test-utils", editable = "packages/autogen-test-utils" }, - { name = "langchain-experimental" }, - { name = "pandas-stubs", specifier = ">=2.2.3.241126" }, -] - [[package]] name = "autogen-magentic-one" version = "0.0.1" @@ -730,16 +509,6 @@ dependencies = [ { name = "youtube-transcript-api" }, ] -[package.dev-dependencies] -dev = [ - { name = "aiofiles" }, - { name = "azure-identity" }, - { name = "openpyxl" }, - { name = "types-aiofiles" }, - { name = "types-pillow" }, - { name = "types-requests" }, -] - [package.metadata] requires-dist = [ { name = "aiofiles" }, @@ -763,16 +532,6 @@ requires-dist = [ { name = "youtube-transcript-api" }, ] -[package.metadata.requires-dev] -dev = [ - { name = "aiofiles" }, - { name = "azure-identity" }, - { name = "openpyxl" }, - { name = "types-aiofiles" }, - { name = "types-pillow" }, - { name = "types-requests" }, -] - [[package]] name = "autogen-test-utils" version = "0.0.0" @@ -861,19 +620,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6d/90/d13cf396989052cadd8511c1878b0913bbce28eeef5feb95710a92e03076/autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b", size = 52522 }, ] -[[package]] -name = "autopep8" -version = "2.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pycodestyle" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807 }, -] - [[package]] name = "azure-common" version = "1.1.28" @@ -956,15 +702,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e2/f8/ef0f76f8c424bedd20c685409836ddfb42ac76fd8a0f21c3c3659cf7207d/azure_storage_blob-12.24.0-py3-none-any.whl", hash = "sha256:4f0bb4592ea79a2d986063696514c781c9e62be240f09f6397986e01755bc071", size = 408579 }, ] -[[package]] -name = "babel" -version = "2.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, -] - [[package]] name = "beartype" version = "0.18.5" @@ -986,27 +723,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, ] -[[package]] -name = "bidict" -version = "0.23.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9a/6e/026678aa5a830e07cd9498a05d3e7e650a4f56a42f267a53d22bcda1bdc9/bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71", size = 29093 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5", size = 32764 }, -] - -[[package]] -name = "binaryornot" -version = "0.4.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "chardet" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a7/fe/7ebfec74d49f97fc55cd38240c7a7d08134002b1e14be8c3897c0dd5e49b/binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061", size = 371054 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/24/7e/f7b6f453e6481d1e233540262ccbfcf89adcd43606f44a028d7f5fae5eb2/binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4", size = 9006 }, -] - [[package]] name = "blinker" version = "1.9.0" @@ -1108,39 +824,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, ] -[[package]] -name = "chainlit" -version = "2.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiofiles" }, - { name = "asyncer" }, - { name = "click" }, - { name = "dataclasses-json" }, - { name = "fastapi" }, - { name = "filetype" }, - { name = "httpx" }, - { name = "lazify" }, - { name = "literalai" }, - { name = "nest-asyncio" }, - { name = "packaging" }, - { name = "pydantic" }, - { name = "pyjwt" }, - { name = "python-dotenv" }, - { name = "python-multipart" }, - { name = "python-socketio" }, - { name = "starlette" }, - { name = "syncer" }, - { name = "tomli" }, - { name = "uptrace" }, - { name = "uvicorn" }, - { name = "watchfiles" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e0/15/26dc5f957c6344813b2ae8c6f52cc820a7074088509ea947da0cf76ffc5f/chainlit-2.0.1.tar.gz", hash = "sha256:9fb7728aa5704e823c5b5d51f570dcfabafdcc97c23a73e6047f65eb72c938e7", size = 4637433 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/99/c63fa2e1d7b949c034b7fc838a0c00de22cd2cec30245e379c9dd15dedfd/chainlit-2.0.1-py3-none-any.whl", hash = "sha256:84982902c6f42a91ac341ea9b6d52e6b1348e53a60ee49b4ffe0e5e5be02f4ba", size = 4703745 }, -] - [[package]] name = "chardet" version = "5.2.0" @@ -1198,39 +881,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, ] -[[package]] -name = "chess" -version = "1.11.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/16/53b895bb4fccede8e506de820fa94db03a2dc8bd2ca4bec0aac4a112fb65/chess-1.11.1.tar.gz", hash = "sha256:b7f66a32dc599ab260e2b688e6ac4e868dad840377a54b61357e2dec2a5fed00", size = 156529 } - -[[package]] -name = "chevron" -version = "0.14.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/1f/ca74b65b19798895d63a6e92874162f44233467c9e7c1ed8afd19016ebe9/chevron-0.14.0.tar.gz", hash = "sha256:87613aafdf6d77b6a90ff073165a61ae5086e21ad49057aa0e53681601800ebf", size = 11440 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/52/93/342cc62a70ab727e093ed98e02a725d85b746345f05d2b5e5034649f4ec8/chevron-0.14.0-py3-none-any.whl", hash = "sha256:fbf996a709f8da2e745ef763f482ce2d311aa817d287593a5b990d6d6e4f0443", size = 11595 }, -] - -[[package]] -name = "chromedriver-autoinstaller" -version = "0.6.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d0/5a/9fc60c65673444d592b8922316c3abcd6177b42208c5a6179f96ccf0e11b/chromedriver-autoinstaller-0.6.4.tar.gz", hash = "sha256:1b4df04b87e6107c730085b98e5fd541db3d1777c32b8bd08e2ca4b1244050af", size = 6944 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/b5/36f0b0add145c371b5282e881a687601899f2d27fae5d0595bc02026b67c/chromedriver_autoinstaller-0.6.4-py3-none-any.whl", hash = "sha256:b12ed187ca9fac4d744deb588d221222ed50836384607e5303e6eab98bb9dc64", size = 7634 }, -] - [[package]] name = "click" version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "platform_system == 'Windows'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } wheels = [ @@ -1350,69 +1006,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/94/86bfae441707205634d80392e873295652fc313dfd93c233c52c4dc07874/contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53", size = 218221 }, ] -[[package]] -name = "cookiecutter" -version = "2.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "arrow" }, - { name = "binaryornot" }, - { name = "click" }, - { name = "jinja2" }, - { name = "python-slugify" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "rich" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/52/17/9f2cd228eb949a91915acd38d3eecdc9d8893dde353b603f0db7e9f6be55/cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c", size = 158767 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/d9/0137658a353168ffa9d0fc14b812d3834772040858ddd1cb6eeaf09f7a44/cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d", size = 39177 }, -] - -[[package]] -name = "coverage" -version = "7.6.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, - { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, - { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, - { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, - { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, - { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, - { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, - { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, - { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, - { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, - { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, - { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, - { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, - { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, - { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, - { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, - { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, - { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, - { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, - { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, - { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, - { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, - { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, - { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, - { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, - { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, - { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, - { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, - { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, - { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, - { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, -] - -[package.optional-dependencies] -toml = [ - { name = "tomli", marker = "python_full_version <= '3.11'" }, -] - [[package]] name = "cryptography" version = "44.0.0" @@ -1450,15 +1043,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/9d/37e5da7519de7b0b070a3fedd4230fe76d50d2a21403e0f2153d70ac4163/cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", size = 3128774 }, ] -[[package]] -name = "cssselect" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d1/91/d51202cc41fbfca7fa332f43a5adac4b253962588c7cc5a54824b019081c/cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", size = 41423 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/06/a9/2da08717a6862c48f1d61ef957a7bba171e7eefa6c0aa0ceb96a140c2a6b/cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e", size = 18687 }, -] - [[package]] name = "cycler" version = "0.12.1" @@ -1499,19 +1083,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/aa/3f/94cff4e36962b843a78a831770b9b44e476a5f9c76c0d53f7cf92053a1b4/dapr_ext_fastapi-1.14.0-py3-none-any.whl", hash = "sha256:88df67d6af33fd5adcf97d8799fa43373774b13cb9a1091ac4dd47e18a009ca0", size = 10458 }, ] -[[package]] -name = "dataclasses-json" -version = "0.6.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "marshmallow" }, - { name = "typing-inspect" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686 }, -] - [[package]] name = "debugpy" version = "1.8.11" @@ -1589,15 +1160,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/ae/afb1487556e2dc827a17097aac8158a25b433a345386f0e249f6d2694ccb/devtools-0.12.2-py3-none-any.whl", hash = "sha256:c366e3de1df4cdd635f1ad8cbcd3af01a384d7abda71900e68d43b04eb6aaca7", size = 19411 }, ] -[[package]] -name = "dirtyjson" -version = "1.0.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/04/d24f6e645ad82ba0ef092fa17d9ef7a21953781663648a01c9371d9e8e98/dirtyjson-1.0.8.tar.gz", hash = "sha256:90ca4a18f3ff30ce849d100dcf4a003953c79d3a2348ef056f1d9c22231a25fd", size = 30782 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/69/1bcf70f81de1b4a9f21b3a62ec0c83bdff991c88d6cc2267d02408457e88/dirtyjson-1.0.8-py3-none-any.whl", hash = "sha256:125e27248435a58acace26d5c2c4c11a1c0de0a9c5124c5a94ba78e517d74f53", size = 25197 }, -] - [[package]] name = "diskcache" version = "5.6.3" @@ -1639,15 +1201,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533 }, ] -[[package]] -name = "docutils" -version = "0.21.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, -] - [[package]] name = "environs" version = "11.2.1" @@ -1688,15 +1241,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, ] -[[package]] -name = "execnet" -version = "2.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 }, -] - [[package]] name = "executing" version = "2.1.0" @@ -1729,29 +1273,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924 }, ] -[[package]] -name = "feedfinder2" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "requests" }, - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/35/82/1251fefec3bb4b03fd966c7e7f7a41c9fc2bb00d823a34c13f847fd61406/feedfinder2-0.0.4.tar.gz", hash = "sha256:3701ee01a6c85f8b865a049c30ba0b4608858c803fe8e30d1d289fdbe89d0efe", size = 3297 } - -[[package]] -name = "feedparser" -version = "6.0.11" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "sgmllib3k" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ff/aa/7af346ebeb42a76bf108027fe7f3328bb4e57a3a96e53e21fd9ef9dd6dd0/feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5", size = 286197 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/d4/8c31aad9cc18f451c49f7f9cfb5799dadffc88177f7917bc90a66459b1d7/feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45", size = 81343 }, -] - [[package]] name = "ffmpeg-python" version = "0.2.0" @@ -1773,15 +1294,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, ] -[[package]] -name = "filetype" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/29/745f7d30d47fe0f251d3ad3dc2978a23141917661998763bebb6da007eb1/filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb", size = 998020 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970 }, -] - [[package]] name = "flask" version = "3.1.0" @@ -2385,43 +1897,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl", hash = "sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8", size = 14448 }, ] -[[package]] -name = "grpcio-tools" -version = "1.62.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "grpcio" }, - { name = "protobuf" }, - { name = "setuptools" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/54/fa/b69bd8040eafc09b88bb0ec0fea59e8aacd1a801e688af087cead213b0d0/grpcio-tools-1.62.3.tar.gz", hash = "sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833", size = 4538520 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/eb/eb0a3aa9480c3689d31fd2ad536df6a828e97a60f667c8a93d05bdf07150/grpcio_tools-1.62.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1", size = 5117556 }, - { url = "https://files.pythonhosted.org/packages/f3/fb/8be3dda485f7fab906bfa02db321c3ecef953a87cdb5f6572ca08b187bcb/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e", size = 2719330 }, - { url = "https://files.pythonhosted.org/packages/63/de/6978f8d10066e240141cd63d1fbfc92818d96bb53427074f47a8eda921e1/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26", size = 3070818 }, - { url = "https://files.pythonhosted.org/packages/74/34/bb8f816893fc73fd6d830e895e8638d65d13642bb7a434f9175c5ca7da11/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667", size = 2804993 }, - { url = "https://files.pythonhosted.org/packages/78/60/b2198d7db83293cdb9760fc083f077c73e4c182da06433b3b157a1567d06/grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193", size = 3684915 }, - { url = "https://files.pythonhosted.org/packages/61/20/56dbdc4ecb14d42a03cd164ff45e6e84572bbe61ee59c50c39f4d556a8d5/grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9", size = 3297482 }, - { url = "https://files.pythonhosted.org/packages/4a/dc/e417a313c905744ce8cedf1e1edd81c41dc45ff400ae1c45080e18f26712/grpcio_tools-1.62.3-cp310-cp310-win32.whl", hash = "sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5", size = 909793 }, - { url = "https://files.pythonhosted.org/packages/d9/69/75e7ebfd8d755d3e7be5c6d1aa6d13220f5bba3a98965e4b50c329046777/grpcio_tools-1.62.3-cp310-cp310-win_amd64.whl", hash = "sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d", size = 1052459 }, - { url = "https://files.pythonhosted.org/packages/23/52/2dfe0a46b63f5ebcd976570aa5fc62f793d5a8b169e211c6a5aede72b7ae/grpcio_tools-1.62.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23", size = 5147623 }, - { url = "https://files.pythonhosted.org/packages/f0/2e/29fdc6c034e058482e054b4a3c2432f84ff2e2765c1342d4f0aa8a5c5b9a/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492", size = 2719538 }, - { url = "https://files.pythonhosted.org/packages/f9/60/abe5deba32d9ec2c76cdf1a2f34e404c50787074a2fee6169568986273f1/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7", size = 3070964 }, - { url = "https://files.pythonhosted.org/packages/bc/ad/e2b066684c75f8d9a48508cde080a3a36618064b9cadac16d019ca511444/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43", size = 2805003 }, - { url = "https://files.pythonhosted.org/packages/9c/3f/59bf7af786eae3f9d24ee05ce75318b87f541d0950190ecb5ffb776a1a58/grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a", size = 3685154 }, - { url = "https://files.pythonhosted.org/packages/f1/79/4dd62478b91e27084c67b35a2316ce8a967bd8b6cb8d6ed6c86c3a0df7cb/grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3", size = 3297942 }, - { url = "https://files.pythonhosted.org/packages/b8/cb/86449ecc58bea056b52c0b891f26977afc8c4464d88c738f9648da941a75/grpcio_tools-1.62.3-cp311-cp311-win32.whl", hash = "sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5", size = 910231 }, - { url = "https://files.pythonhosted.org/packages/45/a4/9736215e3945c30ab6843280b0c6e1bff502910156ea2414cd77fbf1738c/grpcio_tools-1.62.3-cp311-cp311-win_amd64.whl", hash = "sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f", size = 1052496 }, - { url = "https://files.pythonhosted.org/packages/2a/a5/d6887eba415ce318ae5005e8dfac3fa74892400b54b6d37b79e8b4f14f5e/grpcio_tools-1.62.3-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5", size = 5147690 }, - { url = "https://files.pythonhosted.org/packages/8a/7c/3cde447a045e83ceb4b570af8afe67ffc86896a2fe7f59594dc8e5d0a645/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133", size = 2720538 }, - { url = "https://files.pythonhosted.org/packages/88/07/f83f2750d44ac4f06c07c37395b9c1383ef5c994745f73c6bfaf767f0944/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa", size = 3071571 }, - { url = "https://files.pythonhosted.org/packages/37/74/40175897deb61e54aca716bc2e8919155b48f33aafec8043dda9592d8768/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0", size = 2806207 }, - { url = "https://files.pythonhosted.org/packages/ec/ee/d8de915105a217cbcb9084d684abdc032030dcd887277f2ef167372287fe/grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d", size = 3685815 }, - { url = "https://files.pythonhosted.org/packages/fd/d9/4360a6c12be3d7521b0b8c39e5d3801d622fbb81cc2721dbd3eee31e28c8/grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc", size = 3298378 }, - { url = "https://files.pythonhosted.org/packages/29/3b/7cdf4a9e5a3e0a35a528b48b111355cd14da601413a4f887aa99b6da468f/grpcio_tools-1.62.3-cp312-cp312-win32.whl", hash = "sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b", size = 910416 }, - { url = "https://files.pythonhosted.org/packages/6c/66/dd3ec249e44c1cc15e902e783747819ed41ead1336fcba72bf841f72c6e9/grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl", hash = "sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7", size = 1052856 }, -] - [[package]] name = "h11" version = "0.14.0" @@ -2431,12 +1906,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, ] -[[package]] -name = "html2text" -version = "2024.2.26" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1a/43/e1d53588561e533212117750ee79ad0ba02a41f52a08c1df3396bd466c05/html2text-2024.2.26.tar.gz", hash = "sha256:05f8e367d15aaabc96415376776cdd11afd5127a77fce6e36afc60c563ca2c32", size = 56527 } - [[package]] name = "httpcore" version = "1.0.7" @@ -2478,17 +1947,8 @@ wheels = [ ] [[package]] -name = "httpx-sse" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, -] - -[[package]] -name = "huggingface-hub" -version = "0.27.1" +name = "huggingface-hub" +version = "0.27.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "filelock" }, @@ -2540,15 +2000,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, ] -[[package]] -name = "imagesize" -version = "1.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, -] - [[package]] name = "importlib-metadata" version = "8.4.0" @@ -2575,7 +2026,7 @@ name = "ipykernel" version = "6.29.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "appnope", marker = "platform_system == 'Darwin'" }, { name = "comm" }, { name = "debugpy" }, { name = "ipython" }, @@ -2646,12 +2097,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, ] -[[package]] -name = "jieba3k" -version = "0.35.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/cb/2c8332bcdc14d33b0bedd18ae0a4981a069c3513e445120da3c3f23a8aaa/jieba3k-0.35.1.zip", hash = "sha256:980a4f2636b778d312518066be90c7697d410dd5a472385f5afced71a2db1c10", size = 7423646 } - [[package]] name = "jinja2" version = "3.1.5" @@ -2816,25 +2261,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, ] -[[package]] -name = "jupyter-cache" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "click" }, - { name = "importlib-metadata" }, - { name = "nbclient" }, - { name = "nbformat" }, - { name = "pyyaml" }, - { name = "sqlalchemy" }, - { name = "tabulate" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bb/f7/3627358075f183956e8c4974603232b03afd4ddc7baf72c2bc9fff522291/jupyter_cache-1.0.1.tar.gz", hash = "sha256:16e808eb19e3fb67a223db906e131ea6e01f03aa27f49a7214ce6a5fec186fb9", size = 32048 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl", hash = "sha256:9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6", size = 33907 }, -] - [[package]] name = "jupyter-client" version = "8.6.3" @@ -2945,51 +2371,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/34/b9/a3d4bfdaefbc9098ef18bff2cf403c6060f70894c5022983464f9c3db367/lancedb-0.17.0-cp39-abi3-win_amd64.whl", hash = "sha256:9d7e82f83f430d906c285d3303729258b21b1cc8da634c9f7017e354bcb7318a", size = 27511050 }, ] -[[package]] -name = "langchain" -version = "0.3.14" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "langchain-core" }, - { name = "langchain-text-splitters" }, - { name = "langsmith" }, - { name = "numpy" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "sqlalchemy" }, - { name = "tenacity" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/18/35/2adb0693acc149e462bc0e7856ecd58096c285f66a78bc44fc2b8ae91ce0/langchain-0.3.14.tar.gz", hash = "sha256:4a5ae817b5832fa0e1fcadc5353fbf74bebd2f8e550294d4dc039f651ddcd3d1", size = 420409 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/a8/0a8f868615b7a30636b1d15b718e3ea9875bf0dccced03583477c2372495/langchain-0.3.14-py3-none-any.whl", hash = "sha256:5df9031702f7fe6c956e84256b4639a46d5d03a75be1ca4c1bc9479b358061a2", size = 1009213 }, -] - -[[package]] -name = "langchain-community" -version = "0.3.14" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "dataclasses-json" }, - { name = "httpx-sse" }, - { name = "langchain" }, - { name = "langchain-core" }, - { name = "langsmith" }, - { name = "numpy" }, - { name = "pydantic-settings" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "sqlalchemy" }, - { name = "tenacity" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/a32cddaa9e8c618e69cfbfdb11cb8718bd9a531ae8426f6a2125a7a5d31f/langchain_community-0.3.14.tar.gz", hash = "sha256:d8ba0fe2dbb5795bff707684b712baa5ee379227194610af415ccdfdefda0479", size = 1720031 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/df/3a226f47aad50605a4ff77a30e876d7520f2060aa624532872e44ea048d8/langchain_community-0.3.14-py3-none-any.whl", hash = "sha256:cc02a0abad0551edef3e565dff643386a5b2ee45b933b6d883d4a935b9649f3c", size = 2502417 }, -] - [[package]] name = "langchain-core" version = "0.3.29" @@ -3008,85 +2389,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/4f/fe1de63f6fc1ac7af3ba4ae12d420af1a19f7893b5fcb72856b9fc67f650/langchain_core-0.3.29-py3-none-any.whl", hash = "sha256:817db1474871611a81105594a3e4d11704949661008e455a10e38ca9ff601a1a", size = 411593 }, ] -[[package]] -name = "langchain-experimental" -version = "0.3.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "langchain-community" }, - { name = "langchain-core" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/27/56/a8acbb08a03383c28875b3b151e4cefea5612266917fbd6fc3c14c21e172/langchain_experimental-0.3.4.tar.gz", hash = "sha256:937c4259ee4a639c618d19acf0e2c5c2898ef127050346edc5655259aa281a21", size = 140532 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/27/fe8caa4884611286b1f7d6c5cfd76e1fef188faaa946db4fde6daa1cd2cd/langchain_experimental-0.3.4-py3-none-any.whl", hash = "sha256:2e587306aea36b60fa5e5fc05dc7281bee9f60a806f0bf9d30916e0ee096af80", size = 209154 }, -] - -[[package]] -name = "langchain-openai" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "langchain-core" }, - { name = "openai" }, - { name = "tiktoken" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/16/0a/0711117a4e8273d5edd4899399a8597d848b2d7b3c9ba3be97038b4fbc1a/langchain_openai-0.3.0.tar.gz", hash = "sha256:88d623eeb2aaa1fff65c2b419a4a1cfd37d3a1d504e598b87cf0bc822a3b70d0", size = 48067 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/9c/b38e308ac668f6db067b424a2a78e5b865753c144a119456f008a09230db/langchain_openai-0.3.0-py3-none-any.whl", hash = "sha256:49c921a22d272b04749a61e78bffa83aecdb8840b24b69f2909e115a357a9a5b", size = 54218 }, -] - -[[package]] -name = "langchain-text-splitters" -version = "0.3.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "langchain-core" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/10/35/a6f8d6b1bb0e6e8c00b49bce4d1a115f8b68368b1899f65bb34dbbb44160/langchain_text_splitters-0.3.5.tar.gz", hash = "sha256:11cb7ca3694e5bdd342bc16d3875b7f7381651d4a53cbb91d34f22412ae16443", size = 26318 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/83/f8081c3bea416bd9d9f0c26af795c74f42c24f9ad3c4fbf361b7d69de134/langchain_text_splitters-0.3.5-py3-none-any.whl", hash = "sha256:8c9b059827438c5fa8f327b4df857e307828a5ec815163c9b5c9569a3e82c8ee", size = 31620 }, -] - -[[package]] -name = "langgraph" -version = "0.2.62" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "langchain-core" }, - { name = "langgraph-checkpoint" }, - { name = "langgraph-sdk" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/54/bb/23859e3c219944bc9f1f3093629970631b3a6dc0aeaf607d7d205b2b551e/langgraph-0.2.62.tar.gz", hash = "sha256:0aac9fd55ffe669bc1312203e0f9ea2733c65cc276f196e7ff0d443cf4efbb89", size = 119343 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/30/38/571f8bc14d4ced8e9d86aca657ffd9a6d076e32e2a62d487eab15f2ceca7/langgraph-0.2.62-py3-none-any.whl", hash = "sha256:51ae9e02a52485a837642eebe7ae43269af7d7305d62f8f69ac11589b2fbba26", size = 138170 }, -] - -[[package]] -name = "langgraph-checkpoint" -version = "2.0.10" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "langchain-core" }, - { name = "msgpack" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/26/96/378e06c60d8c8cf44e1d6a2b669e9d5d87236bdee6bf7cfc9125ef5b5d0e/langgraph_checkpoint-2.0.10.tar.gz", hash = "sha256:2dcc04e09091d588bb6209e49d83ff5406d7231c2590d6ff18fb29ab8b140129", size = 33431 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/ef/c320b52035e29081f2693377602289a00545016b4adcc963d5e202ac0c92/langgraph_checkpoint-2.0.10-py3-none-any.whl", hash = "sha256:0d592cfda2df93844c6ea44d142170a8f7e5ba5320274e0e5e60e27f2749392c", size = 37476 }, -] - -[[package]] -name = "langgraph-sdk" -version = "0.1.51" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx" }, - { name = "orjson" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/32/d1/95ae599428e8e7d90229e402adf3056072f2ebd0c45c7f7154a5243ff35a/langgraph_sdk-0.1.51.tar.gz", hash = "sha256:dea1363e72562cb1e82a2d156be8d5b1a69ff3fe8815eee0e1e7a2f423242ec1", size = 41591 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/e9/d5d2ea883ddb3e16d4c18213457b3f3d04380089d410db71faae52a3c34a/langgraph_sdk-0.1.51-py3-none-any.whl", hash = "sha256:ce2b58466d1700d06149782ed113157a8694a6d7932c801f316cd13fab315fe4", size = 44652 }, -] - [[package]] name = "langsmith" version = "0.2.10" @@ -3103,15 +2405,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/91/e72d13f6b57a0ea9d884ab1d3388f544d7fe3354dbe1d4dd67678693a9fd/langsmith-0.2.10-py3-none-any.whl", hash = "sha256:b02f2f174189ff72e54c88b1aa63343defd6f0f676c396a690c63a4b6495dcc2", size = 326432 }, ] -[[package]] -name = "lazify" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/2c/b55c4a27a56dd9a00bb2812c404b57f8b7aec0cdbff9fdc61acdd73359bc/Lazify-0.4.0.tar.gz", hash = "sha256:7102bfe63e56de2ab62b3bc661a7190c4056771a8624f04a8b785275c3dd1f9b", size = 2968 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/03/a5/866b44697cee47d1cae429ed370281d937ad4439f71af82a6baaa139d26a/Lazify-0.4.0-py2.py3-none-any.whl", hash = "sha256:c2c17a7a33e9406897e3f66fde4cd3f84716218d580330e5af10cfe5a0cd195a", size = 3107 }, -] - [[package]] name = "lazy-object-proxy" version = "1.10.0" @@ -3142,327 +2435,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/8b/94dc8d58704ab87b39faed6f2fc0090b9d90e2e2aa2bbec35c79f3d2a054/lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d", size = 16405 }, ] -[[package]] -name = "linkify-it-py" -version = "2.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "uc-micro-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79", size = 19820 }, -] - -[[package]] -name = "literalai" -version = "0.0.623" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "chevron" }, - { name = "httpx" }, - { name = "packaging" }, - { name = "pydantic" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/41/af/07d943e62a1297a7b44777297c0dca8f4bfcd6ae18b9df7d3cd9c1970e29/literalai-0.0.623.tar.gz", hash = "sha256:d65c04dde6b1e99d585e4112a607e5fd574d282b70f600c55a671018340dfb0f", size = 57081 } - -[[package]] -name = "llama-cloud" -version = "0.1.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "httpx" }, - { name = "pydantic" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a0/e8/6dcc69cd624f3267e41e2077f33f98c27727a9842a5d8244ce6cf0671859/llama_cloud-0.1.8.tar.gz", hash = "sha256:7199bab2240a9cc330740003fa77648f43f6e533da411a8250a4a70584f91153", size = 90827 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/0f/af106de1780cf526c96de1ba279edcb55a0376a4484a7dea206f9f038cc4/llama_cloud-0.1.8-py3-none-any.whl", hash = "sha256:1a0c4cf212a04f2375f1d0791ca4e5f196e0fb0567c4ec96cd9dbcad773de60a", size = 247083 }, -] - -[[package]] -name = "llama-index" -version = "0.12.11" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-agent-openai" }, - { name = "llama-index-cli" }, - { name = "llama-index-core" }, - { name = "llama-index-embeddings-openai" }, - { name = "llama-index-indices-managed-llama-cloud" }, - { name = "llama-index-llms-openai" }, - { name = "llama-index-multi-modal-llms-openai" }, - { name = "llama-index-program-openai" }, - { name = "llama-index-question-gen-openai" }, - { name = "llama-index-readers-file" }, - { name = "llama-index-readers-llama-parse" }, - { name = "nltk" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/34/7eb11a6b6fa603fa0a072c1ffaa08d337d805d09feca5235bd42664d9ec4/llama_index-0.12.11.tar.gz", hash = "sha256:b1116946a2414aec104a6c417b847da5b4f077a0966c50ebd2fc445cd713adce", size = 7781 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/72/ab8bae2072c0e7786cbe7348d5b45bfb12972dd3a1fdb5cb96c615b779f6/llama_index-0.12.11-py3-none-any.whl", hash = "sha256:007361c35e1981a1656cef287b7bcdf22aa88e7d41b8e3a8ee261bb5a10519a9", size = 6876 }, -] - -[[package]] -name = "llama-index-agent-openai" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-index-llms-openai" }, - { name = "openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0b/09/bb3c4d5496f2d79499ca6d323f379e2051473b56a917ed46cf4d0d2aeb05/llama_index_agent_openai-0.4.2.tar.gz", hash = "sha256:0f8aeb091fc834b2667a46ad2417fc8601bf1c08ccfd1a3d15ede90a30eb1a29", size = 10612 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/37/21bdd9adce0e358203a81f245521e829d72547e14ecd6c298ec0327218a1/llama_index_agent_openai-0.4.2-py3-none-any.whl", hash = "sha256:e100b8a743b11fef373b5be31be590b929950a4d7fd9d158b5f014dd8fd7976e", size = 13205 }, -] - -[[package]] -name = "llama-index-cli" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-index-embeddings-openai" }, - { name = "llama-index-llms-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0a/52/81e1448d4dcff5beb1453f397f34f9ac769b7fcdb6b7c8fbd4c20b73e836/llama_index_cli-0.4.0.tar.gz", hash = "sha256:d6ab201359962a8a34368aeda3a49bbbe67e9e009c59bd925c4fb2be4ace3906", size = 24710 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/29/2b659e5930ea44253bf99e2afc395daaa2a3edaa579d99e63ea53df03313/llama_index_cli-0.4.0-py3-none-any.whl", hash = "sha256:60d12f89e6b85e80a0cc3a8b531f05a911b5eebaebc37314411476d1ba685904", size = 27785 }, -] - -[[package]] -name = "llama-index-core" -version = "0.12.11" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "dataclasses-json" }, - { name = "deprecated" }, - { name = "dirtyjson" }, - { name = "filetype" }, - { name = "fsspec" }, - { name = "httpx" }, - { name = "nest-asyncio" }, - { name = "networkx" }, - { name = "nltk" }, - { name = "numpy" }, - { name = "pillow" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "sqlalchemy", extra = ["asyncio"] }, - { name = "tenacity" }, - { name = "tiktoken" }, - { name = "tqdm" }, - { name = "typing-extensions" }, - { name = "typing-inspect" }, - { name = "wrapt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8d/a7/1ee40a8bcc5e7ff1dc523f2a26e217b3d7a306d4180b0654e9b4ab519c9c/llama_index_core-0.12.11.tar.gz", hash = "sha256:9a41ca91167ea5eec9ebaac7f5e958b7feddbd8af3bfbf7c393a5edfb994d566", size = 1332167 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/fb/3aadbfb0a43a734857802d6c372e70470921aaef3023b5e8f39dbdc6fd94/llama_index_core-0.12.11-py3-none-any.whl", hash = "sha256:3b1e019c899e9e011dfa01c96b7e3f666e0c161035fbca6cb787b4c61e0c94db", size = 1584262 }, -] - -[[package]] -name = "llama-index-embeddings-azure-openai" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-index-embeddings-openai" }, - { name = "llama-index-llms-azure-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/db/a35c34ff7863315ac133b4ff0386913cbe9986988e7f1c076e1745dbe015/llama_index_embeddings_azure_openai-0.3.0.tar.gz", hash = "sha256:80b0cf977d8b967a08536d65b8e2d0c6c966eeaf1b8fff084e97f3081fd70c34", size = 3111 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/78/eb22765325d03008dae55f98c77053231b9344d2bef6304f3d93121f3468/llama_index_embeddings_azure_openai-0.3.0-py3-none-any.whl", hash = "sha256:2ca61d6b75468d1230cfc1151a878d892b237130b8af09b4434f8c0466d44dfe", size = 3425 }, -] - -[[package]] -name = "llama-index-embeddings-openai" -version = "0.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/02/a2604ef3a167131fdd701888f45f16c8efa6d523d02efe8c4e640238f4ea/llama_index_embeddings_openai-0.3.1.tar.gz", hash = "sha256:1368aad3ce24cbaed23d5ad251343cef1eb7b4a06d6563d6606d59cb347fef20", size = 5492 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/45/ca55b91c4ac1b6251d4099fa44121a6c012129822906cadcc27b8cfb33a4/llama_index_embeddings_openai-0.3.1-py3-none-any.whl", hash = "sha256:f15a3d13da9b6b21b8bd51d337197879a453d1605e625a1c6d45e741756c0290", size = 6177 }, -] - -[[package]] -name = "llama-index-indices-managed-llama-cloud" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-cloud" }, - { name = "llama-index-core" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/58/29afa6086e2080ae27da79949e319f77f08cb7d1b2bd26e56a676dab1338/llama_index_indices_managed_llama_cloud-0.6.3.tar.gz", hash = "sha256:f09e4182cbc2a2bd75ae85cebb1681075247f0d91b931b094cac4315386ce87a", size = 10483 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/c6/ebb53a15e63c8da3633a595f53fc965509e8c6707da6a8b1bfa9b7923236/llama_index_indices_managed_llama_cloud-0.6.3-py3-none-any.whl", hash = "sha256:7f125602f624a2d321b6a4130cd98df35eb8c15818a159390755b2c13068f4ce", size = 11077 }, -] - -[[package]] -name = "llama-index-llms-azure-openai" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "azure-identity" }, - { name = "httpx" }, - { name = "llama-index-core" }, - { name = "llama-index-llms-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/81/d7/21264774d0e0819d869ac2f6527fd6b405340647feb4fef7b6b59c520858/llama_index_llms_azure_openai-0.3.0.tar.gz", hash = "sha256:0feea9319d832c8b5e8e0f397c905e45df54c529b6a778825adcd0d254bd7d63", size = 5557 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/49/a90c17bddddb411e0bc2d05bcf393fb03474279fb6fbe20c98db68473d98/llama_index_llms_azure_openai-0.3.0-py3-none-any.whl", hash = "sha256:24091aedf7ba24a7b217d17c4358e62b5d6b43a4d3ca44750d442b02a440d26e", size = 6306 }, -] - -[[package]] -name = "llama-index-llms-openai" -version = "0.3.13" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/12/0d/bc11eb89f8c912747d3a41186b8b9a2fc2c15cc52af7866689621e22ab4d/llama_index_llms_openai-0.3.13.tar.gz", hash = "sha256:51dda240dae7671c37e84bb50fe77fe6bb58a9b2a7e33dccd84473c9998afcea", size = 14302 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/22/b0dad3dd2b9054d020208cbc86e9fd730c04fe3551a9af2e640593eff6ef/llama_index_llms_openai-0.3.13-py3-none-any.whl", hash = "sha256:caea1d6cb5bdd34518fcefe28b784698c92120ed133e6cd4591f777cd15180b0", size = 14542 }, -] - -[[package]] -name = "llama-index-multi-modal-llms-openai" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-index-llms-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/eb/32/6f13d3cb79d71504072041d2e83fa67804c7945d2249f7ccadbcbbe15fdc/llama_index_multi_modal_llms_openai-0.4.2.tar.gz", hash = "sha256:3437a08cec85cebbc212aa73da5c9b8b054b4dc628338568435a7df88489476f", size = 5078 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/05/18/14772cebd9674772bc605632c92d4675e86d87a3263c35a90865d6c4918b/llama_index_multi_modal_llms_openai-0.4.2-py3-none-any.whl", hash = "sha256:093f60f59fc423abab110810f8f129b96b0212b9737d74480f0e3e1b715e975b", size = 5855 }, -] - -[[package]] -name = "llama-index-program-openai" -version = "0.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-agent-openai" }, - { name = "llama-index-core" }, - { name = "llama-index-llms-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7a/b8/24f1103106bfeed04f0e33b587863345c2d7fad001828bb02844a5427fbc/llama_index_program_openai-0.3.1.tar.gz", hash = "sha256:6039a6cdbff62c6388c07e82a157fe2edd3bbef0c5adf292ad8546bf4ec75b82", size = 4818 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/59/3f31171c30a08c8ba21155d5241ba174630e57cf43b03d97fd77bf565b51/llama_index_program_openai-0.3.1-py3-none-any.whl", hash = "sha256:93646937395dc5318fd095153d2f91bd632b25215d013d14a87c088887d205f9", size = 5318 }, -] - -[[package]] -name = "llama-index-question-gen-openai" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-index-llms-openai" }, - { name = "llama-index-program-openai" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4e/47/c57392e2fb00c0f596f912e7977e3c639ac3314f2aed5d4ac733baa367f1/llama_index_question_gen_openai-0.3.0.tar.gz", hash = "sha256:efd3b468232808e9d3474670aaeab00e41b90f75f52d0c9bfbf11207e0963d62", size = 2608 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/2c/765b0dfc2c988bbea267e236c836d7a96c60a20df76d842e43e17401f800/llama_index_question_gen_openai-0.3.0-py3-none-any.whl", hash = "sha256:9b60ec114273a63b50349948666e5744a8f58acb645824e07c979041e8fec598", size = 2899 }, -] - -[[package]] -name = "llama-index-readers-file" -version = "0.4.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "llama-index-core" }, - { name = "pandas" }, - { name = "pypdf" }, - { name = "striprtf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/35/62edc3eed9d69d9b5b5faae4c0c82ff05e608b07b0c547a988c23f19a79c/llama_index_readers_file-0.4.3.tar.gz", hash = "sha256:07514bebed7ce431c1b3ef9279d09aa3d1bba8e342d661860a033355b98fb33a", size = 22046 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/06/f41f795000c623d4cdaf95729a045a2be819c31f39951d5e88f4bccf37db/llama_index_readers_file-0.4.3-py3-none-any.whl", hash = "sha256:c669da967ea534e3af3660f9fd730c71c725288f5c57906bcce338414ebeee5c", size = 38914 }, -] - -[[package]] -name = "llama-index-readers-llama-parse" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "llama-parse" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/35/30/4611821286f82ba7b5842295607baa876262db86f88b87d83595eed172bf/llama_index_readers_llama_parse-0.4.0.tar.gz", hash = "sha256:e99ec56f4f8546d7fda1a7c1ae26162fb9acb7ebcac343b5abdb4234b4644e0f", size = 2472 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/4f/e30d4257fe9e4224f5612b77fe99aaceddae411b2e74ca30534491de3e6f/llama_index_readers_llama_parse-0.4.0-py3-none-any.whl", hash = "sha256:574e48386f28d2c86c3f961ca4a4906910312f3400dd0c53014465bfbc6b32bf", size = 2472 }, -] - -[[package]] -name = "llama-index-readers-web" -version = "0.3.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "beautifulsoup4" }, - { name = "chromedriver-autoinstaller" }, - { name = "html2text" }, - { name = "llama-index-core" }, - { name = "newspaper3k" }, - { name = "playwright" }, - { name = "requests" }, - { name = "selenium" }, - { name = "spider-client" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/89/a5/14e4277c871194092e014fd893f8f17a7c84f447a254696d7985ab9e603c/llama_index_readers_web-0.3.3.tar.gz", hash = "sha256:740373b17456cc46a9b39810253a3c1adfc8814d40f88798bea42115a10626ce", size = 53969 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/40/6e290cac34ac217b47347c7b0268114aef1f0c836998647d0c9f0fabc8f0/llama_index_readers_web-0.3.3-py3-none-any.whl", hash = "sha256:ab166bb14a56f5b10b637d6633c861d86bcaa72e7e123c4e31d304e6b1d88efe", size = 76616 }, -] - -[[package]] -name = "llama-index-readers-wikipedia" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ae/f1/1bd33ebbd003f1e19e9a77a85d0e77c0dd0c904de50cc9212cc718648813/llama_index_readers_wikipedia-0.3.0.tar.gz", hash = "sha256:77972387cd5410c981bd427699613de63e76889f99816512fc3fce3b2eca440a", size = 2445 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/8a/c85a69d9899fd6b7176bcbf6d19579feb1110e340a48b486f3682bc1bf60/llama_index_readers_wikipedia-0.3.0-py3-none-any.whl", hash = "sha256:1723441901a3a19f323872e3c5a968bbfc98cdc5f35e901c99e79f0e8cb7fa57", size = 2702 }, -] - -[[package]] -name = "llama-index-tools-wikipedia" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "llama-index-core" }, - { name = "wikipedia" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/86/fc/0ebe0913694a3582c0ae2c96cafb48689a9d012766e5b8a32d59932009de/llama_index_tools_wikipedia-0.3.0.tar.gz", hash = "sha256:8e3fc5ae8a479aacc6640c6c30a66f9848762bf8ebbbc4ceab41e8a4762a664c", size = 2487 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/89/0d7aa9a41ed0a0768790da770ef057416b81a92ecc35dc9f9d70a86abbb1/llama_index_tools_wikipedia-0.3.0-py3-none-any.whl", hash = "sha256:aa76c39237056b3ed727a23aadc65f34c5b500449ee9ec2efaced055f3ff9938", size = 2712 }, -] - -[[package]] -name = "llama-parse" -version = "0.5.19" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "llama-index-core" }, - { name = "pydantic" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3b/02/63839a55f6f207110400c4f394152fd0290e9f8e450226b02a87cfdbd835/llama_parse-0.5.19.tar.gz", hash = "sha256:db69da70e199a2664705eb983a70fa92b7cee19dd6cff175af7692a0b8a4dd53", size = 16100 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/b7/3ff106e8199992bb62e72f195c8f6f2f2fe4a185f5f92746f0ed9db5c5d2/llama_parse-0.5.19-py3-none-any.whl", hash = "sha256:715cc895d183531b4299359d4f4004089b2e522f5f137f316084e7aa04035b62", size = 15421 }, -] - [[package]] name = "llvmlite" version = "0.43.0" @@ -3579,9 +2551,6 @@ requires-dist = [ { name = "autogen-ext", extras = ["openai", "magentic-one"], editable = "packages/autogen-ext" }, ] -[package.metadata.requires-dev] -dev = [] - [[package]] name = "mako" version = "1.3.8" @@ -3618,14 +2587,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, ] -[package.optional-dependencies] -linkify = [ - { name = "linkify-it-py" }, -] -plugins = [ - { name = "mdit-py-plugins" }, -] - [[package]] name = "markdownify" version = "0.14.1" @@ -3768,18 +2729,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, ] -[[package]] -name = "mdit-py-plugins" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -3851,47 +2800,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/69/314d887a01599669fb330da14e5c6ff5f138609e322812a942a74ef9b765/msal_extensions-1.2.0-py3-none-any.whl", hash = "sha256:cf5ba83a2113fa6dc011a254a72f1c223c88d7dfad74cc30617c4679a417704d", size = 19254 }, ] -[[package]] -name = "msgpack" -version = "1.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/d0/7555686ae7ff5731205df1012ede15dd9d927f6227ea151e901c7406af4f/msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e", size = 167260 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/f9/a892a6038c861fa849b11a2bb0502c07bc698ab6ea53359e5771397d883b/msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd", size = 150428 }, - { url = "https://files.pythonhosted.org/packages/df/7a/d174cc6a3b6bb85556e6a046d3193294a92f9a8e583cdbd46dc8a1d7e7f4/msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d", size = 84131 }, - { url = "https://files.pythonhosted.org/packages/08/52/bf4fbf72f897a23a56b822997a72c16de07d8d56d7bf273242f884055682/msgpack-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:914571a2a5b4e7606997e169f64ce53a8b1e06f2cf2c3a7273aa106236d43dd5", size = 81215 }, - { url = "https://files.pythonhosted.org/packages/02/95/dc0044b439b518236aaf012da4677c1b8183ce388411ad1b1e63c32d8979/msgpack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c921af52214dcbb75e6bdf6a661b23c3e6417f00c603dd2070bccb5c3ef499f5", size = 371229 }, - { url = "https://files.pythonhosted.org/packages/ff/75/09081792db60470bef19d9c2be89f024d366b1e1973c197bb59e6aabc647/msgpack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8ce0b22b890be5d252de90d0e0d119f363012027cf256185fc3d474c44b1b9e", size = 378034 }, - { url = "https://files.pythonhosted.org/packages/32/d3/c152e0c55fead87dd948d4b29879b0f14feeeec92ef1fd2ec21b107c3f49/msgpack-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73322a6cc57fcee3c0c57c4463d828e9428275fb85a27aa2aa1a92fdc42afd7b", size = 363070 }, - { url = "https://files.pythonhosted.org/packages/d9/2c/82e73506dd55f9e43ac8aa007c9dd088c6f0de2aa19e8f7330e6a65879fc/msgpack-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e1f3c3d21f7cf67bcf2da8e494d30a75e4cf60041d98b3f79875afb5b96f3a3f", size = 359863 }, - { url = "https://files.pythonhosted.org/packages/cb/a0/3d093b248837094220e1edc9ec4337de3443b1cfeeb6e0896af8ccc4cc7a/msgpack-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64fc9068d701233effd61b19efb1485587560b66fe57b3e50d29c5d78e7fef68", size = 368166 }, - { url = "https://files.pythonhosted.org/packages/e4/13/7646f14f06838b406cf5a6ddbb7e8dc78b4996d891ab3b93c33d1ccc8678/msgpack-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:42f754515e0f683f9c79210a5d1cad631ec3d06cea5172214d2176a42e67e19b", size = 370105 }, - { url = "https://files.pythonhosted.org/packages/67/fa/dbbd2443e4578e165192dabbc6a22c0812cda2649261b1264ff515f19f15/msgpack-1.1.0-cp310-cp310-win32.whl", hash = "sha256:3df7e6b05571b3814361e8464f9304c42d2196808e0119f55d0d3e62cd5ea044", size = 68513 }, - { url = "https://files.pythonhosted.org/packages/24/ce/c2c8fbf0ded750cb63cbcbb61bc1f2dfd69e16dca30a8af8ba80ec182dcd/msgpack-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:685ec345eefc757a7c8af44a3032734a739f8c45d1b0ac45efc5d8977aa4720f", size = 74687 }, - { url = "https://files.pythonhosted.org/packages/b7/5e/a4c7154ba65d93be91f2f1e55f90e76c5f91ccadc7efc4341e6f04c8647f/msgpack-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d364a55082fb2a7416f6c63ae383fbd903adb5a6cf78c5b96cc6316dc1cedc7", size = 150803 }, - { url = "https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79ec007767b9b56860e0372085f8504db5d06bd6a327a335449508bbee9648fa", size = 84343 }, - { url = "https://files.pythonhosted.org/packages/42/ae/d3adea9bb4a1342763556078b5765e666f8fdf242e00f3f6657380920972/msgpack-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6ad622bf7756d5a497d5b6836e7fc3752e2dd6f4c648e24b1803f6048596f701", size = 81408 }, - { url = "https://files.pythonhosted.org/packages/dc/17/6313325a6ff40ce9c3207293aee3ba50104aed6c2c1559d20d09e5c1ff54/msgpack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e59bca908d9ca0de3dc8684f21ebf9a690fe47b6be93236eb40b99af28b6ea6", size = 396096 }, - { url = "https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1da8f11a3dd397f0a32c76165cf0c4eb95b31013a94f6ecc0b280c05c91b59", size = 403671 }, - { url = "https://files.pythonhosted.org/packages/bb/0b/fd5b7c0b308bbf1831df0ca04ec76fe2f5bf6319833646b0a4bd5e9dc76d/msgpack-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452aff037287acb1d70a804ffd022b21fa2bb7c46bee884dbc864cc9024128a0", size = 387414 }, - { url = "https://files.pythonhosted.org/packages/f0/03/ff8233b7c6e9929a1f5da3c7860eccd847e2523ca2de0d8ef4878d354cfa/msgpack-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8da4bf6d54ceed70e8861f833f83ce0814a2b72102e890cbdfe4b34764cdd66e", size = 383759 }, - { url = "https://files.pythonhosted.org/packages/1f/1b/eb82e1fed5a16dddd9bc75f0854b6e2fe86c0259c4353666d7fab37d39f4/msgpack-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:41c991beebf175faf352fb940bf2af9ad1fb77fd25f38d9142053914947cdbf6", size = 394405 }, - { url = "https://files.pythonhosted.org/packages/90/2e/962c6004e373d54ecf33d695fb1402f99b51832631e37c49273cc564ffc5/msgpack-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a52a1f3a5af7ba1c9ace055b659189f6c669cf3657095b50f9602af3a3ba0fe5", size = 396041 }, - { url = "https://files.pythonhosted.org/packages/f8/20/6e03342f629474414860c48aeffcc2f7f50ddaf351d95f20c3f1c67399a8/msgpack-1.1.0-cp311-cp311-win32.whl", hash = "sha256:58638690ebd0a06427c5fe1a227bb6b8b9fdc2bd07701bec13c2335c82131a88", size = 68538 }, - { url = "https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd2906780f25c8ed5d7b323379f6138524ba793428db5d0e9d226d3fa6aa1788", size = 74871 }, - { url = "https://files.pythonhosted.org/packages/e1/d6/716b7ca1dbde63290d2973d22bbef1b5032ca634c3ff4384a958ec3f093a/msgpack-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d", size = 152421 }, - { url = "https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5dbad74103df937e1325cc4bfeaf57713be0b4f15e1c2da43ccdd836393e2ea2", size = 85277 }, - { url = "https://files.pythonhosted.org/packages/28/51/da7f3ae4462e8bb98af0d5bdf2707f1b8c65a0d4f496e46b6afb06cbc286/msgpack-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58dfc47f8b102da61e8949708b3eafc3504509a5728f8b4ddef84bd9e16ad420", size = 82222 }, - { url = "https://files.pythonhosted.org/packages/33/af/dc95c4b2a49cff17ce47611ca9ba218198806cad7796c0b01d1e332c86bb/msgpack-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676e5be1b472909b2ee6356ff425ebedf5142427842aa06b4dfd5117d1ca8a2", size = 392971 }, - { url = "https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17fb65dd0bec285907f68b15734a993ad3fc94332b5bb21b0435846228de1f39", size = 401403 }, - { url = "https://files.pythonhosted.org/packages/97/8c/e333690777bd33919ab7024269dc3c41c76ef5137b211d776fbb404bfead/msgpack-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51abd48c6d8ac89e0cfd4fe177c61481aca2d5e7ba42044fd218cfd8ea9899f", size = 385356 }, - { url = "https://files.pythonhosted.org/packages/57/52/406795ba478dc1c890559dd4e89280fa86506608a28ccf3a72fbf45df9f5/msgpack-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2137773500afa5494a61b1208619e3871f75f27b03bcfca7b3a7023284140247", size = 383028 }, - { url = "https://files.pythonhosted.org/packages/e7/69/053b6549bf90a3acadcd8232eae03e2fefc87f066a5b9fbb37e2e608859f/msgpack-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:398b713459fea610861c8a7b62a6fec1882759f308ae0795b5413ff6a160cf3c", size = 391100 }, - { url = "https://files.pythonhosted.org/packages/23/f0/d4101d4da054f04274995ddc4086c2715d9b93111eb9ed49686c0f7ccc8a/msgpack-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06f5fd2f6bb2a7914922d935d3b8bb4a7fff3a9a91cfce6d06c13bc42bec975b", size = 394254 }, - { url = "https://files.pythonhosted.org/packages/1c/12/cf07458f35d0d775ff3a2dc5559fa2e1fcd06c46f1ef510e594ebefdca01/msgpack-1.1.0-cp312-cp312-win32.whl", hash = "sha256:ad33e8400e4ec17ba782f7b9cf868977d867ed784a1f5f2ab46e7ba53b6e1e1b", size = 69085 }, - { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 }, -] - [[package]] name = "multidict" version = "6.1.0" @@ -3949,35 +2857,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, ] -[[package]] -name = "mypy" -version = "1.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mypy-extensions" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, - { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, - { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, - { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, - { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, - { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, - { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, - { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, - { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, - { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, - { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, - { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, - { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, - { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, - { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, - { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, -] - [[package]] name = "mypy-extensions" version = "1.0.0" @@ -3987,57 +2866,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, ] -[[package]] -name = "mypy-protobuf" -version = "3.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, - { name = "types-protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4d/6f/282d64d66bf48ce60e38a6560753f784e0f88ab245ac2fb5e93f701a36cd/mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c", size = 24445 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/73/d6b999782ae22f16971cc05378b3b33f6a89ede3b9619e8366aa23484bca/mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c", size = 16434 }, -] - -[[package]] -name = "myst-nb" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "importlib-metadata" }, - { name = "ipykernel" }, - { name = "ipython" }, - { name = "jupyter-cache" }, - { name = "myst-parser" }, - { name = "nbclient" }, - { name = "nbformat" }, - { name = "pyyaml" }, - { name = "sphinx" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/e3/01c093f6a46be2edc0fd370cbf6d227495ea19452939b2810b36657c63d4/myst_nb-1.1.2.tar.gz", hash = "sha256:961b4005657029ca89892a4c75edbf0856c54ceaf6172368b46bf7676c1f7700", size = 78036 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/45/cf78b2f09c46b36f486b75c34a8b48580e53b543bd9a467b3c7eb9054b70/myst_nb-1.1.2-py3-none-any.whl", hash = "sha256:9b7034e5d62640cb6daf03f9ca16ef45d0462fced27944c77aa3f98c7cdcd566", size = 80281 }, -] - -[[package]] -name = "myst-parser" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "docutils" }, - { name = "jinja2" }, - { name = "markdown-it-py" }, - { name = "mdit-py-plugins" }, - { name = "pyyaml" }, - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/85/55/6d1741a1780e5e65038b74bce6689da15f620261c490c3511eb4c12bac4b/myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531", size = 93858 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, -] - [[package]] name = "nbclient" version = "0.10.2" @@ -4068,21 +2896,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, ] -[[package]] -name = "nbqa" -version = "1.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "autopep8" }, - { name = "ipython" }, - { name = "tokenize-rt" }, - { name = "tomli" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/aa/76/62d2609924cf34445148cd6b5de694cf64c179cc416cac93182579620e57/nbqa-1.9.1.tar.gz", hash = "sha256:a1f4bcf587c597302fed295951001fc4e1be4ce0e77e1ab1b25ac2fbe3db0cdd", size = 38348 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl", hash = "sha256:95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5", size = 35259 }, -] - [[package]] name = "nest-asyncio" version = "1.6.0" @@ -4101,30 +2914,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 }, ] -[[package]] -name = "newspaper3k" -version = "0.2.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "cssselect" }, - { name = "feedfinder2" }, - { name = "feedparser" }, - { name = "jieba3k" }, - { name = "lxml" }, - { name = "nltk" }, - { name = "pillow" }, - { name = "python-dateutil" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "tinysegmenter" }, - { name = "tldextract" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/fb/8f8525be0cafa48926e85b0c06a7cb3e2a892d340b8036f8c8b1b572df1c/newspaper3k-0.2.8.tar.gz", hash = "sha256:9f1bd3e1fb48f400c715abf875cc7b0a67b7ddcd87f50c9aeeb8fcbbbd9004fb", size = 205685 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/b9/51afecb35bb61b188a4b44868001de348a0e8134b4dfa00ffc191567c4b9/newspaper3k-0.2.8-py3-none-any.whl", hash = "sha256:44a864222633d3081113d1030615991c3dbba87239f6bbf59d91240f71a22e3e", size = 211132 }, -] - [[package]] name = "nltk" version = "3.9.1" @@ -4140,15 +2929,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4d/66/7d9e26593edda06e8cb531874633f7c2372279c3b0f46235539fe546df8b/nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1", size = 1505442 }, ] -[[package]] -name = "nodeenv" -version = "1.9.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, -] - [[package]] name = "numba" version = "0.60.0" @@ -4249,7 +3029,7 @@ name = "nvidia-cudnn-cu12" version = "9.1.0.70" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 }, @@ -4260,7 +3040,7 @@ name = "nvidia-cufft-cu12" version = "11.2.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/7a/8a/0e728f749baca3fbeffad762738276e5df60851958be7783af121a7221e7/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5dad8008fc7f92f5ddfa2101430917ce2ffacd86824914c82e28990ad7f00399", size = 211422548 }, @@ -4281,9 +3061,9 @@ name = "nvidia-cusolver-cu12" version = "11.6.1.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/46/6b/a5c33cf16af09166845345275c34ad2190944bcc6026797a39f8e0a282e0/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d338f155f174f90724bbde3758b7ac375a70ce8e706d70b018dd3375545fc84e", size = 127634111 }, @@ -4295,7 +3075,7 @@ name = "nvidia-cusparse-cu12" version = "12.3.1.170" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/96/a9/c0d2f83a53d40a4a41be14cea6a0bf9e668ffcf8b004bd65633f433050c0/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9d32f62896231ebe0480efd8a7f702e143c98cfaa0e8a76df3386c1ba2b54df3", size = 207381987 }, @@ -4520,93 +3300,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/1f/737dcdbc9fea2fa96c1b392ae47275165a7c641663fbb08a8d252968eed2/opentelemetry_api-1.27.0-py3-none-any.whl", hash = "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7", size = 63970 }, ] -[[package]] -name = "opentelemetry-exporter-otlp" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-exporter-otlp-proto-grpc" }, - { name = "opentelemetry-exporter-otlp-proto-http" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/d3/8156cc14e8f4573a3572ee7f30badc7aabd02961a09acc72ab5f2c789ef1/opentelemetry_exporter_otlp-1.27.0.tar.gz", hash = "sha256:4a599459e623868cc95d933c301199c2367e530f089750e115599fccd67cb2a1", size = 6166 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/59/6d/95e1fc2c8d945a734db32e87a5aa7a804f847c1657a21351df9338bd1c9c/opentelemetry_exporter_otlp-1.27.0-py3-none-any.whl", hash = "sha256:7688791cbdd951d71eb6445951d1cfbb7b6b2d7ee5948fac805d404802931145", size = 7001 }, -] - -[[package]] -name = "opentelemetry-exporter-otlp-proto-common" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-proto" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cd/2e/7eaf4ba595fb5213cf639c9158dfb64aacb2e4c7d74bfa664af89fa111f4/opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz", hash = "sha256:159d27cf49f359e3798c4c3eb8da6ef4020e292571bd8c5604a2a573231dd5c8", size = 17860 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/27/4610ab3d9bb3cde4309b6505f98b3aabca04a26aa480aa18cede23149837/opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl", hash = "sha256:675db7fffcb60946f3a5c43e17d1168a3307a94a930ecf8d2ea1f286f3d4f79a", size = 17848 }, -] - -[[package]] -name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "deprecated" }, - { name = "googleapis-common-protos" }, - { name = "grpcio" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-common" }, - { name = "opentelemetry-proto" }, - { name = "opentelemetry-sdk" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/d0/c1e375b292df26e0ffebf194e82cd197e4c26cc298582bda626ce3ce74c5/opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz", hash = "sha256:af6f72f76bcf425dfb5ad11c1a6d6eca2863b91e63575f89bb7b4b55099d968f", size = 26244 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/80/32217460c2c64c0568cea38410124ff680a9b65f6732867bbf857c4d8626/opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl", hash = "sha256:56b5bbd5d61aab05e300d9d62a6b3c134827bbd28d0b12f2649c2da368006c9e", size = 18541 }, -] - -[[package]] -name = "opentelemetry-exporter-otlp-proto-http" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "deprecated" }, - { name = "googleapis-common-protos" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-common" }, - { name = "opentelemetry-proto" }, - { name = "opentelemetry-sdk" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/31/0a/f05c55e8913bf58a033583f2580a0ec31a5f4cf2beacc9e286dcb74d6979/opentelemetry_exporter_otlp_proto_http-1.27.0.tar.gz", hash = "sha256:2103479092d8eb18f61f3fbff084f67cc7f2d4a7d37e75304b8b56c1d09ebef5", size = 15059 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/8d/4755884afc0b1db6000527cac0ca17273063b6142c773ce4ecd307a82e72/opentelemetry_exporter_otlp_proto_http-1.27.0-py3-none-any.whl", hash = "sha256:688027575c9da42e179a69fe17e2d1eba9b14d81de8d13553a21d3114f3b4d75", size = 17203 }, -] - -[[package]] -name = "opentelemetry-instrumentation" -version = "0.48b0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "setuptools" }, - { name = "wrapt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/0e/d9394839af5d55c8feb3b22cd11138b953b49739b20678ca96289e30f904/opentelemetry_instrumentation-0.48b0.tar.gz", hash = "sha256:94929685d906380743a71c3970f76b5f07476eea1834abd5dd9d17abfe23cc35", size = 24724 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/7f/405c41d4f359121376c9d5117dcf68149b8122d3f6c718996d037bd4d800/opentelemetry_instrumentation-0.48b0-py3-none-any.whl", hash = "sha256:a69750dc4ba6a5c3eb67986a337185a25b739966d80479befe37b546fc870b44", size = 29449 }, -] - -[[package]] -name = "opentelemetry-proto" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9a/59/959f0beea798ae0ee9c979b90f220736fbec924eedbefc60ca581232e659/opentelemetry_proto-1.27.0.tar.gz", hash = "sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6", size = 34749 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/56/3d2d826834209b19a5141eed717f7922150224d1a982385d19a9444cbf8d/opentelemetry_proto-1.27.0-py3-none-any.whl", hash = "sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace", size = 52464 }, -] - [[package]] name = "opentelemetry-sdk" version = "1.27.0" @@ -4681,18 +3374,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/7f/f2d346819a273653825e7c92dc26418c8da506003c9fc1dfe8157e733b2e/orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406", size = 133663 }, ] -[[package]] -name = "outcome" -version = "1.3.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 }, -] - [[package]] name = "overrides" version = "7.7.0" @@ -4746,19 +3427,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, ] -[[package]] -name = "pandas-stubs" -version = "2.2.3.241126" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "types-pytz" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/86/93c545d149c3e1fe1c4c55478cc3a69859d0ea3467e1d9892e9eb28cb1e7/pandas_stubs-2.2.3.241126.tar.gz", hash = "sha256:cf819383c6d9ae7d4dabf34cd47e1e45525bb2f312e6ad2939c2c204cb708acd", size = 104204 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/ab/ed42acf15bab2e86e5c49fad4aa038315233c4c2d22f41b49faa4d837516/pandas_stubs-2.2.3.241126-py3-none-any.whl", hash = "sha256:74aa79c167af374fe97068acc90776c0ebec5266a6e5c69fe11e9c2cf51f2267", size = 158280 }, -] - [[package]] name = "parse" version = "1.20.2" @@ -4777,15 +3445,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, ] -[[package]] -name = "pastel" -version = "0.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/f1/4594f5e0fcddb6953e5b8fe00da8c317b8b41b547e2b3ae2da7512943c62/pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d", size = 7555 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/18/a8444036c6dd65ba3624c63b734d3ba95ba63ace513078e1580590075d21/pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364", size = 5955 }, -] - [[package]] name = "pathable" version = "0.4.4" @@ -4816,15 +3475,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/87/2b/b50d3d08ea0fc419c183a84210571eba005328efa62b6b98bc28e9ead32a/patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c", size = 232923 }, ] -[[package]] -name = "pbr" -version = "6.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/35/80cf8f6a4f34017a7fe28242dc45161a1baa55c41563c354d8147e8358b2/pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24", size = 124032 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/44/6a65ecd630393d47ad3e7d5354768cb7f9a10b3a0eb2cd8c6f52b28211ee/pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a", size = 108529 }, -] - [[package]] name = "pdfminer-six" version = "20240706" @@ -4898,15 +3548,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/67/936f9814bdd74b2dfd4822f1f7725ab5d8ff4103919a1664eb4874c58b2f/pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", size = 2626353 }, ] -[[package]] -name = "pip" -version = "24.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz", hash = "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", size = 1931073 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl", hash = "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", size = 1822182 }, -] - [[package]] name = "platformdirs" version = "4.3.6" @@ -4943,40 +3584,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] -[[package]] -name = "poethepoet" -version = "0.32.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pastel" }, - { name = "pyyaml" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d1/10/11f929bad564b2dbc5c119ecf0f37456ac24538bb4a70c76f140a2aa695a/poethepoet-0.32.1.tar.gz", hash = "sha256:471e1a025812dcd3d2997e30989681be5ab0a49232ee5fba94859629671c9584", size = 61391 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/85/a5/fc26dd508f33809bdd3823a0170e492fe44ad7e097c32c4a52e16cf3ecb0/poethepoet-0.32.1-py3-none-any.whl", hash = "sha256:d1e0a52a2f677870fac17dfb26bfe4910242756ac821443ef31f90ad26227c2d", size = 81729 }, -] - -[[package]] -name = "polars" -version = "1.19.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/d9/66ada2204483c4c4d83898ade77eacd5fbef26ae4975a0d7d5de134ca46a/polars-1.19.0.tar.gz", hash = "sha256:b52ada5c43fcdadf64f282522198c5549ee4e46ea57d236a4d7e572643070d9d", size = 4267947 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/7d/e8645281281d44d96752443366ceef2df76c9c1e17dce040111abb6a4a12/polars-1.19.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:51c01837268a1aa41785e60ed7d3363d4b52f652ab0eef4981f887bdfa2e9ca7", size = 29472039 }, - { url = "https://files.pythonhosted.org/packages/d7/fb/7e5054598d6bb7a47e4ca086797bae61270f7d570350cf779dd97384d913/polars-1.19.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:20f8235e810f6ee795d7a215a3560945e6a1b57d017f87ba0c8542dced1fc665", size = 26150541 }, - { url = "https://files.pythonhosted.org/packages/ba/ba/6d715730c28b035abd308fc2cf0fcbae0cedea6216797e83ce4a9a96c6d4/polars-1.19.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0ea51f7b3553652bf0d53f3b925e969a898d4feb9980acecf8e3037d696903", size = 32751173 }, - { url = "https://files.pythonhosted.org/packages/ea/9a/bee8ab37ab82b8eea75170afa3b37ea7e1df74e4c4da8f6c93b3009977fd/polars-1.19.0-cp39-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:30305ef4e1b634c67a5d985832296fade9908482c5b1abb0100800808b2d090e", size = 29704437 }, - { url = "https://files.pythonhosted.org/packages/57/ec/74afa5699e37e03e3acc7f241f4e2c3e8c91847524005424d9cf038b3034/polars-1.19.0-cp39-abi3-win_amd64.whl", hash = "sha256:de4aa45e24f8f94a1da9cc6031a7db6fa65ac7de8246fac0bc581ebb427d0643", size = 32846039 }, - { url = "https://files.pythonhosted.org/packages/cf/5b/c6f6c70ddc9d3070dee65f4640437cb84ccb4cca04f7a81b01db15329ae3/polars-1.19.0-cp39-abi3-win_arm64.whl", hash = "sha256:d7ca7aeb63fa22c0a00f6cfa95dd5252c249e83dd4d1b954583a59f97a8e407b", size = 29029208 }, -] - [[package]] name = "portalocker" version = "2.10.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pywin32", marker = "sys_platform == 'win32'" }, + { name = "pywin32", marker = "platform_system == 'Windows'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ed/d3/c6c64067759e87af98cc668c1cc75171347d0f1577fab7ca3749134e3cd4/portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f", size = 40891 } wheels = [ @@ -5244,15 +3857,6 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/ee/52/9aa428633ef5aba4b096b2b2f8d046ece613cecab28b4ceed54126d25ea5/pybars4-0.9.13.tar.gz", hash = "sha256:425817da20d4ad320bc9b8e77a60cab1bb9d3c677df3dce224925c3310fcd635", size = 29907 } -[[package]] -name = "pycodestyle" -version = "2.12.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284 }, -] - [[package]] name = "pycparser" version = "2.22" @@ -5350,25 +3954,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/46/93416fdae86d40879714f72956ac14df9c7b76f7d41a4d68aa9f71a0028b/pydantic_settings-2.7.1-py3-none-any.whl", hash = "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd", size = 29718 }, ] -[[package]] -name = "pydata-sphinx-theme" -version = "0.15.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "accessible-pygments" }, - { name = "babel" }, - { name = "beautifulsoup4" }, - { name = "docutils" }, - { name = "packaging" }, - { name = "pygments" }, - { name = "sphinx" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/67/ea/3ab478cccacc2e8ef69892c42c44ae547bae089f356c4b47caf61730958d/pydata_sphinx_theme-0.15.4.tar.gz", hash = "sha256:7762ec0ac59df3acecf49fd2f889e1b4565dbce8b88b2e29ee06fdd90645a06d", size = 2400673 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl", hash = "sha256:2136ad0e9500d0949f96167e63f3e298620040aea8f9c74621959eda5d4cf8e6", size = 4640157 }, -] - [[package]] name = "pydub" version = "0.25.1" @@ -5461,18 +4046,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, ] -[[package]] -name = "pypdf" -version = "5.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6b/9a/72d74f05f64895ebf1c7f6646cf7fe6dd124398c5c49240093f92d6f0fdd/pypdf-5.1.0.tar.gz", hash = "sha256:425a129abb1614183fd1aca6982f650b47f8026867c0ce7c4b9f281c443d2740", size = 5011381 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/fc/6f52588ac1cb4400a7804ef88d0d4e00cfe57a7ac6793ec3b00de5a8758b/pypdf-5.1.0-py3-none-any.whl", hash = "sha256:3bd4f503f4ebc58bae40d81e81a9176c400cbbac2ba2d877367595fb524dfdfc", size = 297976 }, -] - [[package]] name = "pyreadline3" version = "3.5.4" @@ -5482,28 +4055,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178 }, ] -[[package]] -name = "pyright" -version = "1.1.389" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 }, -] - -[[package]] -name = "pysocks" -version = "1.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 }, -] - [[package]] name = "pytest" version = "8.3.4" @@ -5521,56 +4072,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] -[[package]] -name = "pytest-asyncio" -version = "0.25.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/df/adcc0d60f1053d74717d21d58c0048479e9cab51464ce0d2965b086bd0e2/pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f", size = 53950 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/61/d8/defa05ae50dcd6019a95527200d3b3980043df5aa445d40cb0ef9f7f98ab/pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075", size = 19400 }, -] - -[[package]] -name = "pytest-cov" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "coverage", extra = ["toml"] }, - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, -] - -[[package]] -name = "pytest-mock" -version = "3.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, -] - -[[package]] -name = "pytest-xdist" -version = "3.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "execnet" }, - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108 }, -] - [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -5592,27 +4093,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, ] -[[package]] -name = "python-engineio" -version = "4.11.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "simple-websocket" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/52/e0/a9e0fe427ce7f1b7dbf9531fa00ffe4b557c4a7bc8e71891c115af123170/python_engineio-4.11.2.tar.gz", hash = "sha256:145bb0daceb904b4bb2d3eb2d93f7dbb7bb87a6a0c4f20a94cc8654dec977129", size = 91381 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/8f/978a0b913e3f8ad33a9a2fe204d32efe3d1ee34ecb1f2829c1cfbdd92082/python_engineio-4.11.2-py3-none-any.whl", hash = "sha256:f0971ac4c65accc489154fe12efd88f53ca8caf04754c46a66e85f5102ef22ad", size = 59239 }, -] - -[[package]] -name = "python-multipart" -version = "0.0.18" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/86/b6b38677dec2e2e7898fc5b6f7e42c2d011919a92d25339451892f27b89c/python_multipart-0.0.18.tar.gz", hash = "sha256:7a68db60c8bfb82e460637fa4750727b45af1d5e2ed215593f917f64694d34fe", size = 36622 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/6b/b60f47101ba2cac66b4a83246630e68ae9bbe2e614cbae5f4465f46dee13/python_multipart-0.0.18-py3-none-any.whl", hash = "sha256:efe91480f485f6a361427a541db4796f9e1591afc0fb8e7a4ba06bfbc6708996", size = 24389 }, -] - [[package]] name = "python-pptx" version = "1.0.2" @@ -5628,31 +4108,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/4f/00be2196329ebbff56ce564aa94efb0fbc828d00de250b1980de1a34ab49/python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba", size = 472788 }, ] -[[package]] -name = "python-slugify" -version = "8.0.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "text-unidecode" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051 }, -] - -[[package]] -name = "python-socketio" -version = "5.12.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "bidict" }, - { name = "python-engineio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/d0/40ed38076e8aee94785d546d3e3a1cae393da5806a8530be877187e2875f/python_socketio-5.12.1.tar.gz", hash = "sha256:0299ff1f470b676c09c1bfab1dead25405077d227b2c13cf217a34dadc68ba9c", size = 119991 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/a3/c69806f30dd81df5a99d592e7db4c930c3a9b098555aa97b0eb866b20b11/python_socketio-5.12.1-py3-none-any.whl", hash = "sha256:24a0ea7cfff0e021eb28c68edbf7914ee4111bdf030b95e4d250c4dc9af7a386", size = 76947 }, -] - [[package]] name = "pytz" version = "2024.2" @@ -5770,8 +4225,7 @@ name = "redis" version = "5.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "async-timeout", version = "5.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and python_full_version < '3.11.3'" }, + { name = "async-timeout", marker = "python_full_version < '3.11.3'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/47/da/d283a37303a995cd36f8b92db85135153dc4f7a8e4441aa827721b442cfb/redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f", size = 4608355 } wheels = [ @@ -5860,18 +4314,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] -[[package]] -name = "requests-file" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/97/bf44e6c6bd8ddbb99943baf7ba8b1a8485bcd2fe0e55e5708d7fee4ff1ae/requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658", size = 6891 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/25/dd878a121fcfdf38f52850f11c512e13ec87c2ea72385933818e5b6c15ce/requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c", size = 4244 }, -] - [[package]] name = "requests-toolbelt" version = "1.0.0" @@ -6028,30 +4470,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, ] -[[package]] -name = "ruff" -version = "0.4.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/6b/4545638200466af8b9407bd0d5bea1ce426328eaa9714f8d3ef1a43fc0e6/ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268", size = 2559790 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/fd/cbdfeba4f72856853705b4dfc01c232fd6000cdbbde801224783de65c2a6/ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066", size = 8547521 }, - { url = "https://files.pythonhosted.org/packages/b2/8d/8930e04a82f376b99db57d8d1c86bd35c06496e77f58f6b2cdb388cd12d9/ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913", size = 8149146 }, - { url = "https://files.pythonhosted.org/packages/59/82/63d590c95025d526acc64803ab783f457ba15b3e16bea5bfb4b7ba9bf105/ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3", size = 8192701 }, - { url = "https://files.pythonhosted.org/packages/70/f4/97e142f3c9cb2c886798821e31136b58a6095e068b5bf6a9667f45dcf70b/ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb", size = 7578485 }, - { url = "https://files.pythonhosted.org/packages/fd/46/2b9addf3e3078c6d2c78135480f9dbf104257cfa6736d65154e9c7f64a34/ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764", size = 8768085 }, - { url = "https://files.pythonhosted.org/packages/b5/bf/b7bcec679c67a74d4df5ecaa6e09352d4dd14a365a1d0ce76deb6f5d8a56/ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883", size = 9439095 }, - { url = "https://files.pythonhosted.org/packages/cb/46/1a7bfa8f739116ec48d737d78d99b6e1c3c6307992b17b11bc8a44ee393f/ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199", size = 9060426 }, - { url = "https://files.pythonhosted.org/packages/ad/6b/e82233a81554df12a3508a25a5068d005fb7b69b14cc4194237e7b4c5fcf/ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b", size = 10250216 }, - { url = "https://files.pythonhosted.org/packages/21/77/9d9c536d8544d8b1b2fe1fcd5e3e190b946d91dc00a8956aa5fe88cb264b/ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45", size = 8797490 }, - { url = "https://files.pythonhosted.org/packages/95/90/a614ec4ee32a61dcd76c5d77ef5c336acac447cf731d81313e42dcbc34ed/ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a", size = 8092448 }, - { url = "https://files.pythonhosted.org/packages/1f/5b/d0a5ddf505593bacb52f386b0b92533dc2e87658a59ec55fe5b72890f1af/ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc", size = 7573842 }, - { url = "https://files.pythonhosted.org/packages/da/4a/d6af0c924514ebc588474b5002ac9bc6cc0b2328d3633c1b10b0227032c1/ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed", size = 8358130 }, - { url = "https://files.pythonhosted.org/packages/49/c4/3fbfb5a0020c9f67439dcef5a6e4f6a4f3430a059eaf40b624c00aa31bfa/ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa", size = 8842486 }, - { url = "https://files.pythonhosted.org/packages/a5/e6/c18211dd3fad5a1da66a1bd7a00e3bdc7541fa997adeeb087c2147f1e18a/ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9", size = 7832464 }, - { url = "https://files.pythonhosted.org/packages/95/b7/5b64aba350763aff321463e775f9daee9ad575750ebdb9f60f86f682f913/ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d", size = 8580070 }, - { url = "https://files.pythonhosted.org/packages/fe/f1/3db1590be946c14d86ac0cc8422e5808500903592b7ca09a097e425b1dba/ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780", size = 7944828 }, -] - [[package]] name = "s3transfer" version = "0.11.1" @@ -6158,23 +4576,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, ] -[[package]] -name = "selenium" -version = "4.27.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "trio" }, - { name = "trio-websocket" }, - { name = "typing-extensions" }, - { name = "urllib3", extra = ["socks"] }, - { name = "websocket-client" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/44/8c/62c47c91072aa03af1c3b7d7f1c59b987db41c9fec0f158fb03a0da51aa6/selenium-4.27.1.tar.gz", hash = "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2", size = 973526 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/1e/5f1a5dd2a28528c4b3ec6e076b58e4c035810c805328f9936123283ca14e/selenium-4.27.1-py3-none-any.whl", hash = "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18", size = 9707007 }, -] - [[package]] name = "semantic-kernel" version = "1.18.2" @@ -6266,12 +4667,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, ] -[[package]] -name = "sgmllib3k" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/bd/3704a8c3e0942d711c1299ebf7b9091930adae6675d7c8f476a7ce48653c/sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9", size = 5750 } - [[package]] name = "shapely" version = "2.0.6" @@ -6310,18 +4705,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, ] -[[package]] -name = "simple-websocket" -version = "1.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wsproto" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b0/d4/bfa032f961103eba93de583b161f0e6a5b63cebb8f2c7d0c6e6efe1e3d2e/simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4", size = 17300 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c", size = 13842 }, -] - [[package]] name = "simsimd" version = "6.2.1" @@ -6369,243 +4752,68 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/86/16e8d5b9bdd34f75c7515adfad249f394653131bd1a1366076cf6113e84b/simsimd-6.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:050f68cfa85f1fb2cfa156280928e42926e3977034b755023ce1315bf59e87ff", size = 302974 }, { url = "https://files.pythonhosted.org/packages/02/09/3f4240f2b43957aa0d72a2203b2549c0326c7baf97b7f78c72d48d4cd3d2/simsimd-6.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67bb4b17e04919545f29c7b708faaccbe027f164f8b5c9f4328604fa8f5560ea", size = 227864 }, { url = "https://files.pythonhosted.org/packages/07/4a/8c46806493c3a98025f01d81d9f55e0e574f11279c2ad77be919262ea9eb/simsimd-6.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3d6bffd999dbb36e606b065e0180365efac2606049c4f7818e4cba2d34c3678f", size = 432491 }, - { url = "https://files.pythonhosted.org/packages/13/44/b56f207031405af52c6158c40e9f1121fe3a716d98946d9fa5919cf00266/simsimd-6.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:25adb244fb75dbf49af0d1bcac4ed4a3fef8e847d78449faa5595af0a3e20d61", size = 633061 }, - { url = "https://files.pythonhosted.org/packages/4c/ad/241f87641af09a1789af8df559aa86b45218d087e09c37c2dd8c013819d6/simsimd-6.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b4542cee77e801a9c27370fc36ae271514fc0fb2ce14a35f8b25f47989e3d267", size = 468544 }, - { url = "https://files.pythonhosted.org/packages/e2/3e/357aca7df85ed1092dfa50b91cf1b7c0df6f70b384a0e3798132dd824b5c/simsimd-6.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:4f665228f8ff4911790b485e74b00fa9586a141dde6011970be71bb303b5a22f", size = 269133 }, - { url = "https://files.pythonhosted.org/packages/f0/67/079ca2c58bbc5812802c6ac1b332a6ef889d73cf1188726f36edc27898f6/simsimd-6.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:783b4308f80ae00763b0eaa0dac26196958f9c2df60d35a0347ebd2f82ece46d", size = 344412 }, - { url = "https://files.pythonhosted.org/packages/3c/f0/500c9002276259c17e3a6a13a7c7f84e5119602decadbf40429c978655b0/simsimd-6.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:95055e72cfe313c1c8694783bf8a631cc15673b3b775abef367e396d931db0b8", size = 389546 }, - { url = "https://files.pythonhosted.org/packages/55/a2/d3f4c6aabba0430758367b3de5bbab59b979bf3525c039b882001f1d2ade/simsimd-6.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a98f2b383f51b4f4ee568a637fc7958a347fdae0bd184cff8faa8030b6454a39", size = 316912 }, - { url = "https://files.pythonhosted.org/packages/f8/a3/2514189c3aaa1beb1714b36be86e2d3af7067c3c95152d78cc4cffff6d87/simsimd-6.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e474fd10ceb38e2c9f826108a7762f8ff7912974846d86f08c4e7b19cd35ed4", size = 670006 }, - { url = "https://files.pythonhosted.org/packages/ef/23/dbf7c4aed7542260784dc7bc2056a4e5b6d716a14a9b40989d5c3096990a/simsimd-6.2.1-cp312-cp312-win32.whl", hash = "sha256:b2530ea44fffeab25e5752bec6a5991f30fbc430b04647980db5b195c0971d48", size = 55019 }, - { url = "https://files.pythonhosted.org/packages/a0/d8/57304c2317822634abd475f5912584a3cfa13363740e9ec72c0622c894f1/simsimd-6.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:dc23283235d5b8f0373b95a547e26da2d7785647a5d0fa15c282fc8c49c0dcb0", size = 87133 }, - { url = "https://files.pythonhosted.org/packages/3f/7b/ca333232a8bc87d1e846fa2feb9f0d4778500c30493726cb48f04551dfab/simsimd-6.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:5692ce7e56253178eea9dbd58191734918409b83d54b07cfdcecf868d0150a73", size = 60401 }, -] - -[[package]] -name = "six" -version = "1.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, -] - -[[package]] -name = "smart-open" -version = "7.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wrapt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/21/30/1f41c3d3b8cec82024b4b277bfd4e5b18b765ae7279eb9871fa25c503778/smart_open-7.1.0.tar.gz", hash = "sha256:a4f09f84f0f6d3637c6543aca7b5487438877a21360e7368ccf1f704789752ba", size = 72044 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/18/9a8d9f01957aa1f8bbc5676d54c2e33102d247e146c1a3679d3bd5cc2e3a/smart_open-7.1.0-py3-none-any.whl", hash = "sha256:4b8489bb6058196258bafe901730c7db0dcf4f083f316e97269c66f45502055b", size = 61746 }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, -] - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, -] - -[[package]] -name = "sortedcontainers" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, -] - -[[package]] -name = "soupsieve" -version = "2.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, -] - -[[package]] -name = "speechrecognition" -version = "3.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/67/b91500f0796806659c37ba4da26750148ea98cd4e00d951facfdf4f440b3/speechrecognition-3.14.0.tar.gz", hash = "sha256:8f23d0125422fac358a05697ceffb5d7387a3f699fc2dcf829ee692fb15471c2", size = 32860450 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/25/447b3a61afbc1d7e713ba56df0156aab1450442db752f1e6741d6a9f41df/SpeechRecognition-3.14.0-py3-none-any.whl", hash = "sha256:28303ae2b6abc13408963a91f838996f181f1c256936f94b8c021b51fcd4a3f5", size = 32852277 }, -] - -[[package]] -name = "sphinx" -version = "8.1.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "alabaster" }, - { name = "babel" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "docutils" }, - { name = "imagesize" }, - { name = "jinja2" }, - { name = "packaging" }, - { name = "pygments" }, - { name = "requests" }, - { name = "snowballstemmer" }, - { name = "sphinxcontrib-applehelp" }, - { name = "sphinxcontrib-devhelp" }, - { name = "sphinxcontrib-htmlhelp" }, - { name = "sphinxcontrib-jsmath" }, - { name = "sphinxcontrib-qthelp" }, - { name = "sphinxcontrib-serializinghtml" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125 }, -] - -[[package]] -name = "sphinx-autobuild" -version = "2024.10.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama" }, - { name = "sphinx" }, - { name = "starlette" }, - { name = "uvicorn" }, - { name = "watchfiles" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908 }, -] - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343 }, -] - -[[package]] -name = "sphinx-design" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, -] - -[[package]] -name = "sphinxcontrib-apidoc" -version = "0.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pbr" }, - { name = "sphinx" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/52/8c/a4fe93b51a1026c217731337cfe50569b8521d3e254dd451126bed208cd8/sphinxcontrib-apidoc-0.5.0.tar.gz", hash = "sha256:65efcd92212a5f823715fb95ee098b458a6bb09a5ee617d9ed3dead97177cd55", size = 16117 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/35/453ba8b0f407b9b86520eba5122fe28e87230266cfae9524a623b524485e/sphinxcontrib_apidoc-0.5.0-py3-none-any.whl", hash = "sha256:c671d644d6dc468be91b813dcddf74d87893bff74fe8f1b8b01b69408f0fb776", size = 8603 }, -] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, + { url = "https://files.pythonhosted.org/packages/13/44/b56f207031405af52c6158c40e9f1121fe3a716d98946d9fa5919cf00266/simsimd-6.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:25adb244fb75dbf49af0d1bcac4ed4a3fef8e847d78449faa5595af0a3e20d61", size = 633061 }, + { url = "https://files.pythonhosted.org/packages/4c/ad/241f87641af09a1789af8df559aa86b45218d087e09c37c2dd8c013819d6/simsimd-6.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b4542cee77e801a9c27370fc36ae271514fc0fb2ce14a35f8b25f47989e3d267", size = 468544 }, + { url = "https://files.pythonhosted.org/packages/e2/3e/357aca7df85ed1092dfa50b91cf1b7c0df6f70b384a0e3798132dd824b5c/simsimd-6.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:4f665228f8ff4911790b485e74b00fa9586a141dde6011970be71bb303b5a22f", size = 269133 }, + { url = "https://files.pythonhosted.org/packages/f0/67/079ca2c58bbc5812802c6ac1b332a6ef889d73cf1188726f36edc27898f6/simsimd-6.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:783b4308f80ae00763b0eaa0dac26196958f9c2df60d35a0347ebd2f82ece46d", size = 344412 }, + { url = "https://files.pythonhosted.org/packages/3c/f0/500c9002276259c17e3a6a13a7c7f84e5119602decadbf40429c978655b0/simsimd-6.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:95055e72cfe313c1c8694783bf8a631cc15673b3b775abef367e396d931db0b8", size = 389546 }, + { url = "https://files.pythonhosted.org/packages/55/a2/d3f4c6aabba0430758367b3de5bbab59b979bf3525c039b882001f1d2ade/simsimd-6.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a98f2b383f51b4f4ee568a637fc7958a347fdae0bd184cff8faa8030b6454a39", size = 316912 }, + { url = "https://files.pythonhosted.org/packages/f8/a3/2514189c3aaa1beb1714b36be86e2d3af7067c3c95152d78cc4cffff6d87/simsimd-6.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e474fd10ceb38e2c9f826108a7762f8ff7912974846d86f08c4e7b19cd35ed4", size = 670006 }, + { url = "https://files.pythonhosted.org/packages/ef/23/dbf7c4aed7542260784dc7bc2056a4e5b6d716a14a9b40989d5c3096990a/simsimd-6.2.1-cp312-cp312-win32.whl", hash = "sha256:b2530ea44fffeab25e5752bec6a5991f30fbc430b04647980db5b195c0971d48", size = 55019 }, + { url = "https://files.pythonhosted.org/packages/a0/d8/57304c2317822634abd475f5912584a3cfa13363740e9ec72c0622c894f1/simsimd-6.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:dc23283235d5b8f0373b95a547e26da2d7785647a5d0fa15c282fc8c49c0dcb0", size = 87133 }, + { url = "https://files.pythonhosted.org/packages/3f/7b/ca333232a8bc87d1e846fa2feb9f0d4778500c30493726cb48f04551dfab/simsimd-6.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:5692ce7e56253178eea9dbd58191734918409b83d54b07cfdcecf868d0150a73", size = 60401 }, ] [[package]] -name = "sphinxcontrib-devhelp" -version = "2.0.0" +name = "six" +version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, ] [[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.1.0" +name = "smart-open" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +dependencies = [ + { name = "wrapt" }, ] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +sdist = { url = "https://files.pythonhosted.org/packages/21/30/1f41c3d3b8cec82024b4b277bfd4e5b18b765ae7279eb9871fa25c503778/smart_open-7.1.0.tar.gz", hash = "sha256:a4f09f84f0f6d3637c6543aca7b5487438877a21360e7368ccf1f704789752ba", size = 72044 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, + { url = "https://files.pythonhosted.org/packages/7a/18/9a8d9f01957aa1f8bbc5676d54c2e33102d247e146c1a3679d3bd5cc2e3a/smart_open-7.1.0-py3-none-any.whl", hash = "sha256:4b8489bb6058196258bafe901730c7db0dcf4f083f316e97269c66f45502055b", size = 61746 }, ] [[package]] -name = "sphinxcontrib-qthelp" -version = "2.0.0" +name = "sniffio" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] [[package]] -name = "sphinxcontrib-serializinghtml" -version = "2.0.0" +name = "soupsieve" +version = "2.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, ] [[package]] -name = "sphinxext-rediraffe" -version = "0.2.7" +name = "speechrecognition" +version = "3.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/b4/e5fbb493f796430230189a1ce5f9beff1ac1b98619fc71ed35deca6059a5/sphinxext-rediraffe-0.2.7.tar.gz", hash = "sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d", size = 8735 } +sdist = { url = "https://files.pythonhosted.org/packages/ce/67/b91500f0796806659c37ba4da26750148ea98cd4e00d951facfdf4f440b3/speechrecognition-3.14.0.tar.gz", hash = "sha256:8f23d0125422fac358a05697ceffb5d7387a3f699fc2dcf829ee692fb15471c2", size = 32860450 } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/4f/c8797e796199e55cf6c8979ecdf5f4b09b81e93f87b3193c759faea63263/sphinxext_rediraffe-0.2.7-py3-none-any.whl", hash = "sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c", size = 8267 }, -] - -[[package]] -name = "spider-client" -version = "0.0.27" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "requests" }, + { url = "https://files.pythonhosted.org/packages/5e/25/447b3a61afbc1d7e713ba56df0156aab1450442db752f1e6741d6a9f41df/SpeechRecognition-3.14.0-py3-none-any.whl", hash = "sha256:28303ae2b6abc13408963a91f838996f181f1c256936f94b8c021b51fcd4a3f5", size = 32852277 }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/fc/a2a4cc112c467f89921328d005c0ac2df9c81f62c8a6d445f747252f5856/spider-client-0.0.27.tar.gz", hash = "sha256:c3feaf5c491bd9a6c509efa0c8789452497073d9f68e70fc90e7626a6a8365aa", size = 5755 } [[package]] name = "sqlalchemy" @@ -6644,11 +4852,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/36/59cc97c365f2f79ac9f3f51446cae56dfd82c4f2dd98497e6be6de20fb91/SQLAlchemy-2.0.37-py3-none-any.whl", hash = "sha256:a8998bf9f8658bd3839cbc44ddbe982955641863da0c1efe5b00c1ab4f5c16b1", size = 1894113 }, ] -[package.optional-dependencies] -asyncio = [ - { name = "greenlet" }, -] - [[package]] name = "sqlmodel" version = "0.0.22" @@ -6721,15 +4924,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/9a/e466a1b887a1441141e52dbcc98152f013d85076576da6eed2357f2016ae/statsmodels-0.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:7f7917a51766b4e074da283c507a25048ad29a18e527207883d73535e0dc6184", size = 9823866 }, ] -[[package]] -name = "striprtf" -version = "0.0.26" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/20/3d419008265346452d09e5dadfd5d045b64b40d8fc31af40588e6c76997a/striprtf-0.0.26.tar.gz", hash = "sha256:fdb2bba7ac440072d1c41eab50d8d74ae88f60a8b6575c6e2c7805dc462093aa", size = 6258 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/cf/0fea4f4ba3fc2772ac2419278aa9f6964124d4302117d61bc055758e000c/striprtf-0.0.26-py3-none-any.whl", hash = "sha256:8c8f9d32083cdc2e8bfb149455aa1cc5a4e0a035893bedc75db8b73becb3a1bb", size = 6914 }, -] - [[package]] name = "sympy" version = "1.13.1" @@ -6742,12 +4936,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 }, ] -[[package]] -name = "syncer" -version = "2.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8d/dd/d4dd75843692690d81f0a4b929212a1614b25d4896aa7c72f4c3546c7e3d/syncer-2.0.3.tar.gz", hash = "sha256:4340eb54b54368724a78c5c0763824470201804fe9180129daf3635cb500550f", size = 11512 } - [[package]] name = "tabulate" version = "0.9.0" @@ -6757,20 +4945,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, ] -[[package]] -name = "tavily-python" -version = "0.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx" }, - { name = "requests" }, - { name = "tiktoken" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ca/50/7f4acafe72ffd10d3578ddec76f993af5af81504bc7315ea54862f2705b9/tavily_python-0.5.0.tar.gz", hash = "sha256:2c60b88203b630e1b37fc711913a1090ced6719b3f21089f25ec06e9e1602822", size = 16455 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/99/05776f7150a5b3f8d853377144a3a634131964c0fce38307537674a9a674/tavily_python-0.5.0-py3-none-any.whl", hash = "sha256:e874f6a04a56cdda80a505fe0b4f5d61d25372bd52a83e6773926fb297dcaa29", size = 14361 }, -] - [[package]] name = "tenacity" version = "9.0.0" @@ -6780,77 +4954,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, ] -[[package]] -name = "text-unidecode" -version = "1.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154 }, -] - -[[package]] -name = "textual" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py", extra = ["linkify", "plugins"] }, - { name = "platformdirs" }, - { name = "rich" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1f/b6/59b1de04bb4dca0f21ed7ba0b19309ed7f3f5de4396edf20cc2855e53085/textual-1.0.0.tar.gz", hash = "sha256:bec9fe63547c1c552569d1b75d309038b7d456c03f86dfa3706ddb099b151399", size = 1532733 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/bb/5fb6656c625019cd653d5215237d7cd6e0b12e7eae4195c3d1c91b2136fc/textual-1.0.0-py3-none-any.whl", hash = "sha256:2d4a701781c05104925e463ae370c630567c70c2880e92ab838052e3e23c986f", size = 660456 }, -] - -[[package]] -name = "textual-dev" -version = "1.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "click" }, - { name = "msgpack" }, - { name = "textual" }, - { name = "textual-serve" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/d3/ed0b20f6de0af1b7062c402d59d256029c0daa055ad9e04c27471b450cdd/textual_dev-1.7.0.tar.gz", hash = "sha256:bf1a50eaaff4cd6a863535dd53f06dbbd62617c371604f66f56de3908220ccd5", size = 25935 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/50/4b/3c1eb9cbc39f2f28d27e10ef2fe42bfe0cf3c2f8445a454c124948d6169b/textual_dev-1.7.0-py3-none-any.whl", hash = "sha256:a93a846aeb6a06edb7808504d9c301565f7f4bf2e7046d56583ed755af356c8d", size = 27221 }, -] - -[[package]] -name = "textual-imageview" -version = "0.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pillow" }, - { name = "rich" }, - { name = "textual" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4b/31/3d8a517bd8694ee0d70fd260fbc20590f00a5fcde6ca1ce2edb174c000ac/textual_imageview-0.1.1.tar.gz", hash = "sha256:4299d8ed677db0adb8fe945687470cf1421dcafd2a5dddab54b6ee8ef2ab3320", size = 3232614 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/56/c0514dcfdb2b67333bf4e653ca9cf0fda51004932d3b246bf835376cbaba/textual_imageview-0.1.1-py3-none-any.whl", hash = "sha256:335c8043e2f1f735b1b2ec1753a743d6762578175cd2cedae3ce67e2694800a4", size = 8875 }, -] - -[[package]] -name = "textual-serve" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "aiohttp-jinja2" }, - { name = "jinja2" }, - { name = "rich" }, - { name = "textual" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/18/6c/57248070f525ea8a9a02d9f58dc2747c609b615b0bda1306aaeb80a233bd/textual_serve-1.1.1.tar.gz", hash = "sha256:71c662472c462e5e368defc660ee6e8eae3bfda88ca40c050c55474686eb0c54", size = 445957 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/a9/01d35770fde8d889e1fe28b726188cf28801e57afd369c614cd2bc100ee4/textual_serve-1.1.1-py3-none-any.whl", hash = "sha256:568782f1c0e60e3f7039d9121e1cb5c2f4ca1aaf6d6bd7aeb833d5763a534cb2", size = 445034 }, -] - [[package]] name = "threadpoolctl" version = "3.5.0" @@ -6890,36 +4993,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/e2/39d4aa02a52bba73b2cd21ba4533c84425ff8786cc63c511d68c8897376e/tiktoken-0.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:d8f3192733ac4d77977432947d563d7e1b310b96497acd3c196c9bddb36ed9db", size = 883824 }, ] -[[package]] -name = "tinysegmenter" -version = "0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/82/86982e4b6d16e4febc79c2a1d68ee3b707e8a020c5d2bc4af8052d0f136a/tinysegmenter-0.3.tar.gz", hash = "sha256:ed1f6d2e806a4758a73be589754384cbadadc7e1a414c81a166fc9adf2d40c6d", size = 16893 } - -[[package]] -name = "tldextract" -version = "5.1.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "filelock" }, - { name = "idna" }, - { name = "requests" }, - { name = "requests-file" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4a/4f/eee4bebcbad25a798bf55601d3a4aee52003bebcf9e55fce08b91ca541a9/tldextract-5.1.3.tar.gz", hash = "sha256:d43c7284c23f5dc8a42fd0fee2abede2ff74cc622674e4cb07f514ab3330c338", size = 125033 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/86/aebe15fa40a992c446be5cf14e70e58a251277494c14d26bdbcff0e658fd/tldextract-5.1.3-py3-none-any.whl", hash = "sha256:78de310cc2ca018692de5ddf320f9d6bd7c5cf857d0fd4f2175f0cdf4440ea75", size = 104923 }, -] - -[[package]] -name = "tokenize-rt" -version = "6.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/0a/5854d8ced8c1e00193d1353d13db82d7f813f99bd5dcb776ce3e2a4c0d19/tokenize_rt-6.1.0.tar.gz", hash = "sha256:e8ee836616c0877ab7c7b54776d2fefcc3bde714449a206762425ae114b53c86", size = 5506 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/87/ba/576aac29b10dfa49a6ce650001d1bb31f81e734660555eaf144bfe5b8995/tokenize_rt-6.1.0-py2.py3-none-any.whl", hash = "sha256:d706141cdec4aa5f358945abe36b911b8cbdc844545da99e811250c0cee9b6fc", size = 6015 }, -] - [[package]] name = "tokenizers" version = "0.21.0" @@ -6974,15 +5047,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] -[[package]] -name = "tomli-w" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675 }, -] - [[package]] name = "torch" version = "2.5.1" @@ -6992,21 +5056,21 @@ dependencies = [ { name = "fsspec" }, { name = "jinja2" }, { name = "networkx" }, - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, - { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, { name = "setuptools", marker = "python_full_version >= '3.12'" }, { name = "sympy" }, - { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "triton", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, { name = "typing-extensions" }, ] wheels = [ @@ -7047,7 +5111,7 @@ name = "tqdm" version = "4.67.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "platform_system == 'Windows'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 } wheels = [ @@ -7090,44 +5154,12 @@ torch = [ { name = "torch" }, ] -[[package]] -name = "trio" -version = "0.28.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "cffi", marker = "(implementation_name != 'pypy' and os_name == 'nt' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'pypy' and os_name == 'nt' and sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "idna" }, - { name = "outcome" }, - { name = "sniffio" }, - { name = "sortedcontainers" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/73/57efab729506a8d4b89814f1e356ec8f3369de0ed4fd7e7616974d09646d/trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", size = 580318 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/04/9954a59e1fb6732f5436225c9af963811d7b24ea62a8bf96991f2cb8c26e/trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94", size = 486317 }, -] - -[[package]] -name = "trio-websocket" -version = "0.11.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "trio" }, - { name = "wsproto" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/dd/36/abad2385853077424a11b818d9fd8350d249d9e31d583cb9c11cd4c85eda/trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f", size = 26511 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/be/a9ae5f50cad5b6f85bd2574c2c923730098530096e170c1ce7452394d7aa/trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638", size = 17408 }, -] - [[package]] name = "triton" version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "filelock", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 }, @@ -7150,85 +5182,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/cc/0a838ba5ca64dc832aa43f727bd586309846b0ffb2ce52422543e6075e8a/typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847", size = 44908 }, ] -[[package]] -name = "types-aiofiles" -version = "24.1.0.20241221" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ab/5e/f984b9ddc7eecdf31e683e692d933f3672276ed95aad6adb9aea9ecbdc29/types_aiofiles-24.1.0.20241221.tar.gz", hash = "sha256:c40f6c290b0af9e902f7f3fa91213cf5bb67f37086fb21dc0ff458253586ad55", size = 14081 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/da/77902220df98ce920444cf3611fa0b1cf0dc2cfa5a137c55e93829aa458e/types_aiofiles-24.1.0.20241221-py3-none-any.whl", hash = "sha256:11d4e102af0627c02e8c1d17736caa3c39de1058bea37e2f4de6ef11a5b652ab", size = 14162 }, -] - -[[package]] -name = "types-docker" -version = "7.1.0.20241229" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "types-requests" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/00/4b/7ca6c1fe916ef4c71f145234902bb4da074e410d9cc0bd72572790c3f06d/types_docker-7.1.0.20241229.tar.gz", hash = "sha256:d968f164bb02f934bc2f178515dd4b3c8b2b4e371a9400ec440247c09c139545", size = 29032 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/32/8a1c95566816fef8f7b2407d25981cf0d3ecf2f226ed0ab3a34969994ab7/types_docker-7.1.0.20241229-py3-none-any.whl", hash = "sha256:b760745a6cb0351a19108c0b76e2a43ebc05a686f6c3ec9bc1a991ff9f1cc353", size = 43650 }, -] - -[[package]] -name = "types-pillow" -version = "10.2.0.20240822" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/4a/4495264dddaa600d65d68bcedb64dcccf9d9da61adff51f7d2ffd8e4c9ce/types-Pillow-10.2.0.20240822.tar.gz", hash = "sha256:559fb52a2ef991c326e4a0d20accb3bb63a7ba8d40eb493e0ecb0310ba52f0d3", size = 35389 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/66/23/e81a5354859831fcf54d488d33b80ba6133ea84f874a9c0ec40a4881e133/types_Pillow-10.2.0.20240822-py3-none-any.whl", hash = "sha256:d9dab025aba07aeb12fd50a6799d4eac52a9603488eca09d7662543983f16c5d", size = 54354 }, -] - -[[package]] -name = "types-protobuf" -version = "5.29.1.20241207" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/89/b661a447139f665ccea8e39bfdd52a92f803df4b5de0e6001a3537feaacb/types_protobuf-5.29.1.20241207.tar.gz", hash = "sha256:2ebcadb8ab3ef2e3e2f067e0882906d64ba0dc65fc5b0fd7a8b692315b4a0be9", size = 59190 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/6e/cdf152187019d6f6d04066b23e48659d961b527e9c6d43b48459d160e332/types_protobuf-5.29.1.20241207-py3-none-any.whl", hash = "sha256:92893c42083e9b718c678badc0af7a9a1307b92afe1599e5cba5f3d35b668b2f", size = 73902 }, -] - -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20241206" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, -] - -[[package]] -name = "types-pytz" -version = "2024.2.0.20241221" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/26/516311b02b5a215e721155fb65db8a965d061372e388d6125ebce8d674b0/types_pytz-2024.2.0.20241221.tar.gz", hash = "sha256:06d7cde9613e9f7504766a0554a270c369434b50e00975b3a4a0f6eed0f2c1a9", size = 10213 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/74/db/c92ca6920cccd9c2998b013601542e2ac5e59bc805bcff94c94ad254b7df/types_pytz-2024.2.0.20241221-py3-none-any.whl", hash = "sha256:8fc03195329c43637ed4f593663df721fef919b60a969066e22606edf0b53ad5", size = 10008 }, -] - -[[package]] -name = "types-requests" -version = "2.32.0.20241016" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fa/3c/4f2a430c01a22abd49a583b6b944173e39e7d01b688190a5618bd59a2e22/types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95", size = 18065 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/01/485b3026ff90e5190b5e24f1711522e06c79f4a56c8f4b95848ac072e20f/types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747", size = 15836 }, -] - -[[package]] -name = "types-tabulate" -version = "0.9.0.20241207" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/43/16030404a327e4ff8c692f2273854019ed36718667b2993609dc37d14dd4/types_tabulate-0.9.0.20241207.tar.gz", hash = "sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230", size = 8195 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/86/a9ebfd509cbe74471106dffed320e208c72537f9aeb0a55eaa6b1b5e4d17/types_tabulate-0.9.0.20241207-py3-none-any.whl", hash = "sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85", size = 8307 }, -] - [[package]] name = "typing-extensions" version = "4.12.2" @@ -7260,15 +5213,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, ] -[[package]] -name = "uc-micro-py" -version = "1.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/7a/146a99696aee0609e3712f2b44c6274566bc368dfe8375191278045186b8/uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a", size = 6043 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5", size = 6229 }, -] - [[package]] name = "umap-learn" version = "0.5.7" @@ -7286,21 +5230,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/8f/671c0e1f2572ba625cbcc1faeba9435e00330c3d6962858711445cf1e817/umap_learn-0.5.7-py3-none-any.whl", hash = "sha256:6a7e0be2facfa365a5ed6588447102bdbef32a0ef449535c25c97ea7e680073c", size = 88815 }, ] -[[package]] -name = "uptrace" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp" }, - { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-sdk" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f3/89/ba1df9328e4bd4b440ac6979e20ec8c63a26f6400598e806cc9dfef764f4/uptrace-1.27.0.tar.gz", hash = "sha256:983f783b2f4303d1d2bdfaf6ace1b7a5f072af47f78a7815f82c51fcf5099cac", size = 7633 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/77/00/054ac30e9e8312c3c79371c495dd570865eab2a05bfcd640f6242d460c8b/uptrace-1.27.0-py3-none-any.whl", hash = "sha256:d5473efa33c34e3d5738d32d19301dbf004d4e19598c658f2fa9f3f09458f630", size = 8627 }, -] - [[package]] name = "uritemplate" version = "4.1.1" @@ -7319,11 +5248,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, ] -[package.optional-dependencies] -socks = [ - { name = "pysocks" }, -] - [[package]] name = "usearch" version = "2.16.9" @@ -7377,30 +5301,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/59/fddd9df489fe27f492cc97626e03663fb3b9b6ef7ce8597a7cdc5f2cbbad/uvicorn-0.25.0-py3-none-any.whl", hash = "sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c", size = 60303 }, ] -[[package]] -name = "watchfiles" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ef/48/02d2d2cbf54e134810b2cb40ac79fdb8ce08476184536a4764717a7bc9f4/watchfiles-0.20.0.tar.gz", hash = "sha256:728575b6b94c90dd531514677201e8851708e6e4b5fe7028ac506a200b622019", size = 37041 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/db/899832e11fef2d468bf8b3c1c13289b1db4cb7c3410bb2a9612a52fc8b22/watchfiles-0.20.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3796312bd3587e14926013612b23066912cf45a14af71cf2b20db1c12dadf4e9", size = 417357 }, - { url = "https://files.pythonhosted.org/packages/9f/1a/85c914e4db62a3f8197daa98a271ea380a5d200a8d3058bd9f417752bc26/watchfiles-0.20.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d0002d81c89a662b595645fb684a371b98ff90a9c7d8f8630c82f0fde8310458", size = 407258 }, - { url = "https://files.pythonhosted.org/packages/25/ae/b7bddad421af5e33079a2ce639aa58837b715a2da98df16e25ecd310af52/watchfiles-0.20.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:570848706440373b4cd8017f3e850ae17f76dbdf1e9045fc79023b11e1afe490", size = 1331327 }, - { url = "https://files.pythonhosted.org/packages/21/e5/b080cec4e841b1cf338ccbd958cf3232ad1691a590653b2d124b5c79cf6b/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0351d20d03c6f7ad6b2e8a226a5efafb924c7755ee1e34f04c77c3682417fa", size = 1301371 }, - { url = "https://files.pythonhosted.org/packages/05/a0/2fb2c36730995a6b3f060187195dc08ad9ceee67426bdca8a4296024071c/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:007dcc4a401093010b389c044e81172c8a2520dba257c88f8828b3d460c6bb38", size = 1302438 }, - { url = "https://files.pythonhosted.org/packages/13/ea/d11971958ae703cfe443b21f672169cb8bc12dbec5781b910633fa2186ec/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d82dbc1832da83e441d112069833eedd4cf583d983fb8dd666fbefbea9d99c0", size = 1410655 }, - { url = "https://files.pythonhosted.org/packages/6b/81/3f922f3ede53ca9c0b4095f63688ffeea19a49592d0ac62db1eb9632b1e3/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99f4c65fd2fce61a571b2a6fcf747d6868db0bef8a934e8ca235cc8533944d95", size = 1494222 }, - { url = "https://files.pythonhosted.org/packages/e1/46/c9d5ee4871b187d291d62e61c41f9a4d67d4866a89704b0ad16b6949e9bd/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5392dd327a05f538c56edb1c6ebba6af91afc81b40822452342f6da54907bbdf", size = 1294171 }, - { url = "https://files.pythonhosted.org/packages/59/5e/6b64e3bf9fd4422250f3c716d992dd76dbe55e6fa1e7ebaf2bf88f389707/watchfiles-0.20.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:08dc702529bb06a2b23859110c214db245455532da5eaea602921687cfcd23db", size = 1462256 }, - { url = "https://files.pythonhosted.org/packages/11/c0/75f5a71ac24118ab11bd898e0114cedc72b25924ff2d960d473bddb4ec6e/watchfiles-0.20.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d4e66a857621584869cfbad87039e65dadd7119f0d9bb9dbc957e089e32c164", size = 1461725 }, - { url = "https://files.pythonhosted.org/packages/91/d4/0c0fdcc4293ad1b73db54896fa0de4b37439ae4f25971b5eb1708dd04f9a/watchfiles-0.20.0-cp37-abi3-win32.whl", hash = "sha256:a03d1e6feb7966b417f43c3e3783188167fd69c2063e86bad31e62c4ea794cc5", size = 268193 }, - { url = "https://files.pythonhosted.org/packages/87/79/098b1b1fcb6de16149d23283a2ab5dadce6a06b864e7a182d231f57a1f9e/watchfiles-0.20.0-cp37-abi3-win_amd64.whl", hash = "sha256:eccc8942bcdc7d638a01435d915b913255bbd66f018f1af051cd8afddb339ea3", size = 276723 }, - { url = "https://files.pythonhosted.org/packages/3f/82/45dddf4f5bf8b73ba27382cebb2bb3c0ee922c7ef77d936b86276aa39dca/watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c", size = 265344 }, -] - [[package]] name = "wcwidth" version = "0.2.13" @@ -7410,15 +5310,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, ] -[[package]] -name = "websocket-client" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, -] - [[package]] name = "websockets" version = "14.1" @@ -7479,16 +5370,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, ] -[[package]] -name = "wikipedia" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/67/35/25e68fbc99e672127cc6fbb14b8ec1ba3dfef035bf1e4c90f78f24a80b7d/wikipedia-1.4.0.tar.gz", hash = "sha256:db0fad1829fdd441b1852306e9856398204dc0786d2996dd2e0c8bb8e26133b2", size = 27748 } - [[package]] name = "win32-setctime" version = "1.2.0" @@ -7540,18 +5421,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594 }, ] -[[package]] -name = "wsproto" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c9/4a/44d3c295350d776427904d73c189e10aeae66d7f555bb2feee16d1e4ba5a/wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", size = 53425 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736", size = 24226 }, -] - [[package]] name = "xlsxwriter" version = "3.2.0" From efb8fbb660fa65949cad9436e4932c2af202ce01 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 10:11:43 -0800 Subject: [PATCH 065/110] propogate cancellation --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index fbbd69adc13e..33f0c7a5471d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -371,8 +371,8 @@ void StartCore() try { - _readTask = Task.Run(RunReadPump, CancellationToken.None); - _writeTask = Task.Run(RunWritePump, CancellationToken.None); + _readTask = Task.Run(RunReadPump, cancellationToken); + _writeTask = Task.Run(RunWritePump, cancellationToken); } finally { From 954aad2e34bf5837b9964fd3d3f3346a13c85afd Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 11:10:26 -0800 Subject: [PATCH 066/110] fix mixup in topic --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 25f51b4506d0..af87ce12d644 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -297,7 +297,10 @@ private string SetTopic(string? topic = null, string? source = null, string? key { topic = this.AgentId.Type + "." + this.AgentId.Key; } - topic = topic + "." + source + "." + key; + else + { + topic = topic + "." + source + "." + key; + } return topic; } From eaab0cd9440306d031feb3536f5e012c3f93c1f0 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 11:13:31 -0800 Subject: [PATCH 067/110] undo unexpected change --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a85b33992373..179067fe9106 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ from autogen_agentchat.teams import RoundRobinGroupChat from autogen_agentchat.ui import Console from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_ext.agents.web_surfer import MultimodalWebSurfer + async def main() -> None: model_client = OpenAIChatCompletionClient(model="gpt-4o") assistant = AssistantAgent("assistant", model_client) From ae81b19ff5765ca992d8d6c117e428fcf531a048 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 11:29:50 -0800 Subject: [PATCH 068/110] need to Connect() the worker process --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index afe95c747a93..294ffbf48eac 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -145,13 +145,13 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) _logger.LogWarning(exception, "Error removing worker from registry."); } } - internal Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + internal async Task ConnectToWorkerProcess(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) { _logger.LogInformation("Received new connection from {Peer}.", context.Peer); var workerProcess = new GrpcWorkerConnection(this, requestStream, responseStream, context); + await workerProcess.Connect().ConfigureAwait(false); _workers[workerProcess] = workerProcess; _workersByConnection[context.Peer] = workerProcess; - return workerProcess.Completion; } internal async Task SendMessageAsync(GrpcWorkerConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { From 17618c08a7016e0b59c338425b2bc36b044aed98 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 11:51:14 -0800 Subject: [PATCH 069/110] TryGetValue instead of index --- .../Services/Orleans/RegistryGrain.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index c3fbd58dbd43..3145b8f6b87d 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -22,11 +22,22 @@ public override Task OnActivateAsync(CancellationToken cancellationToken) public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) { // get all agent types that are subscribed to the topic - var subscribedAgents = state.State.TopicToAgentTypesMap[topic]; - // get all agent types that are handling the event - var handlingAgents = state.State.EventsToAgentTypesMap[eventType]; - // return the intersection of the two sets - return new(subscribedAgents.Intersect(handlingAgents).ToList()); + if(state.State.TopicToAgentTypesMap.TryGetValue(topic, out var subscribedAgentTypes)) + { + // get all agent types that are handling the event + if(state.State.EventsToAgentTypesMap.TryGetValue(eventType, out var handlingAgents)) + { + // return the intersection of the two sets + return new(subscribedAgentTypes.Intersect(handlingAgents).ToList()); + } + else + { + return new(); + } + } else + { + return new(); + } } public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) { From 6c8bcb01135746cbfebd2188bfcd7a6c6e841ff9 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 12:34:15 -0800 Subject: [PATCH 070/110] remove incorrect test, fix some null values, ensure subject/source is set correctly --- .../Core.Grpc/GrpcAgentWorker.cs | 9 +++++++-- .../Core/MessageExtensions.cs | 9 ++++++++- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 3 ++- .../AgentGrpcTests.cs | 20 ------------------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 33f0c7a5471d..c63c4efc2c8c 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -96,7 +96,12 @@ private async Task RunReadPump() } foreach (var a in agents) { - var agent = GetOrActivateAgent(new AgentId { Type = a.Name, Key = item.GetSubject() }); + var subject = item.GetSubject(); + if (string.IsNullOrEmpty(subject)) + { + subject = item.Source; + } + var agent = GetOrActivateAgent(new AgentId { Type = a.Name, Key = subject }); agent.ReceiveMessage(message); } break; @@ -191,7 +196,7 @@ private Agent GetOrActivateAgent(AgentId agentId) { if (_agentTypes.TryGetValue(agentId.Type, out var agentType)) { - agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType, this); + agent = (Agent)ActivatorUtilities.CreateInstance(ServiceProvider, agentType); Agent.Initialize(this, agent); _agents.TryAdd((agentId.Type, agentId.Key), agent); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs index 5ac9d43cf092..e5fbb4c99025 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs @@ -55,7 +55,14 @@ public static CloudEvent ToCloudEvent(this T message, string key, string topi /// public static string GetSubject(this CloudEvent cloudEvent) { - return cloudEvent.Attributes["subject"].CeString; + if(cloudEvent.Attributes.TryGetValue("subject", out var value)) + { + return value.CeString; + } + else + { + return string.Empty; + } } /// diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 294ffbf48eac..c2257cbc2b08 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -216,7 +216,8 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) var registry = _clusterClient.GetGrain(0); //intentionally blocking var targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); - if (targetAgentTypes.Count == 0) + //verify targetAgentTypes is not null + if (targetAgentTypes is null || targetAgentTypes.Count == 0) { _logger.LogWarning("No agents found registered for event {Event}.", evt); } diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 6fd2d495d7a8..9a9b16669330 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -153,26 +153,6 @@ public async Task InvokeCorrectHandler() agent.ReceivedItems[1].Should().Be(42); } - [Fact] - public async Task DelegateMessageToTestAgentAsync() - { - var client = _fixture.Client.Services.GetRequiredService(); - await client.PublishMessageAsync(new TextMessage() - { - Source = nameof(DelegateMessageToTestAgentAsync), - TextMessage_ = "buffer" - }, token: CancellationToken.None); - - // wait for 10 seconds - var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); - while (!TestAgent.ReceivedMessages.ContainsKey(nameof(DelegateMessageToTestAgentAsync)) && !cts.Token.IsCancellationRequested) - { - await Task.Delay(100); - } - - TestAgent.ReceivedMessages[nameof(DelegateMessageToTestAgentAsync)].Should().NotBeNull(); - } - /// /// The test agent is a simple agent that is used for testing purposes. /// From 9f78691c409dc54e068d48c256ffd80dead4550c Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 12:40:08 -0800 Subject: [PATCH 071/110] format --- dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs | 2 +- .../Runtime.Grpc/Services/Orleans/RegistryGrain.cs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs index e5fbb4c99025..7e2260d313a2 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/MessageExtensions.cs @@ -55,7 +55,7 @@ public static CloudEvent ToCloudEvent(this T message, string key, string topi /// public static string GetSubject(this CloudEvent cloudEvent) { - if(cloudEvent.Attributes.TryGetValue("subject", out var value)) + if (cloudEvent.Attributes.TryGetValue("subject", out var value)) { return value.CeString; } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 3145b8f6b87d..5dce2b5ef649 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -22,10 +22,10 @@ public override Task OnActivateAsync(CancellationToken cancellationToken) public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) { // get all agent types that are subscribed to the topic - if(state.State.TopicToAgentTypesMap.TryGetValue(topic, out var subscribedAgentTypes)) + if (state.State.TopicToAgentTypesMap.TryGetValue(topic, out var subscribedAgentTypes)) { // get all agent types that are handling the event - if(state.State.EventsToAgentTypesMap.TryGetValue(eventType, out var handlingAgents)) + if (state.State.EventsToAgentTypesMap.TryGetValue(eventType, out var handlingAgents)) { // return the intersection of the two sets return new(subscribedAgentTypes.Intersect(handlingAgents).ToList()); @@ -34,7 +34,8 @@ public ValueTask> GetSubscribedAndHandlingAgents(string topic, stri { return new(); } - } else + } + else { return new(); } From bfaf6f1b3cf4b1d51950feae045612b2eead90e1 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 13:07:33 -0800 Subject: [PATCH 072/110] keep alive ping scenarios always --- .../Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index e91f7ee28752..c22a2b551806 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -28,7 +28,7 @@ public static IHostApplicationBuilder AddGrpcAgentWorker(this IHostApplicationBu EnableMultipleHttp2Connections = true, KeepAlivePingDelay = TimeSpan.FromSeconds(20), KeepAlivePingTimeout = TimeSpan.FromSeconds(10), - KeepAlivePingPolicy = HttpKeepAlivePingPolicy.WithActiveRequests + KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always }; var methodConfig = new MethodConfig From 8109d339c1b8a3261b60c220388c1ec955e9830a Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 14:02:12 -0800 Subject: [PATCH 073/110] package name was wrong --- dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index c63c4efc2c8c..79e7c57042cd 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -10,7 +10,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -namespace Microsoft.AutoGen.Core; +namespace Microsoft.AutoGen.Core.Grpc; public sealed class GrpcAgentWorker( AgentRpc.AgentRpcClient client, From e2264965c56af73f4fb319b0a32f66a10011a26c Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 14:12:54 -0800 Subject: [PATCH 074/110] accidentally changed uv.lock --- python/uv.lock | 2307 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 2219 insertions(+), 88 deletions(-) diff --git a/python/uv.lock b/python/uv.lock index 84bfac995e61..e8a07804e93d 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -1,42 +1,18 @@ version = 1 requires-python = ">=3.10, <3.13" resolution-markers = [ - "python_full_version >= '3.12.4' and platform_system == 'Darwin' and sys_platform == 'darwin'", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", - "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version >= '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system == 'Darwin' and sys_platform == 'darwin'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", - "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", - "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12.4' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", - "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", - "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", - "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and platform_system == 'Darwin' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version == '3.11.*' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version == '3.11.*' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version == '3.11.*' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", - "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version == '3.11.*' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version < '3.11' and platform_system == 'Darwin' and sys_platform == 'darwin'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'darwin'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'darwin')", - "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Darwin' and sys_platform == 'linux'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform == 'linux'", - "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform == 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system == 'Darwin' and sys_platform != 'darwin') or (python_full_version < '3.11' and platform_system == 'Darwin' and sys_platform != 'darwin' and sys_platform != 'linux')", - "python_full_version < '3.11' and platform_machine == 'aarch64' and platform_system == 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux'", - "(python_full_version < '3.11' and platform_machine != 'aarch64' and platform_system != 'Darwin' and sys_platform != 'darwin') or (python_full_version < '3.11' and platform_system != 'Darwin' and platform_system != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version >= '3.12.4' and sys_platform == 'darwin'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and sys_platform == 'darwin'", + "python_full_version >= '3.12.4' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version >= '3.12.4' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12.4' and sys_platform != 'darwin' and sys_platform != 'linux')", + "(python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version >= '3.12' and python_full_version < '3.12.4' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", + "python_full_version < '3.11' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", ] [manifest] @@ -58,6 +34,29 @@ overrides = [ { name = "tenacity", specifier = ">=9.0.0" }, ] +[manifest.dependency-groups] +dev = [ + { name = "chainlit" }, + { name = "cookiecutter" }, + { name = "grpcio-tools", specifier = "~=1.62.0" }, + { name = "mypy", specifier = "==1.13.0" }, + { name = "mypy-protobuf" }, + { name = "packaging" }, + { name = "poethepoet" }, + { name = "polars" }, + { name = "pyright", specifier = "==1.1.389" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "pytest-mock" }, + { name = "pytest-xdist" }, + { name = "rich" }, + { name = "ruff", specifier = "==0.4.8" }, + { name = "tomli" }, + { name = "tomli-w" }, + { name = "typer" }, +] + [[package]] name = "accelerate" version = "1.3.0" @@ -76,6 +75,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/de/64508cb91af013aaba214752309c0967568a4219d50a4ea30e822af3c976/accelerate-1.3.0-py3-none-any.whl", hash = "sha256:5788d9e6a7a9f80fed665cf09681c4dddd9dc056bea656db4140ffc285ce423e", size = 336647 }, ] +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903 }, +] + [[package]] name = "agbench" version = "0.0.1a1" @@ -90,6 +101,12 @@ dependencies = [ { name = "tabulate" }, ] +[package.dev-dependencies] +dev = [ + { name = "types-docker" }, + { name = "types-tabulate" }, +] + [package.metadata] requires-dist = [ { name = "azure-identity" }, @@ -101,6 +118,12 @@ requires-dist = [ { name = "tabulate" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "types-docker" }, + { name = "types-tabulate" }, +] + [[package]] name = "aiofiles" version = "24.1.0" @@ -126,7 +149,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, - { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, @@ -182,6 +205,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/23/cc36d9c398980acaeeb443100f0216f50a7cfe20c67a9fd0a2f1a5a846de/aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", size = 437666 }, ] +[[package]] +name = "aiohttp-jinja2" +version = "1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "jinja2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e6/39/da5a94dd89b1af7241fb7fc99ae4e73505b5f898b540b6aba6dc7afe600e/aiohttp-jinja2-1.6.tar.gz", hash = "sha256:a3a7ff5264e5bca52e8ae547bbfd0761b72495230d438d05b6c0915be619b0e2", size = 53057 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/90/65238d4246307195411b87a07d03539049819b022c01bcc773826f600138/aiohttp_jinja2-1.6-py3-none-any.whl", hash = "sha256:0df405ee6ad1b58e5a068a105407dc7dcc1704544c559f1938babde954f945c7", size = 11736 }, +] + [[package]] name = "aiolimiter" version = "1.2.1" @@ -203,6 +239,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 }, ] +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929 }, +] + [[package]] name = "alembic" version = "1.14.0" @@ -280,6 +325,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, ] +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, +] + [[package]] name = "asttokens" version = "2.4.1" @@ -296,11 +354,51 @@ wheels = [ name = "async-timeout" version = "4.0.3" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11' and sys_platform == 'darwin'", + "python_full_version < '3.11' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version < '3.11' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux')", +] sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, ] +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.11.*' and sys_platform == 'darwin'", + "python_full_version == '3.11.*' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "(python_full_version == '3.11.*' and platform_machine != 'aarch64' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux')", +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233 }, +] + +[[package]] +name = "asyncer" +version = "0.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/39/29/245ba9fa5769a1e3226c1157aedb372fe9dab28c4e1dcf6911d84d3a5e04/asyncer-0.0.7.tar.gz", hash = "sha256:d5e563fb0f56eb87b97257984703658a4f5bbdb52ff851b3e8ed864cc200b1d2", size = 14437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/4b/40a1dc52fc26695b1e80a9e67dfb0fe7e6ddc57bbc5b61348e40c0045abb/asyncer-0.0.7-py3-none-any.whl", hash = "sha256:f0d579d4f67c4ead52ede3a45c854f462cae569058a8a6a68a4ebccac1c335d8", size = 8476 }, +] + +[[package]] +name = "asyncio-atexit" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/d3/dd2974be3f67c7ec96e0d6ab454429d0372cb7c7bffa3d0ac67a483cb801/asyncio-atexit-1.0.1.tar.gz", hash = "sha256:1d0c71544b8ee2c484d322844ee72c0875dde6f250c0ed5b6993592ab9f7d436", size = 4373 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/10/d6abaefa57a52646651fd0383c056280b0853c0106229ece6bb38cd14463/asyncio_atexit-1.0.1-py3-none-any.whl", hash = "sha256:d93d5f7d5633a534abd521ce2896ed0fbe8de170bb1e65ec871d1c20eac9d376", size = 3752 }, +] + [[package]] name = "attrs" version = "24.3.0" @@ -310,6 +408,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 }, ] +[[package]] +name = "autodoc-pydantic" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "sphinx" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/df/87120e2195f08d760bc5cf8a31cfa2381a6887517aa89453b23f1ae3354f/autodoc_pydantic-2.2.0-py3-none-any.whl", hash = "sha256:8c6a36fbf6ed2700ea9c6d21ea76ad541b621fbdf16b5a80ee04673548af4d95", size = 34001 }, +] + [[package]] name = "autogen-agentchat" version = "0.4.3" @@ -334,6 +445,54 @@ dependencies = [ { name = "typing-extensions" }, ] +[package.dev-dependencies] +dev = [ + { name = "aiofiles" }, + { name = "asyncio-atexit" }, + { name = "autodoc-pydantic" }, + { name = "autogen-ext" }, + { name = "autogen-test-utils" }, + { name = "azure-identity" }, + { name = "chess" }, + { name = "colorama" }, + { name = "diskcache" }, + { name = "langchain-openai" }, + { name = "langgraph" }, + { name = "llama-index" }, + { name = "llama-index-embeddings-azure-openai" }, + { name = "llama-index-llms-azure-openai" }, + { name = "llama-index-readers-web" }, + { name = "llama-index-readers-wikipedia" }, + { name = "llama-index-tools-wikipedia" }, + { name = "markdownify" }, + { name = "myst-nb" }, + { name = "nbqa" }, + { name = "opentelemetry-sdk" }, + { name = "pip" }, + { name = "polars" }, + { name = "pydata-sphinx-theme" }, + { name = "pygments" }, + { name = "python-dotenv" }, + { name = "redis" }, + { name = "requests" }, + { name = "sphinx" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinxcontrib-apidoc" }, + { name = "sphinxext-rediraffe" }, + { name = "tavily-python" }, + { name = "textual" }, + { name = "textual-dev" }, + { name = "textual-imageview" }, + { name = "types-aiofiles" }, + { name = "types-docker" }, + { name = "types-pillow" }, + { name = "types-protobuf" }, + { name = "types-requests" }, + { name = "wikipedia" }, +] + [package.metadata] requires-dist = [ { name = "jsonref", specifier = "~=1.1.0" }, @@ -344,6 +503,54 @@ requires-dist = [ { name = "typing-extensions", specifier = ">=4.0.0" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "aiofiles" }, + { name = "asyncio-atexit" }, + { name = "autodoc-pydantic", specifier = "~=2.2" }, + { name = "autogen-ext", editable = "packages/autogen-ext" }, + { name = "autogen-test-utils", editable = "packages/autogen-test-utils" }, + { name = "azure-identity" }, + { name = "chess" }, + { name = "colorama" }, + { name = "diskcache" }, + { name = "langchain-openai" }, + { name = "langgraph" }, + { name = "llama-index" }, + { name = "llama-index-embeddings-azure-openai" }, + { name = "llama-index-llms-azure-openai" }, + { name = "llama-index-readers-web" }, + { name = "llama-index-readers-wikipedia" }, + { name = "llama-index-tools-wikipedia" }, + { name = "markdownify" }, + { name = "myst-nb", specifier = "==1.1.2" }, + { name = "nbqa" }, + { name = "opentelemetry-sdk", specifier = ">=1.27.0" }, + { name = "pip" }, + { name = "polars" }, + { name = "pydata-sphinx-theme", specifier = "==0.15.4" }, + { name = "pygments" }, + { name = "python-dotenv" }, + { name = "redis" }, + { name = "requests" }, + { name = "sphinx" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinxcontrib-apidoc" }, + { name = "sphinxext-rediraffe" }, + { name = "tavily-python" }, + { name = "textual" }, + { name = "textual-dev" }, + { name = "textual-imageview" }, + { name = "types-aiofiles" }, + { name = "types-docker" }, + { name = "types-pillow" }, + { name = "types-protobuf" }, + { name = "types-requests" }, + { name = "wikipedia" }, +] + [[package]] name = "autogen-ext" version = "0.4.3" @@ -440,6 +647,13 @@ web-surfer = [ { name = "playwright" }, ] +[package.dev-dependencies] +dev = [ + { name = "autogen-test-utils" }, + { name = "langchain-experimental" }, + { name = "pandas-stubs" }, +] + [package.metadata] requires-dist = [ { name = "aiofiles", marker = "extra == 'openai'" }, @@ -483,6 +697,13 @@ requires-dist = [ { name = "tiktoken", marker = "extra == 'openai'", specifier = ">=0.8.0" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "autogen-test-utils", editable = "packages/autogen-test-utils" }, + { name = "langchain-experimental" }, + { name = "pandas-stubs", specifier = ">=2.2.3.241126" }, +] + [[package]] name = "autogen-magentic-one" version = "0.0.1" @@ -509,6 +730,16 @@ dependencies = [ { name = "youtube-transcript-api" }, ] +[package.dev-dependencies] +dev = [ + { name = "aiofiles" }, + { name = "azure-identity" }, + { name = "openpyxl" }, + { name = "types-aiofiles" }, + { name = "types-pillow" }, + { name = "types-requests" }, +] + [package.metadata] requires-dist = [ { name = "aiofiles" }, @@ -532,6 +763,16 @@ requires-dist = [ { name = "youtube-transcript-api" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "aiofiles" }, + { name = "azure-identity" }, + { name = "openpyxl" }, + { name = "types-aiofiles" }, + { name = "types-pillow" }, + { name = "types-requests" }, +] + [[package]] name = "autogen-test-utils" version = "0.0.0" @@ -620,6 +861,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6d/90/d13cf396989052cadd8511c1878b0913bbce28eeef5feb95710a92e03076/autograd-1.7.0-py3-none-any.whl", hash = "sha256:49680300f842f3a8722b060ac0d3ed7aca071d1ad4d3d38c9fdadafdcc73c30b", size = 52522 }, ] +[[package]] +name = "autopep8" +version = "2.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycodestyle" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/d8/30873d2b7b57dee9263e53d142da044c4600a46f2d28374b3e38b023df16/autopep8-2.3.2.tar.gz", hash = "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", size = 92210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/43/53afb8ba17218f19b77c7834128566c5bbb100a0ad9ba2e8e89d089d7079/autopep8-2.3.2-py2.py3-none-any.whl", hash = "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128", size = 45807 }, +] + [[package]] name = "azure-common" version = "1.1.28" @@ -702,6 +956,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e2/f8/ef0f76f8c424bedd20c685409836ddfb42ac76fd8a0f21c3c3659cf7207d/azure_storage_blob-12.24.0-py3-none-any.whl", hash = "sha256:4f0bb4592ea79a2d986063696514c781c9e62be240f09f6397986e01755bc071", size = 408579 }, ] +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + [[package]] name = "beartype" version = "0.18.5" @@ -723,6 +986,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, ] +[[package]] +name = "bidict" +version = "0.23.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/6e/026678aa5a830e07cd9498a05d3e7e650a4f56a42f267a53d22bcda1bdc9/bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71", size = 29093 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/37/e8730c3587a65eb5645d4aba2d27aae48e8003614d6aaf15dda67f702f1f/bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5", size = 32764 }, +] + +[[package]] +name = "binaryornot" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "chardet" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/fe/7ebfec74d49f97fc55cd38240c7a7d08134002b1e14be8c3897c0dd5e49b/binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061", size = 371054 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/7e/f7b6f453e6481d1e233540262ccbfcf89adcd43606f44a028d7f5fae5eb2/binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4", size = 9006 }, +] + [[package]] name = "blinker" version = "1.9.0" @@ -824,6 +1108,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, ] +[[package]] +name = "chainlit" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiofiles" }, + { name = "asyncer" }, + { name = "click" }, + { name = "dataclasses-json" }, + { name = "fastapi" }, + { name = "filetype" }, + { name = "httpx" }, + { name = "lazify" }, + { name = "literalai" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "pydantic" }, + { name = "pyjwt" }, + { name = "python-dotenv" }, + { name = "python-multipart" }, + { name = "python-socketio" }, + { name = "starlette" }, + { name = "syncer" }, + { name = "tomli" }, + { name = "uptrace" }, + { name = "uvicorn" }, + { name = "watchfiles" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/15/26dc5f957c6344813b2ae8c6f52cc820a7074088509ea947da0cf76ffc5f/chainlit-2.0.1.tar.gz", hash = "sha256:9fb7728aa5704e823c5b5d51f570dcfabafdcc97c23a73e6047f65eb72c938e7", size = 4637433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/99/c63fa2e1d7b949c034b7fc838a0c00de22cd2cec30245e379c9dd15dedfd/chainlit-2.0.1-py3-none-any.whl", hash = "sha256:84982902c6f42a91ac341ea9b6d52e6b1348e53a60ee49b4ffe0e5e5be02f4ba", size = 4703745 }, +] + [[package]] name = "chardet" version = "5.2.0" @@ -881,12 +1198,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, ] +[[package]] +name = "chess" +version = "1.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/16/53b895bb4fccede8e506de820fa94db03a2dc8bd2ca4bec0aac4a112fb65/chess-1.11.1.tar.gz", hash = "sha256:b7f66a32dc599ab260e2b688e6ac4e868dad840377a54b61357e2dec2a5fed00", size = 156529 } + +[[package]] +name = "chevron" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/1f/ca74b65b19798895d63a6e92874162f44233467c9e7c1ed8afd19016ebe9/chevron-0.14.0.tar.gz", hash = "sha256:87613aafdf6d77b6a90ff073165a61ae5086e21ad49057aa0e53681601800ebf", size = 11440 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/93/342cc62a70ab727e093ed98e02a725d85b746345f05d2b5e5034649f4ec8/chevron-0.14.0-py3-none-any.whl", hash = "sha256:fbf996a709f8da2e745ef763f482ce2d311aa817d287593a5b990d6d6e4f0443", size = 11595 }, +] + +[[package]] +name = "chromedriver-autoinstaller" +version = "0.6.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/5a/9fc60c65673444d592b8922316c3abcd6177b42208c5a6179f96ccf0e11b/chromedriver-autoinstaller-0.6.4.tar.gz", hash = "sha256:1b4df04b87e6107c730085b98e5fd541db3d1777c32b8bd08e2ca4b1244050af", size = 6944 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/b5/36f0b0add145c371b5282e881a687601899f2d27fae5d0595bc02026b67c/chromedriver_autoinstaller-0.6.4-py3-none-any.whl", hash = "sha256:b12ed187ca9fac4d744deb588d221222ed50836384607e5303e6eab98bb9dc64", size = 7634 }, +] + [[package]] name = "click" version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } wheels = [ @@ -1006,6 +1350,69 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/94/86bfae441707205634d80392e873295652fc313dfd93c233c52c4dc07874/contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53", size = 218221 }, ] +[[package]] +name = "cookiecutter" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, + { name = "binaryornot" }, + { name = "click" }, + { name = "jinja2" }, + { name = "python-slugify" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/17/9f2cd228eb949a91915acd38d3eecdc9d8893dde353b603f0db7e9f6be55/cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c", size = 158767 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/d9/0137658a353168ffa9d0fc14b812d3834772040858ddd1cb6eeaf09f7a44/cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d", size = 39177 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + [[package]] name = "cryptography" version = "44.0.0" @@ -1043,6 +1450,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/9d/37e5da7519de7b0b070a3fedd4230fe76d50d2a21403e0f2153d70ac4163/cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", size = 3128774 }, ] +[[package]] +name = "cssselect" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/91/d51202cc41fbfca7fa332f43a5adac4b253962588c7cc5a54824b019081c/cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", size = 41423 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/a9/2da08717a6862c48f1d61ef957a7bba171e7eefa6c0aa0ceb96a140c2a6b/cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e", size = 18687 }, +] + [[package]] name = "cycler" version = "0.12.1" @@ -1083,6 +1499,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/aa/3f/94cff4e36962b843a78a831770b9b44e476a5f9c76c0d53f7cf92053a1b4/dapr_ext_fastapi-1.14.0-py3-none-any.whl", hash = "sha256:88df67d6af33fd5adcf97d8799fa43373774b13cb9a1091ac4dd47e18a009ca0", size = 10458 }, ] +[[package]] +name = "dataclasses-json" +version = "0.6.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "marshmallow" }, + { name = "typing-inspect" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/64/a4/f71d9cf3a5ac257c993b5ca3f93df5f7fb395c725e7f1e6479d2514173c3/dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0", size = 32227 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/be/d0d44e092656fe7a06b55e6103cbce807cdbdee17884a5367c68c9860853/dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a", size = 28686 }, +] + [[package]] name = "debugpy" version = "1.8.11" @@ -1160,6 +1589,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/ae/afb1487556e2dc827a17097aac8158a25b433a345386f0e249f6d2694ccb/devtools-0.12.2-py3-none-any.whl", hash = "sha256:c366e3de1df4cdd635f1ad8cbcd3af01a384d7abda71900e68d43b04eb6aaca7", size = 19411 }, ] +[[package]] +name = "dirtyjson" +version = "1.0.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/04/d24f6e645ad82ba0ef092fa17d9ef7a21953781663648a01c9371d9e8e98/dirtyjson-1.0.8.tar.gz", hash = "sha256:90ca4a18f3ff30ce849d100dcf4a003953c79d3a2348ef056f1d9c22231a25fd", size = 30782 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/69/1bcf70f81de1b4a9f21b3a62ec0c83bdff991c88d6cc2267d02408457e88/dirtyjson-1.0.8-py3-none-any.whl", hash = "sha256:125e27248435a58acace26d5c2c4c11a1c0de0a9c5124c5a94ba78e517d74f53", size = 25197 }, +] + [[package]] name = "diskcache" version = "5.6.3" @@ -1201,6 +1639,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533 }, ] +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, +] + [[package]] name = "environs" version = "11.2.1" @@ -1241,6 +1688,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, ] +[[package]] +name = "execnet" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 }, +] + [[package]] name = "executing" version = "2.1.0" @@ -1273,6 +1729,29 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924 }, ] +[[package]] +name = "feedfinder2" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "requests" }, + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/35/82/1251fefec3bb4b03fd966c7e7f7a41c9fc2bb00d823a34c13f847fd61406/feedfinder2-0.0.4.tar.gz", hash = "sha256:3701ee01a6c85f8b865a049c30ba0b4608858c803fe8e30d1d289fdbe89d0efe", size = 3297 } + +[[package]] +name = "feedparser" +version = "6.0.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sgmllib3k" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/aa/7af346ebeb42a76bf108027fe7f3328bb4e57a3a96e53e21fd9ef9dd6dd0/feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5", size = 286197 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/d4/8c31aad9cc18f451c49f7f9cfb5799dadffc88177f7917bc90a66459b1d7/feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45", size = 81343 }, +] + [[package]] name = "ffmpeg-python" version = "0.2.0" @@ -1294,6 +1773,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, ] +[[package]] +name = "filetype" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/29/745f7d30d47fe0f251d3ad3dc2978a23141917661998763bebb6da007eb1/filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb", size = 998020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/79/1b8fa1bb3568781e84c9200f951c735f3f157429f44be0495da55894d620/filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25", size = 19970 }, +] + [[package]] name = "flask" version = "3.1.0" @@ -1897,6 +2385,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/90/40/972271de05f9315c0d69f9f7ebbcadd83bc85322f538637d11bb8c67803d/grpcio_status-1.62.3-py3-none-any.whl", hash = "sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8", size = 14448 }, ] +[[package]] +name = "grpcio-tools" +version = "1.62.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "grpcio" }, + { name = "protobuf" }, + { name = "setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/fa/b69bd8040eafc09b88bb0ec0fea59e8aacd1a801e688af087cead213b0d0/grpcio-tools-1.62.3.tar.gz", hash = "sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833", size = 4538520 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/eb/eb0a3aa9480c3689d31fd2ad536df6a828e97a60f667c8a93d05bdf07150/grpcio_tools-1.62.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1", size = 5117556 }, + { url = "https://files.pythonhosted.org/packages/f3/fb/8be3dda485f7fab906bfa02db321c3ecef953a87cdb5f6572ca08b187bcb/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e", size = 2719330 }, + { url = "https://files.pythonhosted.org/packages/63/de/6978f8d10066e240141cd63d1fbfc92818d96bb53427074f47a8eda921e1/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26", size = 3070818 }, + { url = "https://files.pythonhosted.org/packages/74/34/bb8f816893fc73fd6d830e895e8638d65d13642bb7a434f9175c5ca7da11/grpcio_tools-1.62.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667", size = 2804993 }, + { url = "https://files.pythonhosted.org/packages/78/60/b2198d7db83293cdb9760fc083f077c73e4c182da06433b3b157a1567d06/grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193", size = 3684915 }, + { url = "https://files.pythonhosted.org/packages/61/20/56dbdc4ecb14d42a03cd164ff45e6e84572bbe61ee59c50c39f4d556a8d5/grpcio_tools-1.62.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9", size = 3297482 }, + { url = "https://files.pythonhosted.org/packages/4a/dc/e417a313c905744ce8cedf1e1edd81c41dc45ff400ae1c45080e18f26712/grpcio_tools-1.62.3-cp310-cp310-win32.whl", hash = "sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5", size = 909793 }, + { url = "https://files.pythonhosted.org/packages/d9/69/75e7ebfd8d755d3e7be5c6d1aa6d13220f5bba3a98965e4b50c329046777/grpcio_tools-1.62.3-cp310-cp310-win_amd64.whl", hash = "sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d", size = 1052459 }, + { url = "https://files.pythonhosted.org/packages/23/52/2dfe0a46b63f5ebcd976570aa5fc62f793d5a8b169e211c6a5aede72b7ae/grpcio_tools-1.62.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23", size = 5147623 }, + { url = "https://files.pythonhosted.org/packages/f0/2e/29fdc6c034e058482e054b4a3c2432f84ff2e2765c1342d4f0aa8a5c5b9a/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492", size = 2719538 }, + { url = "https://files.pythonhosted.org/packages/f9/60/abe5deba32d9ec2c76cdf1a2f34e404c50787074a2fee6169568986273f1/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7", size = 3070964 }, + { url = "https://files.pythonhosted.org/packages/bc/ad/e2b066684c75f8d9a48508cde080a3a36618064b9cadac16d019ca511444/grpcio_tools-1.62.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43", size = 2805003 }, + { url = "https://files.pythonhosted.org/packages/9c/3f/59bf7af786eae3f9d24ee05ce75318b87f541d0950190ecb5ffb776a1a58/grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a", size = 3685154 }, + { url = "https://files.pythonhosted.org/packages/f1/79/4dd62478b91e27084c67b35a2316ce8a967bd8b6cb8d6ed6c86c3a0df7cb/grpcio_tools-1.62.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3", size = 3297942 }, + { url = "https://files.pythonhosted.org/packages/b8/cb/86449ecc58bea056b52c0b891f26977afc8c4464d88c738f9648da941a75/grpcio_tools-1.62.3-cp311-cp311-win32.whl", hash = "sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5", size = 910231 }, + { url = "https://files.pythonhosted.org/packages/45/a4/9736215e3945c30ab6843280b0c6e1bff502910156ea2414cd77fbf1738c/grpcio_tools-1.62.3-cp311-cp311-win_amd64.whl", hash = "sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f", size = 1052496 }, + { url = "https://files.pythonhosted.org/packages/2a/a5/d6887eba415ce318ae5005e8dfac3fa74892400b54b6d37b79e8b4f14f5e/grpcio_tools-1.62.3-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5", size = 5147690 }, + { url = "https://files.pythonhosted.org/packages/8a/7c/3cde447a045e83ceb4b570af8afe67ffc86896a2fe7f59594dc8e5d0a645/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133", size = 2720538 }, + { url = "https://files.pythonhosted.org/packages/88/07/f83f2750d44ac4f06c07c37395b9c1383ef5c994745f73c6bfaf767f0944/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa", size = 3071571 }, + { url = "https://files.pythonhosted.org/packages/37/74/40175897deb61e54aca716bc2e8919155b48f33aafec8043dda9592d8768/grpcio_tools-1.62.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0", size = 2806207 }, + { url = "https://files.pythonhosted.org/packages/ec/ee/d8de915105a217cbcb9084d684abdc032030dcd887277f2ef167372287fe/grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d", size = 3685815 }, + { url = "https://files.pythonhosted.org/packages/fd/d9/4360a6c12be3d7521b0b8c39e5d3801d622fbb81cc2721dbd3eee31e28c8/grpcio_tools-1.62.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc", size = 3298378 }, + { url = "https://files.pythonhosted.org/packages/29/3b/7cdf4a9e5a3e0a35a528b48b111355cd14da601413a4f887aa99b6da468f/grpcio_tools-1.62.3-cp312-cp312-win32.whl", hash = "sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b", size = 910416 }, + { url = "https://files.pythonhosted.org/packages/6c/66/dd3ec249e44c1cc15e902e783747819ed41ead1336fcba72bf841f72c6e9/grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl", hash = "sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7", size = 1052856 }, +] + [[package]] name = "h11" version = "0.14.0" @@ -1906,6 +2431,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, ] +[[package]] +name = "html2text" +version = "2024.2.26" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/43/e1d53588561e533212117750ee79ad0ba02a41f52a08c1df3396bd466c05/html2text-2024.2.26.tar.gz", hash = "sha256:05f8e367d15aaabc96415376776cdd11afd5127a77fce6e36afc60c563ca2c32", size = 56527 } + [[package]] name = "httpcore" version = "1.0.7" @@ -1947,10 +2478,19 @@ wheels = [ ] [[package]] -name = "huggingface-hub" -version = "0.27.1" +name = "httpx-sse" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ +sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, +] + +[[package]] +name = "huggingface-hub" +version = "0.27.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ { name = "filelock" }, { name = "fsspec" }, { name = "packaging" }, @@ -2000,6 +2540,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, ] +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + [[package]] name = "importlib-metadata" version = "8.4.0" @@ -2026,7 +2575,7 @@ name = "ipykernel" version = "6.29.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "appnope", marker = "platform_system == 'Darwin'" }, + { name = "appnope", marker = "sys_platform == 'darwin'" }, { name = "comm" }, { name = "debugpy" }, { name = "ipython" }, @@ -2097,6 +2646,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, ] +[[package]] +name = "jieba3k" +version = "0.35.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/cb/2c8332bcdc14d33b0bedd18ae0a4981a069c3513e445120da3c3f23a8aaa/jieba3k-0.35.1.zip", hash = "sha256:980a4f2636b778d312518066be90c7697d410dd5a472385f5afced71a2db1c10", size = 7423646 } + [[package]] name = "jinja2" version = "3.1.5" @@ -2261,6 +2816,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, ] +[[package]] +name = "jupyter-cache" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "click" }, + { name = "importlib-metadata" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "pyyaml" }, + { name = "sqlalchemy" }, + { name = "tabulate" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/f7/3627358075f183956e8c4974603232b03afd4ddc7baf72c2bc9fff522291/jupyter_cache-1.0.1.tar.gz", hash = "sha256:16e808eb19e3fb67a223db906e131ea6e01f03aa27f49a7214ce6a5fec186fb9", size = 32048 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl", hash = "sha256:9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6", size = 33907 }, +] + [[package]] name = "jupyter-client" version = "8.6.3" @@ -2371,6 +2945,51 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/34/b9/a3d4bfdaefbc9098ef18bff2cf403c6060f70894c5022983464f9c3db367/lancedb-0.17.0-cp39-abi3-win_amd64.whl", hash = "sha256:9d7e82f83f430d906c285d3303729258b21b1cc8da634c9f7017e354bcb7318a", size = 27511050 }, ] +[[package]] +name = "langchain" +version = "0.3.14" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "langchain-core" }, + { name = "langchain-text-splitters" }, + { name = "langsmith" }, + { name = "numpy" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, + { name = "tenacity" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/35/2adb0693acc149e462bc0e7856ecd58096c285f66a78bc44fc2b8ae91ce0/langchain-0.3.14.tar.gz", hash = "sha256:4a5ae817b5832fa0e1fcadc5353fbf74bebd2f8e550294d4dc039f651ddcd3d1", size = 420409 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/a8/0a8f868615b7a30636b1d15b718e3ea9875bf0dccced03583477c2372495/langchain-0.3.14-py3-none-any.whl", hash = "sha256:5df9031702f7fe6c956e84256b4639a46d5d03a75be1ca4c1bc9479b358061a2", size = 1009213 }, +] + +[[package]] +name = "langchain-community" +version = "0.3.14" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "dataclasses-json" }, + { name = "httpx-sse" }, + { name = "langchain" }, + { name = "langchain-core" }, + { name = "langsmith" }, + { name = "numpy" }, + { name = "pydantic-settings" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy" }, + { name = "tenacity" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/a32cddaa9e8c618e69cfbfdb11cb8718bd9a531ae8426f6a2125a7a5d31f/langchain_community-0.3.14.tar.gz", hash = "sha256:d8ba0fe2dbb5795bff707684b712baa5ee379227194610af415ccdfdefda0479", size = 1720031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/df/3a226f47aad50605a4ff77a30e876d7520f2060aa624532872e44ea048d8/langchain_community-0.3.14-py3-none-any.whl", hash = "sha256:cc02a0abad0551edef3e565dff643386a5b2ee45b933b6d883d4a935b9649f3c", size = 2502417 }, +] + [[package]] name = "langchain-core" version = "0.3.29" @@ -2389,6 +3008,85 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/4f/fe1de63f6fc1ac7af3ba4ae12d420af1a19f7893b5fcb72856b9fc67f650/langchain_core-0.3.29-py3-none-any.whl", hash = "sha256:817db1474871611a81105594a3e4d11704949661008e455a10e38ca9ff601a1a", size = 411593 }, ] +[[package]] +name = "langchain-experimental" +version = "0.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-community" }, + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/56/a8acbb08a03383c28875b3b151e4cefea5612266917fbd6fc3c14c21e172/langchain_experimental-0.3.4.tar.gz", hash = "sha256:937c4259ee4a639c618d19acf0e2c5c2898ef127050346edc5655259aa281a21", size = 140532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/27/fe8caa4884611286b1f7d6c5cfd76e1fef188faaa946db4fde6daa1cd2cd/langchain_experimental-0.3.4-py3-none-any.whl", hash = "sha256:2e587306aea36b60fa5e5fc05dc7281bee9f60a806f0bf9d30916e0ee096af80", size = 209154 }, +] + +[[package]] +name = "langchain-openai" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "openai" }, + { name = "tiktoken" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/0a/0711117a4e8273d5edd4899399a8597d848b2d7b3c9ba3be97038b4fbc1a/langchain_openai-0.3.0.tar.gz", hash = "sha256:88d623eeb2aaa1fff65c2b419a4a1cfd37d3a1d504e598b87cf0bc822a3b70d0", size = 48067 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/9c/b38e308ac668f6db067b424a2a78e5b865753c144a119456f008a09230db/langchain_openai-0.3.0-py3-none-any.whl", hash = "sha256:49c921a22d272b04749a61e78bffa83aecdb8840b24b69f2909e115a357a9a5b", size = 54218 }, +] + +[[package]] +name = "langchain-text-splitters" +version = "0.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/35/a6f8d6b1bb0e6e8c00b49bce4d1a115f8b68368b1899f65bb34dbbb44160/langchain_text_splitters-0.3.5.tar.gz", hash = "sha256:11cb7ca3694e5bdd342bc16d3875b7f7381651d4a53cbb91d34f22412ae16443", size = 26318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/83/f8081c3bea416bd9d9f0c26af795c74f42c24f9ad3c4fbf361b7d69de134/langchain_text_splitters-0.3.5-py3-none-any.whl", hash = "sha256:8c9b059827438c5fa8f327b4df857e307828a5ec815163c9b5c9569a3e82c8ee", size = 31620 }, +] + +[[package]] +name = "langgraph" +version = "0.2.62" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, + { name = "langgraph-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/bb/23859e3c219944bc9f1f3093629970631b3a6dc0aeaf607d7d205b2b551e/langgraph-0.2.62.tar.gz", hash = "sha256:0aac9fd55ffe669bc1312203e0f9ea2733c65cc276f196e7ff0d443cf4efbb89", size = 119343 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/38/571f8bc14d4ced8e9d86aca657ffd9a6d076e32e2a62d487eab15f2ceca7/langgraph-0.2.62-py3-none-any.whl", hash = "sha256:51ae9e02a52485a837642eebe7ae43269af7d7305d62f8f69ac11589b2fbba26", size = 138170 }, +] + +[[package]] +name = "langgraph-checkpoint" +version = "2.0.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "msgpack" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/26/96/378e06c60d8c8cf44e1d6a2b669e9d5d87236bdee6bf7cfc9125ef5b5d0e/langgraph_checkpoint-2.0.10.tar.gz", hash = "sha256:2dcc04e09091d588bb6209e49d83ff5406d7231c2590d6ff18fb29ab8b140129", size = 33431 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/ef/c320b52035e29081f2693377602289a00545016b4adcc963d5e202ac0c92/langgraph_checkpoint-2.0.10-py3-none-any.whl", hash = "sha256:0d592cfda2df93844c6ea44d142170a8f7e5ba5320274e0e5e60e27f2749392c", size = 37476 }, +] + +[[package]] +name = "langgraph-sdk" +version = "0.1.51" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/32/d1/95ae599428e8e7d90229e402adf3056072f2ebd0c45c7f7154a5243ff35a/langgraph_sdk-0.1.51.tar.gz", hash = "sha256:dea1363e72562cb1e82a2d156be8d5b1a69ff3fe8815eee0e1e7a2f423242ec1", size = 41591 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/e9/d5d2ea883ddb3e16d4c18213457b3f3d04380089d410db71faae52a3c34a/langgraph_sdk-0.1.51-py3-none-any.whl", hash = "sha256:ce2b58466d1700d06149782ed113157a8694a6d7932c801f316cd13fab315fe4", size = 44652 }, +] + [[package]] name = "langsmith" version = "0.2.10" @@ -2405,6 +3103,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/91/e72d13f6b57a0ea9d884ab1d3388f544d7fe3354dbe1d4dd67678693a9fd/langsmith-0.2.10-py3-none-any.whl", hash = "sha256:b02f2f174189ff72e54c88b1aa63343defd6f0f676c396a690c63a4b6495dcc2", size = 326432 }, ] +[[package]] +name = "lazify" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/2c/b55c4a27a56dd9a00bb2812c404b57f8b7aec0cdbff9fdc61acdd73359bc/Lazify-0.4.0.tar.gz", hash = "sha256:7102bfe63e56de2ab62b3bc661a7190c4056771a8624f04a8b785275c3dd1f9b", size = 2968 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/a5/866b44697cee47d1cae429ed370281d937ad4439f71af82a6baaa139d26a/Lazify-0.4.0-py2.py3-none-any.whl", hash = "sha256:c2c17a7a33e9406897e3f66fde4cd3f84716218d580330e5af10cfe5a0cd195a", size = 3107 }, +] + [[package]] name = "lazy-object-proxy" version = "1.10.0" @@ -2435,6 +3142,327 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/8b/94dc8d58704ab87b39faed6f2fc0090b9d90e2e2aa2bbec35c79f3d2a054/lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d", size = 16405 }, ] +[[package]] +name = "linkify-it-py" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "uc-micro-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/1e/b832de447dee8b582cac175871d2f6c3d5077cc56d5575cadba1fd1cccfa/linkify_it_py-2.0.3-py3-none-any.whl", hash = "sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79", size = 19820 }, +] + +[[package]] +name = "literalai" +version = "0.0.623" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "chevron" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/af/07d943e62a1297a7b44777297c0dca8f4bfcd6ae18b9df7d3cd9c1970e29/literalai-0.0.623.tar.gz", hash = "sha256:d65c04dde6b1e99d585e4112a607e5fd574d282b70f600c55a671018340dfb0f", size = 57081 } + +[[package]] +name = "llama-cloud" +version = "0.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "httpx" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/e8/6dcc69cd624f3267e41e2077f33f98c27727a9842a5d8244ce6cf0671859/llama_cloud-0.1.8.tar.gz", hash = "sha256:7199bab2240a9cc330740003fa77648f43f6e533da411a8250a4a70584f91153", size = 90827 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/0f/af106de1780cf526c96de1ba279edcb55a0376a4484a7dea206f9f038cc4/llama_cloud-0.1.8-py3-none-any.whl", hash = "sha256:1a0c4cf212a04f2375f1d0791ca4e5f196e0fb0567c4ec96cd9dbcad773de60a", size = 247083 }, +] + +[[package]] +name = "llama-index" +version = "0.12.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-agent-openai" }, + { name = "llama-index-cli" }, + { name = "llama-index-core" }, + { name = "llama-index-embeddings-openai" }, + { name = "llama-index-indices-managed-llama-cloud" }, + { name = "llama-index-llms-openai" }, + { name = "llama-index-multi-modal-llms-openai" }, + { name = "llama-index-program-openai" }, + { name = "llama-index-question-gen-openai" }, + { name = "llama-index-readers-file" }, + { name = "llama-index-readers-llama-parse" }, + { name = "nltk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/34/7eb11a6b6fa603fa0a072c1ffaa08d337d805d09feca5235bd42664d9ec4/llama_index-0.12.11.tar.gz", hash = "sha256:b1116946a2414aec104a6c417b847da5b4f077a0966c50ebd2fc445cd713adce", size = 7781 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/72/ab8bae2072c0e7786cbe7348d5b45bfb12972dd3a1fdb5cb96c615b779f6/llama_index-0.12.11-py3-none-any.whl", hash = "sha256:007361c35e1981a1656cef287b7bcdf22aa88e7d41b8e3a8ee261bb5a10519a9", size = 6876 }, +] + +[[package]] +name = "llama-index-agent-openai" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-index-llms-openai" }, + { name = "openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/09/bb3c4d5496f2d79499ca6d323f379e2051473b56a917ed46cf4d0d2aeb05/llama_index_agent_openai-0.4.2.tar.gz", hash = "sha256:0f8aeb091fc834b2667a46ad2417fc8601bf1c08ccfd1a3d15ede90a30eb1a29", size = 10612 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/37/21bdd9adce0e358203a81f245521e829d72547e14ecd6c298ec0327218a1/llama_index_agent_openai-0.4.2-py3-none-any.whl", hash = "sha256:e100b8a743b11fef373b5be31be590b929950a4d7fd9d158b5f014dd8fd7976e", size = 13205 }, +] + +[[package]] +name = "llama-index-cli" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-index-embeddings-openai" }, + { name = "llama-index-llms-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/52/81e1448d4dcff5beb1453f397f34f9ac769b7fcdb6b7c8fbd4c20b73e836/llama_index_cli-0.4.0.tar.gz", hash = "sha256:d6ab201359962a8a34368aeda3a49bbbe67e9e009c59bd925c4fb2be4ace3906", size = 24710 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/29/2b659e5930ea44253bf99e2afc395daaa2a3edaa579d99e63ea53df03313/llama_index_cli-0.4.0-py3-none-any.whl", hash = "sha256:60d12f89e6b85e80a0cc3a8b531f05a911b5eebaebc37314411476d1ba685904", size = 27785 }, +] + +[[package]] +name = "llama-index-core" +version = "0.12.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "dataclasses-json" }, + { name = "deprecated" }, + { name = "dirtyjson" }, + { name = "filetype" }, + { name = "fsspec" }, + { name = "httpx" }, + { name = "nest-asyncio" }, + { name = "networkx" }, + { name = "nltk" }, + { name = "numpy" }, + { name = "pillow" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "sqlalchemy", extra = ["asyncio"] }, + { name = "tenacity" }, + { name = "tiktoken" }, + { name = "tqdm" }, + { name = "typing-extensions" }, + { name = "typing-inspect" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/a7/1ee40a8bcc5e7ff1dc523f2a26e217b3d7a306d4180b0654e9b4ab519c9c/llama_index_core-0.12.11.tar.gz", hash = "sha256:9a41ca91167ea5eec9ebaac7f5e958b7feddbd8af3bfbf7c393a5edfb994d566", size = 1332167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/fb/3aadbfb0a43a734857802d6c372e70470921aaef3023b5e8f39dbdc6fd94/llama_index_core-0.12.11-py3-none-any.whl", hash = "sha256:3b1e019c899e9e011dfa01c96b7e3f666e0c161035fbca6cb787b4c61e0c94db", size = 1584262 }, +] + +[[package]] +name = "llama-index-embeddings-azure-openai" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-index-embeddings-openai" }, + { name = "llama-index-llms-azure-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/db/a35c34ff7863315ac133b4ff0386913cbe9986988e7f1c076e1745dbe015/llama_index_embeddings_azure_openai-0.3.0.tar.gz", hash = "sha256:80b0cf977d8b967a08536d65b8e2d0c6c966eeaf1b8fff084e97f3081fd70c34", size = 3111 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/78/eb22765325d03008dae55f98c77053231b9344d2bef6304f3d93121f3468/llama_index_embeddings_azure_openai-0.3.0-py3-none-any.whl", hash = "sha256:2ca61d6b75468d1230cfc1151a878d892b237130b8af09b4434f8c0466d44dfe", size = 3425 }, +] + +[[package]] +name = "llama-index-embeddings-openai" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/02/a2604ef3a167131fdd701888f45f16c8efa6d523d02efe8c4e640238f4ea/llama_index_embeddings_openai-0.3.1.tar.gz", hash = "sha256:1368aad3ce24cbaed23d5ad251343cef1eb7b4a06d6563d6606d59cb347fef20", size = 5492 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/45/ca55b91c4ac1b6251d4099fa44121a6c012129822906cadcc27b8cfb33a4/llama_index_embeddings_openai-0.3.1-py3-none-any.whl", hash = "sha256:f15a3d13da9b6b21b8bd51d337197879a453d1605e625a1c6d45e741756c0290", size = 6177 }, +] + +[[package]] +name = "llama-index-indices-managed-llama-cloud" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-cloud" }, + { name = "llama-index-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/58/29afa6086e2080ae27da79949e319f77f08cb7d1b2bd26e56a676dab1338/llama_index_indices_managed_llama_cloud-0.6.3.tar.gz", hash = "sha256:f09e4182cbc2a2bd75ae85cebb1681075247f0d91b931b094cac4315386ce87a", size = 10483 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/c6/ebb53a15e63c8da3633a595f53fc965509e8c6707da6a8b1bfa9b7923236/llama_index_indices_managed_llama_cloud-0.6.3-py3-none-any.whl", hash = "sha256:7f125602f624a2d321b6a4130cd98df35eb8c15818a159390755b2c13068f4ce", size = 11077 }, +] + +[[package]] +name = "llama-index-llms-azure-openai" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "azure-identity" }, + { name = "httpx" }, + { name = "llama-index-core" }, + { name = "llama-index-llms-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/d7/21264774d0e0819d869ac2f6527fd6b405340647feb4fef7b6b59c520858/llama_index_llms_azure_openai-0.3.0.tar.gz", hash = "sha256:0feea9319d832c8b5e8e0f397c905e45df54c529b6a778825adcd0d254bd7d63", size = 5557 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/49/a90c17bddddb411e0bc2d05bcf393fb03474279fb6fbe20c98db68473d98/llama_index_llms_azure_openai-0.3.0-py3-none-any.whl", hash = "sha256:24091aedf7ba24a7b217d17c4358e62b5d6b43a4d3ca44750d442b02a440d26e", size = 6306 }, +] + +[[package]] +name = "llama-index-llms-openai" +version = "0.3.13" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/0d/bc11eb89f8c912747d3a41186b8b9a2fc2c15cc52af7866689621e22ab4d/llama_index_llms_openai-0.3.13.tar.gz", hash = "sha256:51dda240dae7671c37e84bb50fe77fe6bb58a9b2a7e33dccd84473c9998afcea", size = 14302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/22/b0dad3dd2b9054d020208cbc86e9fd730c04fe3551a9af2e640593eff6ef/llama_index_llms_openai-0.3.13-py3-none-any.whl", hash = "sha256:caea1d6cb5bdd34518fcefe28b784698c92120ed133e6cd4591f777cd15180b0", size = 14542 }, +] + +[[package]] +name = "llama-index-multi-modal-llms-openai" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-index-llms-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/32/6f13d3cb79d71504072041d2e83fa67804c7945d2249f7ccadbcbbe15fdc/llama_index_multi_modal_llms_openai-0.4.2.tar.gz", hash = "sha256:3437a08cec85cebbc212aa73da5c9b8b054b4dc628338568435a7df88489476f", size = 5078 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/18/14772cebd9674772bc605632c92d4675e86d87a3263c35a90865d6c4918b/llama_index_multi_modal_llms_openai-0.4.2-py3-none-any.whl", hash = "sha256:093f60f59fc423abab110810f8f129b96b0212b9737d74480f0e3e1b715e975b", size = 5855 }, +] + +[[package]] +name = "llama-index-program-openai" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-agent-openai" }, + { name = "llama-index-core" }, + { name = "llama-index-llms-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/b8/24f1103106bfeed04f0e33b587863345c2d7fad001828bb02844a5427fbc/llama_index_program_openai-0.3.1.tar.gz", hash = "sha256:6039a6cdbff62c6388c07e82a157fe2edd3bbef0c5adf292ad8546bf4ec75b82", size = 4818 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/59/3f31171c30a08c8ba21155d5241ba174630e57cf43b03d97fd77bf565b51/llama_index_program_openai-0.3.1-py3-none-any.whl", hash = "sha256:93646937395dc5318fd095153d2f91bd632b25215d013d14a87c088887d205f9", size = 5318 }, +] + +[[package]] +name = "llama-index-question-gen-openai" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-index-llms-openai" }, + { name = "llama-index-program-openai" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4e/47/c57392e2fb00c0f596f912e7977e3c639ac3314f2aed5d4ac733baa367f1/llama_index_question_gen_openai-0.3.0.tar.gz", hash = "sha256:efd3b468232808e9d3474670aaeab00e41b90f75f52d0c9bfbf11207e0963d62", size = 2608 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/2c/765b0dfc2c988bbea267e236c836d7a96c60a20df76d842e43e17401f800/llama_index_question_gen_openai-0.3.0-py3-none-any.whl", hash = "sha256:9b60ec114273a63b50349948666e5744a8f58acb645824e07c979041e8fec598", size = 2899 }, +] + +[[package]] +name = "llama-index-readers-file" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "llama-index-core" }, + { name = "pandas" }, + { name = "pypdf" }, + { name = "striprtf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/35/62edc3eed9d69d9b5b5faae4c0c82ff05e608b07b0c547a988c23f19a79c/llama_index_readers_file-0.4.3.tar.gz", hash = "sha256:07514bebed7ce431c1b3ef9279d09aa3d1bba8e342d661860a033355b98fb33a", size = 22046 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/06/f41f795000c623d4cdaf95729a045a2be819c31f39951d5e88f4bccf37db/llama_index_readers_file-0.4.3-py3-none-any.whl", hash = "sha256:c669da967ea534e3af3660f9fd730c71c725288f5c57906bcce338414ebeee5c", size = 38914 }, +] + +[[package]] +name = "llama-index-readers-llama-parse" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "llama-parse" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/35/30/4611821286f82ba7b5842295607baa876262db86f88b87d83595eed172bf/llama_index_readers_llama_parse-0.4.0.tar.gz", hash = "sha256:e99ec56f4f8546d7fda1a7c1ae26162fb9acb7ebcac343b5abdb4234b4644e0f", size = 2472 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/4f/e30d4257fe9e4224f5612b77fe99aaceddae411b2e74ca30534491de3e6f/llama_index_readers_llama_parse-0.4.0-py3-none-any.whl", hash = "sha256:574e48386f28d2c86c3f961ca4a4906910312f3400dd0c53014465bfbc6b32bf", size = 2472 }, +] + +[[package]] +name = "llama-index-readers-web" +version = "0.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "beautifulsoup4" }, + { name = "chromedriver-autoinstaller" }, + { name = "html2text" }, + { name = "llama-index-core" }, + { name = "newspaper3k" }, + { name = "playwright" }, + { name = "requests" }, + { name = "selenium" }, + { name = "spider-client" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/a5/14e4277c871194092e014fd893f8f17a7c84f447a254696d7985ab9e603c/llama_index_readers_web-0.3.3.tar.gz", hash = "sha256:740373b17456cc46a9b39810253a3c1adfc8814d40f88798bea42115a10626ce", size = 53969 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/40/6e290cac34ac217b47347c7b0268114aef1f0c836998647d0c9f0fabc8f0/llama_index_readers_web-0.3.3-py3-none-any.whl", hash = "sha256:ab166bb14a56f5b10b637d6633c861d86bcaa72e7e123c4e31d304e6b1d88efe", size = 76616 }, +] + +[[package]] +name = "llama-index-readers-wikipedia" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/f1/1bd33ebbd003f1e19e9a77a85d0e77c0dd0c904de50cc9212cc718648813/llama_index_readers_wikipedia-0.3.0.tar.gz", hash = "sha256:77972387cd5410c981bd427699613de63e76889f99816512fc3fce3b2eca440a", size = 2445 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/8a/c85a69d9899fd6b7176bcbf6d19579feb1110e340a48b486f3682bc1bf60/llama_index_readers_wikipedia-0.3.0-py3-none-any.whl", hash = "sha256:1723441901a3a19f323872e3c5a968bbfc98cdc5f35e901c99e79f0e8cb7fa57", size = 2702 }, +] + +[[package]] +name = "llama-index-tools-wikipedia" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llama-index-core" }, + { name = "wikipedia" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/fc/0ebe0913694a3582c0ae2c96cafb48689a9d012766e5b8a32d59932009de/llama_index_tools_wikipedia-0.3.0.tar.gz", hash = "sha256:8e3fc5ae8a479aacc6640c6c30a66f9848762bf8ebbbc4ceab41e8a4762a664c", size = 2487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/89/0d7aa9a41ed0a0768790da770ef057416b81a92ecc35dc9f9d70a86abbb1/llama_index_tools_wikipedia-0.3.0-py3-none-any.whl", hash = "sha256:aa76c39237056b3ed727a23aadc65f34c5b500449ee9ec2efaced055f3ff9938", size = 2712 }, +] + +[[package]] +name = "llama-parse" +version = "0.5.19" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "llama-index-core" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/02/63839a55f6f207110400c4f394152fd0290e9f8e450226b02a87cfdbd835/llama_parse-0.5.19.tar.gz", hash = "sha256:db69da70e199a2664705eb983a70fa92b7cee19dd6cff175af7692a0b8a4dd53", size = 16100 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/b7/3ff106e8199992bb62e72f195c8f6f2f2fe4a185f5f92746f0ed9db5c5d2/llama_parse-0.5.19-py3-none-any.whl", hash = "sha256:715cc895d183531b4299359d4f4004089b2e522f5f137f316084e7aa04035b62", size = 15421 }, +] + [[package]] name = "llvmlite" version = "0.43.0" @@ -2551,6 +3579,9 @@ requires-dist = [ { name = "autogen-ext", extras = ["openai", "magentic-one"], editable = "packages/autogen-ext" }, ] +[package.metadata.requires-dev] +dev = [] + [[package]] name = "mako" version = "1.3.8" @@ -2587,6 +3618,14 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, ] +[package.optional-dependencies] +linkify = [ + { name = "linkify-it-py" }, +] +plugins = [ + { name = "mdit-py-plugins" }, +] + [[package]] name = "markdownify" version = "0.14.1" @@ -2729,6 +3768,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, ] +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -2800,6 +3851,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/69/314d887a01599669fb330da14e5c6ff5f138609e322812a942a74ef9b765/msal_extensions-1.2.0-py3-none-any.whl", hash = "sha256:cf5ba83a2113fa6dc011a254a72f1c223c88d7dfad74cc30617c4679a417704d", size = 19254 }, ] +[[package]] +name = "msgpack" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/d0/7555686ae7ff5731205df1012ede15dd9d927f6227ea151e901c7406af4f/msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e", size = 167260 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/f9/a892a6038c861fa849b11a2bb0502c07bc698ab6ea53359e5771397d883b/msgpack-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ad442d527a7e358a469faf43fda45aaf4ac3249c8310a82f0ccff9164e5dccd", size = 150428 }, + { url = "https://files.pythonhosted.org/packages/df/7a/d174cc6a3b6bb85556e6a046d3193294a92f9a8e583cdbd46dc8a1d7e7f4/msgpack-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74bed8f63f8f14d75eec75cf3d04ad581da6b914001b474a5d3cd3372c8cc27d", size = 84131 }, + { url = "https://files.pythonhosted.org/packages/08/52/bf4fbf72f897a23a56b822997a72c16de07d8d56d7bf273242f884055682/msgpack-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:914571a2a5b4e7606997e169f64ce53a8b1e06f2cf2c3a7273aa106236d43dd5", size = 81215 }, + { url = "https://files.pythonhosted.org/packages/02/95/dc0044b439b518236aaf012da4677c1b8183ce388411ad1b1e63c32d8979/msgpack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c921af52214dcbb75e6bdf6a661b23c3e6417f00c603dd2070bccb5c3ef499f5", size = 371229 }, + { url = "https://files.pythonhosted.org/packages/ff/75/09081792db60470bef19d9c2be89f024d366b1e1973c197bb59e6aabc647/msgpack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8ce0b22b890be5d252de90d0e0d119f363012027cf256185fc3d474c44b1b9e", size = 378034 }, + { url = "https://files.pythonhosted.org/packages/32/d3/c152e0c55fead87dd948d4b29879b0f14feeeec92ef1fd2ec21b107c3f49/msgpack-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73322a6cc57fcee3c0c57c4463d828e9428275fb85a27aa2aa1a92fdc42afd7b", size = 363070 }, + { url = "https://files.pythonhosted.org/packages/d9/2c/82e73506dd55f9e43ac8aa007c9dd088c6f0de2aa19e8f7330e6a65879fc/msgpack-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e1f3c3d21f7cf67bcf2da8e494d30a75e4cf60041d98b3f79875afb5b96f3a3f", size = 359863 }, + { url = "https://files.pythonhosted.org/packages/cb/a0/3d093b248837094220e1edc9ec4337de3443b1cfeeb6e0896af8ccc4cc7a/msgpack-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64fc9068d701233effd61b19efb1485587560b66fe57b3e50d29c5d78e7fef68", size = 368166 }, + { url = "https://files.pythonhosted.org/packages/e4/13/7646f14f06838b406cf5a6ddbb7e8dc78b4996d891ab3b93c33d1ccc8678/msgpack-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:42f754515e0f683f9c79210a5d1cad631ec3d06cea5172214d2176a42e67e19b", size = 370105 }, + { url = "https://files.pythonhosted.org/packages/67/fa/dbbd2443e4578e165192dabbc6a22c0812cda2649261b1264ff515f19f15/msgpack-1.1.0-cp310-cp310-win32.whl", hash = "sha256:3df7e6b05571b3814361e8464f9304c42d2196808e0119f55d0d3e62cd5ea044", size = 68513 }, + { url = "https://files.pythonhosted.org/packages/24/ce/c2c8fbf0ded750cb63cbcbb61bc1f2dfd69e16dca30a8af8ba80ec182dcd/msgpack-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:685ec345eefc757a7c8af44a3032734a739f8c45d1b0ac45efc5d8977aa4720f", size = 74687 }, + { url = "https://files.pythonhosted.org/packages/b7/5e/a4c7154ba65d93be91f2f1e55f90e76c5f91ccadc7efc4341e6f04c8647f/msgpack-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d364a55082fb2a7416f6c63ae383fbd903adb5a6cf78c5b96cc6316dc1cedc7", size = 150803 }, + { url = "https://files.pythonhosted.org/packages/60/c2/687684164698f1d51c41778c838d854965dd284a4b9d3a44beba9265c931/msgpack-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79ec007767b9b56860e0372085f8504db5d06bd6a327a335449508bbee9648fa", size = 84343 }, + { url = "https://files.pythonhosted.org/packages/42/ae/d3adea9bb4a1342763556078b5765e666f8fdf242e00f3f6657380920972/msgpack-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6ad622bf7756d5a497d5b6836e7fc3752e2dd6f4c648e24b1803f6048596f701", size = 81408 }, + { url = "https://files.pythonhosted.org/packages/dc/17/6313325a6ff40ce9c3207293aee3ba50104aed6c2c1559d20d09e5c1ff54/msgpack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e59bca908d9ca0de3dc8684f21ebf9a690fe47b6be93236eb40b99af28b6ea6", size = 396096 }, + { url = "https://files.pythonhosted.org/packages/a8/a1/ad7b84b91ab5a324e707f4c9761633e357820b011a01e34ce658c1dda7cc/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1da8f11a3dd397f0a32c76165cf0c4eb95b31013a94f6ecc0b280c05c91b59", size = 403671 }, + { url = "https://files.pythonhosted.org/packages/bb/0b/fd5b7c0b308bbf1831df0ca04ec76fe2f5bf6319833646b0a4bd5e9dc76d/msgpack-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452aff037287acb1d70a804ffd022b21fa2bb7c46bee884dbc864cc9024128a0", size = 387414 }, + { url = "https://files.pythonhosted.org/packages/f0/03/ff8233b7c6e9929a1f5da3c7860eccd847e2523ca2de0d8ef4878d354cfa/msgpack-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8da4bf6d54ceed70e8861f833f83ce0814a2b72102e890cbdfe4b34764cdd66e", size = 383759 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/eb82e1fed5a16dddd9bc75f0854b6e2fe86c0259c4353666d7fab37d39f4/msgpack-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:41c991beebf175faf352fb940bf2af9ad1fb77fd25f38d9142053914947cdbf6", size = 394405 }, + { url = "https://files.pythonhosted.org/packages/90/2e/962c6004e373d54ecf33d695fb1402f99b51832631e37c49273cc564ffc5/msgpack-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a52a1f3a5af7ba1c9ace055b659189f6c669cf3657095b50f9602af3a3ba0fe5", size = 396041 }, + { url = "https://files.pythonhosted.org/packages/f8/20/6e03342f629474414860c48aeffcc2f7f50ddaf351d95f20c3f1c67399a8/msgpack-1.1.0-cp311-cp311-win32.whl", hash = "sha256:58638690ebd0a06427c5fe1a227bb6b8b9fdc2bd07701bec13c2335c82131a88", size = 68538 }, + { url = "https://files.pythonhosted.org/packages/aa/c4/5a582fc9a87991a3e6f6800e9bb2f3c82972912235eb9539954f3e9997c7/msgpack-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd2906780f25c8ed5d7b323379f6138524ba793428db5d0e9d226d3fa6aa1788", size = 74871 }, + { url = "https://files.pythonhosted.org/packages/e1/d6/716b7ca1dbde63290d2973d22bbef1b5032ca634c3ff4384a958ec3f093a/msgpack-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d46cf9e3705ea9485687aa4001a76e44748b609d260af21c4ceea7f2212a501d", size = 152421 }, + { url = "https://files.pythonhosted.org/packages/70/da/5312b067f6773429cec2f8f08b021c06af416bba340c912c2ec778539ed6/msgpack-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5dbad74103df937e1325cc4bfeaf57713be0b4f15e1c2da43ccdd836393e2ea2", size = 85277 }, + { url = "https://files.pythonhosted.org/packages/28/51/da7f3ae4462e8bb98af0d5bdf2707f1b8c65a0d4f496e46b6afb06cbc286/msgpack-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58dfc47f8b102da61e8949708b3eafc3504509a5728f8b4ddef84bd9e16ad420", size = 82222 }, + { url = "https://files.pythonhosted.org/packages/33/af/dc95c4b2a49cff17ce47611ca9ba218198806cad7796c0b01d1e332c86bb/msgpack-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676e5be1b472909b2ee6356ff425ebedf5142427842aa06b4dfd5117d1ca8a2", size = 392971 }, + { url = "https://files.pythonhosted.org/packages/f1/54/65af8de681fa8255402c80eda2a501ba467921d5a7a028c9c22a2c2eedb5/msgpack-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17fb65dd0bec285907f68b15734a993ad3fc94332b5bb21b0435846228de1f39", size = 401403 }, + { url = "https://files.pythonhosted.org/packages/97/8c/e333690777bd33919ab7024269dc3c41c76ef5137b211d776fbb404bfead/msgpack-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51abd48c6d8ac89e0cfd4fe177c61481aca2d5e7ba42044fd218cfd8ea9899f", size = 385356 }, + { url = "https://files.pythonhosted.org/packages/57/52/406795ba478dc1c890559dd4e89280fa86506608a28ccf3a72fbf45df9f5/msgpack-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2137773500afa5494a61b1208619e3871f75f27b03bcfca7b3a7023284140247", size = 383028 }, + { url = "https://files.pythonhosted.org/packages/e7/69/053b6549bf90a3acadcd8232eae03e2fefc87f066a5b9fbb37e2e608859f/msgpack-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:398b713459fea610861c8a7b62a6fec1882759f308ae0795b5413ff6a160cf3c", size = 391100 }, + { url = "https://files.pythonhosted.org/packages/23/f0/d4101d4da054f04274995ddc4086c2715d9b93111eb9ed49686c0f7ccc8a/msgpack-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:06f5fd2f6bb2a7914922d935d3b8bb4a7fff3a9a91cfce6d06c13bc42bec975b", size = 394254 }, + { url = "https://files.pythonhosted.org/packages/1c/12/cf07458f35d0d775ff3a2dc5559fa2e1fcd06c46f1ef510e594ebefdca01/msgpack-1.1.0-cp312-cp312-win32.whl", hash = "sha256:ad33e8400e4ec17ba782f7b9cf868977d867ed784a1f5f2ab46e7ba53b6e1e1b", size = 69085 }, + { url = "https://files.pythonhosted.org/packages/73/80/2708a4641f7d553a63bc934a3eb7214806b5b39d200133ca7f7afb0a53e8/msgpack-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:115a7af8ee9e8cddc10f87636767857e7e3717b7a2e97379dc2054712693e90f", size = 75347 }, +] + [[package]] name = "multidict" version = "6.1.0" @@ -2857,6 +3949,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, ] +[[package]] +name = "mypy" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, + { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, + { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, + { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, + { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, + { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, + { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, + { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, + { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, + { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, + { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, + { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, + { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, + { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, + { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -2866,6 +3987,57 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, ] +[[package]] +name = "mypy-protobuf" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, + { name = "types-protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/6f/282d64d66bf48ce60e38a6560753f784e0f88ab245ac2fb5e93f701a36cd/mypy-protobuf-3.6.0.tar.gz", hash = "sha256:02f242eb3409f66889f2b1a3aa58356ec4d909cdd0f93115622e9e70366eca3c", size = 24445 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/73/d6b999782ae22f16971cc05378b3b33f6a89ede3b9619e8366aa23484bca/mypy_protobuf-3.6.0-py3-none-any.whl", hash = "sha256:56176e4d569070e7350ea620262478b49b7efceba4103d468448f1d21492fd6c", size = 16434 }, +] + +[[package]] +name = "myst-nb" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "ipykernel" }, + { name = "ipython" }, + { name = "jupyter-cache" }, + { name = "myst-parser" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "pyyaml" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/e3/01c093f6a46be2edc0fd370cbf6d227495ea19452939b2810b36657c63d4/myst_nb-1.1.2.tar.gz", hash = "sha256:961b4005657029ca89892a4c75edbf0856c54ceaf6172368b46bf7676c1f7700", size = 78036 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/45/cf78b2f09c46b36f486b75c34a8b48580e53b543bd9a467b3c7eb9054b70/myst_nb-1.1.2-py3-none-any.whl", hash = "sha256:9b7034e5d62640cb6daf03f9ca16ef45d0462fced27944c77aa3f98c7cdcd566", size = 80281 }, +] + +[[package]] +name = "myst-parser" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/55/6d1741a1780e5e65038b74bce6689da15f620261c490c3511eb4c12bac4b/myst_parser-4.0.0.tar.gz", hash = "sha256:851c9dfb44e36e56d15d05e72f02b80da21a9e0d07cba96baf5e2d476bb91531", size = 93858 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/b4/b036f8fdb667587bb37df29dc6644681dd78b7a2a6321a34684b79412b28/myst_parser-4.0.0-py3-none-any.whl", hash = "sha256:b9317997552424448c6096c2558872fdb6f81d3ecb3a40ce84a7518798f3f28d", size = 84563 }, +] + [[package]] name = "nbclient" version = "0.10.2" @@ -2896,6 +4068,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, ] +[[package]] +name = "nbqa" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "autopep8" }, + { name = "ipython" }, + { name = "tokenize-rt" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/76/62d2609924cf34445148cd6b5de694cf64c179cc416cac93182579620e57/nbqa-1.9.1.tar.gz", hash = "sha256:a1f4bcf587c597302fed295951001fc4e1be4ce0e77e1ab1b25ac2fbe3db0cdd", size = 38348 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/88/4789719fbbe166d12d345b3ac66b96105f10001b16e00a9765ba29261a21/nbqa-1.9.1-py3-none-any.whl", hash = "sha256:95552d2f6c2c038136252a805aa78d85018aef922586270c3a074332737282e5", size = 35259 }, +] + [[package]] name = "nest-asyncio" version = "1.6.0" @@ -2914,6 +4101,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 }, ] +[[package]] +name = "newspaper3k" +version = "0.2.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "cssselect" }, + { name = "feedfinder2" }, + { name = "feedparser" }, + { name = "jieba3k" }, + { name = "lxml" }, + { name = "nltk" }, + { name = "pillow" }, + { name = "python-dateutil" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "tinysegmenter" }, + { name = "tldextract" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/fb/8f8525be0cafa48926e85b0c06a7cb3e2a892d340b8036f8c8b1b572df1c/newspaper3k-0.2.8.tar.gz", hash = "sha256:9f1bd3e1fb48f400c715abf875cc7b0a67b7ddcd87f50c9aeeb8fcbbbd9004fb", size = 205685 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/b9/51afecb35bb61b188a4b44868001de348a0e8134b4dfa00ffc191567c4b9/newspaper3k-0.2.8-py3-none-any.whl", hash = "sha256:44a864222633d3081113d1030615991c3dbba87239f6bbf59d91240f71a22e3e", size = 211132 }, +] + [[package]] name = "nltk" version = "3.9.1" @@ -2929,6 +4140,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4d/66/7d9e26593edda06e8cb531874633f7c2372279c3b0f46235539fe546df8b/nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1", size = 1505442 }, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + [[package]] name = "numba" version = "0.60.0" @@ -3029,7 +4249,7 @@ name = "nvidia-cudnn-cu12" version = "9.1.0.70" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 }, @@ -3040,7 +4260,7 @@ name = "nvidia-cufft-cu12" version = "11.2.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/7a/8a/0e728f749baca3fbeffad762738276e5df60851958be7783af121a7221e7/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5dad8008fc7f92f5ddfa2101430917ce2ffacd86824914c82e28990ad7f00399", size = 211422548 }, @@ -3061,9 +4281,9 @@ name = "nvidia-cusolver-cu12" version = "11.6.1.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/46/6b/a5c33cf16af09166845345275c34ad2190944bcc6026797a39f8e0a282e0/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d338f155f174f90724bbde3758b7ac375a70ce8e706d70b018dd3375545fc84e", size = 127634111 }, @@ -3075,7 +4295,7 @@ name = "nvidia-cusparse-cu12" version = "12.3.1.170" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/96/a9/c0d2f83a53d40a4a41be14cea6a0bf9e668ffcf8b004bd65633f433050c0/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9d32f62896231ebe0480efd8a7f702e143c98cfaa0e8a76df3386c1ba2b54df3", size = 207381987 }, @@ -3300,6 +4520,93 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/1f/737dcdbc9fea2fa96c1b392ae47275165a7c641663fbb08a8d252968eed2/opentelemetry_api-1.27.0-py3-none-any.whl", hash = "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7", size = 63970 }, ] +[[package]] +name = "opentelemetry-exporter-otlp" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-exporter-otlp-proto-grpc" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/d3/8156cc14e8f4573a3572ee7f30badc7aabd02961a09acc72ab5f2c789ef1/opentelemetry_exporter_otlp-1.27.0.tar.gz", hash = "sha256:4a599459e623868cc95d933c301199c2367e530f089750e115599fccd67cb2a1", size = 6166 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/6d/95e1fc2c8d945a734db32e87a5aa7a804f847c1657a21351df9338bd1c9c/opentelemetry_exporter_otlp-1.27.0-py3-none-any.whl", hash = "sha256:7688791cbdd951d71eb6445951d1cfbb7b6b2d7ee5948fac805d404802931145", size = 7001 }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-proto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/2e/7eaf4ba595fb5213cf639c9158dfb64aacb2e4c7d74bfa664af89fa111f4/opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz", hash = "sha256:159d27cf49f359e3798c4c3eb8da6ef4020e292571bd8c5604a2a573231dd5c8", size = 17860 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/27/4610ab3d9bb3cde4309b6505f98b3aabca04a26aa480aa18cede23149837/opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl", hash = "sha256:675db7fffcb60946f3a5c43e17d1168a3307a94a930ecf8d2ea1f286f3d4f79a", size = 17848 }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-grpc" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated" }, + { name = "googleapis-common-protos" }, + { name = "grpcio" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/d0/c1e375b292df26e0ffebf194e82cd197e4c26cc298582bda626ce3ce74c5/opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz", hash = "sha256:af6f72f76bcf425dfb5ad11c1a6d6eca2863b91e63575f89bb7b4b55099d968f", size = 26244 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/80/32217460c2c64c0568cea38410124ff680a9b65f6732867bbf857c4d8626/opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl", hash = "sha256:56b5bbd5d61aab05e300d9d62a6b3c134827bbd28d0b12f2649c2da368006c9e", size = 18541 }, +] + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated" }, + { name = "googleapis-common-protos" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-common" }, + { name = "opentelemetry-proto" }, + { name = "opentelemetry-sdk" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/0a/f05c55e8913bf58a033583f2580a0ec31a5f4cf2beacc9e286dcb74d6979/opentelemetry_exporter_otlp_proto_http-1.27.0.tar.gz", hash = "sha256:2103479092d8eb18f61f3fbff084f67cc7f2d4a7d37e75304b8b56c1d09ebef5", size = 15059 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/8d/4755884afc0b1db6000527cac0ca17273063b6142c773ce4ecd307a82e72/opentelemetry_exporter_otlp_proto_http-1.27.0-py3-none-any.whl", hash = "sha256:688027575c9da42e179a69fe17e2d1eba9b14d81de8d13553a21d3114f3b4d75", size = 17203 }, +] + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.48b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "setuptools" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0e/d9394839af5d55c8feb3b22cd11138b953b49739b20678ca96289e30f904/opentelemetry_instrumentation-0.48b0.tar.gz", hash = "sha256:94929685d906380743a71c3970f76b5f07476eea1834abd5dd9d17abfe23cc35", size = 24724 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7f/405c41d4f359121376c9d5117dcf68149b8122d3f6c718996d037bd4d800/opentelemetry_instrumentation-0.48b0-py3-none-any.whl", hash = "sha256:a69750dc4ba6a5c3eb67986a337185a25b739966d80479befe37b546fc870b44", size = 29449 }, +] + +[[package]] +name = "opentelemetry-proto" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "protobuf" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/59/959f0beea798ae0ee9c979b90f220736fbec924eedbefc60ca581232e659/opentelemetry_proto-1.27.0.tar.gz", hash = "sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6", size = 34749 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/56/3d2d826834209b19a5141eed717f7922150224d1a982385d19a9444cbf8d/opentelemetry_proto-1.27.0-py3-none-any.whl", hash = "sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace", size = 52464 }, +] + [[package]] name = "opentelemetry-sdk" version = "1.27.0" @@ -3374,6 +4681,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/7f/f2d346819a273653825e7c92dc26418c8da506003c9fc1dfe8157e733b2e/orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406", size = 133663 }, ] +[[package]] +name = "outcome" +version = "1.3.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 }, +] + [[package]] name = "overrides" version = "7.7.0" @@ -3427,6 +4746,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, ] +[[package]] +name = "pandas-stubs" +version = "2.2.3.241126" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "types-pytz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/86/93c545d149c3e1fe1c4c55478cc3a69859d0ea3467e1d9892e9eb28cb1e7/pandas_stubs-2.2.3.241126.tar.gz", hash = "sha256:cf819383c6d9ae7d4dabf34cd47e1e45525bb2f312e6ad2939c2c204cb708acd", size = 104204 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/ab/ed42acf15bab2e86e5c49fad4aa038315233c4c2d22f41b49faa4d837516/pandas_stubs-2.2.3.241126-py3-none-any.whl", hash = "sha256:74aa79c167af374fe97068acc90776c0ebec5266a6e5c69fe11e9c2cf51f2267", size = 158280 }, +] + [[package]] name = "parse" version = "1.20.2" @@ -3445,6 +4777,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, ] +[[package]] +name = "pastel" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/f1/4594f5e0fcddb6953e5b8fe00da8c317b8b41b547e2b3ae2da7512943c62/pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d", size = 7555 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/18/a8444036c6dd65ba3624c63b734d3ba95ba63ace513078e1580590075d21/pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364", size = 5955 }, +] + [[package]] name = "pathable" version = "0.4.4" @@ -3475,6 +4816,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/87/2b/b50d3d08ea0fc419c183a84210571eba005328efa62b6b98bc28e9ead32a/patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c", size = 232923 }, ] +[[package]] +name = "pbr" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/35/80cf8f6a4f34017a7fe28242dc45161a1baa55c41563c354d8147e8358b2/pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24", size = 124032 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/44/6a65ecd630393d47ad3e7d5354768cb7f9a10b3a0eb2cd8c6f52b28211ee/pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a", size = 108529 }, +] + [[package]] name = "pdfminer-six" version = "20240706" @@ -3548,6 +4898,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/67/936f9814bdd74b2dfd4822f1f7725ab5d8ff4103919a1664eb4874c58b2f/pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", size = 2626353 }, ] +[[package]] +name = "pip" +version = "24.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz", hash = "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", size = 1931073 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl", hash = "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", size = 1822182 }, +] + [[package]] name = "platformdirs" version = "4.3.6" @@ -3584,12 +4943,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, ] +[[package]] +name = "poethepoet" +version = "0.32.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pastel" }, + { name = "pyyaml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/10/11f929bad564b2dbc5c119ecf0f37456ac24538bb4a70c76f140a2aa695a/poethepoet-0.32.1.tar.gz", hash = "sha256:471e1a025812dcd3d2997e30989681be5ab0a49232ee5fba94859629671c9584", size = 61391 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/a5/fc26dd508f33809bdd3823a0170e492fe44ad7e097c32c4a52e16cf3ecb0/poethepoet-0.32.1-py3-none-any.whl", hash = "sha256:d1e0a52a2f677870fac17dfb26bfe4910242756ac821443ef31f90ad26227c2d", size = 81729 }, +] + +[[package]] +name = "polars" +version = "1.19.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/d9/66ada2204483c4c4d83898ade77eacd5fbef26ae4975a0d7d5de134ca46a/polars-1.19.0.tar.gz", hash = "sha256:b52ada5c43fcdadf64f282522198c5549ee4e46ea57d236a4d7e572643070d9d", size = 4267947 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/7d/e8645281281d44d96752443366ceef2df76c9c1e17dce040111abb6a4a12/polars-1.19.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:51c01837268a1aa41785e60ed7d3363d4b52f652ab0eef4981f887bdfa2e9ca7", size = 29472039 }, + { url = "https://files.pythonhosted.org/packages/d7/fb/7e5054598d6bb7a47e4ca086797bae61270f7d570350cf779dd97384d913/polars-1.19.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:20f8235e810f6ee795d7a215a3560945e6a1b57d017f87ba0c8542dced1fc665", size = 26150541 }, + { url = "https://files.pythonhosted.org/packages/ba/ba/6d715730c28b035abd308fc2cf0fcbae0cedea6216797e83ce4a9a96c6d4/polars-1.19.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0ea51f7b3553652bf0d53f3b925e969a898d4feb9980acecf8e3037d696903", size = 32751173 }, + { url = "https://files.pythonhosted.org/packages/ea/9a/bee8ab37ab82b8eea75170afa3b37ea7e1df74e4c4da8f6c93b3009977fd/polars-1.19.0-cp39-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:30305ef4e1b634c67a5d985832296fade9908482c5b1abb0100800808b2d090e", size = 29704437 }, + { url = "https://files.pythonhosted.org/packages/57/ec/74afa5699e37e03e3acc7f241f4e2c3e8c91847524005424d9cf038b3034/polars-1.19.0-cp39-abi3-win_amd64.whl", hash = "sha256:de4aa45e24f8f94a1da9cc6031a7db6fa65ac7de8246fac0bc581ebb427d0643", size = 32846039 }, + { url = "https://files.pythonhosted.org/packages/cf/5b/c6f6c70ddc9d3070dee65f4640437cb84ccb4cca04f7a81b01db15329ae3/polars-1.19.0-cp39-abi3-win_arm64.whl", hash = "sha256:d7ca7aeb63fa22c0a00f6cfa95dd5252c249e83dd4d1b954583a59f97a8e407b", size = 29029208 }, +] + [[package]] name = "portalocker" version = "2.10.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pywin32", marker = "platform_system == 'Windows'" }, + { name = "pywin32", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ed/d3/c6c64067759e87af98cc668c1cc75171347d0f1577fab7ca3749134e3cd4/portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f", size = 40891 } wheels = [ @@ -3857,6 +5244,15 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/ee/52/9aa428633ef5aba4b096b2b2f8d046ece613cecab28b4ceed54126d25ea5/pybars4-0.9.13.tar.gz", hash = "sha256:425817da20d4ad320bc9b8e77a60cab1bb9d3c677df3dce224925c3310fcd635", size = 29907 } +[[package]] +name = "pycodestyle" +version = "2.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/aa/210b2c9aedd8c1cbeea31a50e42050ad56187754b34eb214c46709445801/pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521", size = 39232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/d8/a211b3f85e99a0daa2ddec96c949cac6824bd305b040571b82a03dd62636/pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3", size = 31284 }, +] + [[package]] name = "pycparser" version = "2.22" @@ -3954,6 +5350,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/46/93416fdae86d40879714f72956ac14df9c7b76f7d41a4d68aa9f71a0028b/pydantic_settings-2.7.1-py3-none-any.whl", hash = "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd", size = 29718 }, ] +[[package]] +name = "pydata-sphinx-theme" +version = "0.15.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/ea/3ab478cccacc2e8ef69892c42c44ae547bae089f356c4b47caf61730958d/pydata_sphinx_theme-0.15.4.tar.gz", hash = "sha256:7762ec0ac59df3acecf49fd2f889e1b4565dbce8b88b2e29ee06fdd90645a06d", size = 2400673 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/d3/c622950d87a2ffd1654208733b5bd1c5645930014abed8f4c0d74863988b/pydata_sphinx_theme-0.15.4-py3-none-any.whl", hash = "sha256:2136ad0e9500d0949f96167e63f3e298620040aea8f9c74621959eda5d4cf8e6", size = 4640157 }, +] + [[package]] name = "pydub" version = "0.25.1" @@ -4046,6 +5461,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, ] +[[package]] +name = "pypdf" +version = "5.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/9a/72d74f05f64895ebf1c7f6646cf7fe6dd124398c5c49240093f92d6f0fdd/pypdf-5.1.0.tar.gz", hash = "sha256:425a129abb1614183fd1aca6982f650b47f8026867c0ce7c4b9f281c443d2740", size = 5011381 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/fc/6f52588ac1cb4400a7804ef88d0d4e00cfe57a7ac6793ec3b00de5a8758b/pypdf-5.1.0-py3-none-any.whl", hash = "sha256:3bd4f503f4ebc58bae40d81e81a9176c400cbbac2ba2d877367595fb524dfdfc", size = 297976 }, +] + [[package]] name = "pyreadline3" version = "3.5.4" @@ -4055,6 +5482,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178 }, ] +[[package]] +name = "pyright" +version = "1.1.389" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/4e/9a5ab8745e7606b88c2c7ca223449ac9d82a71fd5e31df47b453f2cb39a1/pyright-1.1.389.tar.gz", hash = "sha256:716bf8cc174ab8b4dcf6828c3298cac05c5ed775dda9910106a5dcfe4c7fe220", size = 21940 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/26/c288cabf8cfc5a27e1aa9e5029b7682c0f920b8074f45d22bf844314d66a/pyright-1.1.389-py3-none-any.whl", hash = "sha256:41e9620bba9254406dc1f621a88ceab5a88af4c826feb4f614d95691ed243a60", size = 18581 }, +] + +[[package]] +name = "pysocks" +version = "1.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 }, +] + [[package]] name = "pytest" version = "8.3.4" @@ -4072,6 +5521,56 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] +[[package]] +name = "pytest-asyncio" +version = "0.25.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/df/adcc0d60f1053d74717d21d58c0048479e9cab51464ce0d2965b086bd0e2/pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f", size = 53950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/d8/defa05ae50dcd6019a95527200d3b3980043df5aa445d40cb0ef9f7f98ab/pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075", size = 19400 }, +] + +[[package]] +name = "pytest-cov" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, +] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c6/90/a955c3ab35ccd41ad4de556596fa86685bf4fc5ffcc62d22d856cfd4e29a/pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0", size = 32814 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/3b/b26f90f74e2986a82df6e7ac7e319b8ea7ccece1caec9f8ab6104dc70603/pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", size = 9863 }, +] + +[[package]] +name = "pytest-xdist" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108 }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -4093,6 +5592,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, ] +[[package]] +name = "python-engineio" +version = "4.11.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "simple-websocket" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/e0/a9e0fe427ce7f1b7dbf9531fa00ffe4b557c4a7bc8e71891c115af123170/python_engineio-4.11.2.tar.gz", hash = "sha256:145bb0daceb904b4bb2d3eb2d93f7dbb7bb87a6a0c4f20a94cc8654dec977129", size = 91381 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/8f/978a0b913e3f8ad33a9a2fe204d32efe3d1ee34ecb1f2829c1cfbdd92082/python_engineio-4.11.2-py3-none-any.whl", hash = "sha256:f0971ac4c65accc489154fe12efd88f53ca8caf04754c46a66e85f5102ef22ad", size = 59239 }, +] + +[[package]] +name = "python-multipart" +version = "0.0.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/86/b6b38677dec2e2e7898fc5b6f7e42c2d011919a92d25339451892f27b89c/python_multipart-0.0.18.tar.gz", hash = "sha256:7a68db60c8bfb82e460637fa4750727b45af1d5e2ed215593f917f64694d34fe", size = 36622 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/6b/b60f47101ba2cac66b4a83246630e68ae9bbe2e614cbae5f4465f46dee13/python_multipart-0.0.18-py3-none-any.whl", hash = "sha256:efe91480f485f6a361427a541db4796f9e1591afc0fb8e7a4ba06bfbc6708996", size = 24389 }, +] + [[package]] name = "python-pptx" version = "1.0.2" @@ -4108,6 +5628,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/4f/00be2196329ebbff56ce564aa94efb0fbc828d00de250b1980de1a34ab49/python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba", size = 472788 }, ] +[[package]] +name = "python-slugify" +version = "8.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "text-unidecode" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051 }, +] + +[[package]] +name = "python-socketio" +version = "5.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bidict" }, + { name = "python-engineio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/d0/40ed38076e8aee94785d546d3e3a1cae393da5806a8530be877187e2875f/python_socketio-5.12.1.tar.gz", hash = "sha256:0299ff1f470b676c09c1bfab1dead25405077d227b2c13cf217a34dadc68ba9c", size = 119991 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/a3/c69806f30dd81df5a99d592e7db4c930c3a9b098555aa97b0eb866b20b11/python_socketio-5.12.1-py3-none-any.whl", hash = "sha256:24a0ea7cfff0e021eb28c68edbf7914ee4111bdf030b95e4d250c4dc9af7a386", size = 76947 }, +] + [[package]] name = "pytz" version = "2024.2" @@ -4225,7 +5770,8 @@ name = "redis" version = "5.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "async-timeout", marker = "python_full_version < '3.11.3'" }, + { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "async-timeout", version = "5.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and python_full_version < '3.11.3'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/47/da/d283a37303a995cd36f8b92db85135153dc4f7a8e4441aa827721b442cfb/redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f", size = 4608355 } wheels = [ @@ -4314,6 +5860,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] +[[package]] +name = "requests-file" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/97/bf44e6c6bd8ddbb99943baf7ba8b1a8485bcd2fe0e55e5708d7fee4ff1ae/requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658", size = 6891 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/25/dd878a121fcfdf38f52850f11c512e13ec87c2ea72385933818e5b6c15ce/requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c", size = 4244 }, +] + [[package]] name = "requests-toolbelt" version = "1.0.0" @@ -4470,6 +6028,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, ] +[[package]] +name = "ruff" +version = "0.4.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/6b/4545638200466af8b9407bd0d5bea1ce426328eaa9714f8d3ef1a43fc0e6/ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268", size = 2559790 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/fd/cbdfeba4f72856853705b4dfc01c232fd6000cdbbde801224783de65c2a6/ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066", size = 8547521 }, + { url = "https://files.pythonhosted.org/packages/b2/8d/8930e04a82f376b99db57d8d1c86bd35c06496e77f58f6b2cdb388cd12d9/ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913", size = 8149146 }, + { url = "https://files.pythonhosted.org/packages/59/82/63d590c95025d526acc64803ab783f457ba15b3e16bea5bfb4b7ba9bf105/ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3", size = 8192701 }, + { url = "https://files.pythonhosted.org/packages/70/f4/97e142f3c9cb2c886798821e31136b58a6095e068b5bf6a9667f45dcf70b/ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb", size = 7578485 }, + { url = "https://files.pythonhosted.org/packages/fd/46/2b9addf3e3078c6d2c78135480f9dbf104257cfa6736d65154e9c7f64a34/ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764", size = 8768085 }, + { url = "https://files.pythonhosted.org/packages/b5/bf/b7bcec679c67a74d4df5ecaa6e09352d4dd14a365a1d0ce76deb6f5d8a56/ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883", size = 9439095 }, + { url = "https://files.pythonhosted.org/packages/cb/46/1a7bfa8f739116ec48d737d78d99b6e1c3c6307992b17b11bc8a44ee393f/ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199", size = 9060426 }, + { url = "https://files.pythonhosted.org/packages/ad/6b/e82233a81554df12a3508a25a5068d005fb7b69b14cc4194237e7b4c5fcf/ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b", size = 10250216 }, + { url = "https://files.pythonhosted.org/packages/21/77/9d9c536d8544d8b1b2fe1fcd5e3e190b946d91dc00a8956aa5fe88cb264b/ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45", size = 8797490 }, + { url = "https://files.pythonhosted.org/packages/95/90/a614ec4ee32a61dcd76c5d77ef5c336acac447cf731d81313e42dcbc34ed/ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a", size = 8092448 }, + { url = "https://files.pythonhosted.org/packages/1f/5b/d0a5ddf505593bacb52f386b0b92533dc2e87658a59ec55fe5b72890f1af/ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc", size = 7573842 }, + { url = "https://files.pythonhosted.org/packages/da/4a/d6af0c924514ebc588474b5002ac9bc6cc0b2328d3633c1b10b0227032c1/ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed", size = 8358130 }, + { url = "https://files.pythonhosted.org/packages/49/c4/3fbfb5a0020c9f67439dcef5a6e4f6a4f3430a059eaf40b624c00aa31bfa/ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa", size = 8842486 }, + { url = "https://files.pythonhosted.org/packages/a5/e6/c18211dd3fad5a1da66a1bd7a00e3bdc7541fa997adeeb087c2147f1e18a/ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9", size = 7832464 }, + { url = "https://files.pythonhosted.org/packages/95/b7/5b64aba350763aff321463e775f9daee9ad575750ebdb9f60f86f682f913/ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d", size = 8580070 }, + { url = "https://files.pythonhosted.org/packages/fe/f1/3db1590be946c14d86ac0cc8422e5808500903592b7ca09a097e425b1dba/ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780", size = 7944828 }, +] + [[package]] name = "s3transfer" version = "0.11.1" @@ -4576,6 +6158,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, ] +[[package]] +name = "selenium" +version = "4.27.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "trio" }, + { name = "trio-websocket" }, + { name = "typing-extensions" }, + { name = "urllib3", extra = ["socks"] }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/8c/62c47c91072aa03af1c3b7d7f1c59b987db41c9fec0f158fb03a0da51aa6/selenium-4.27.1.tar.gz", hash = "sha256:5296c425a75ff1b44d0d5199042b36a6d1ef76c04fb775b97b40be739a9caae2", size = 973526 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/1e/5f1a5dd2a28528c4b3ec6e076b58e4c035810c805328f9936123283ca14e/selenium-4.27.1-py3-none-any.whl", hash = "sha256:b89b1f62b5cfe8025868556fe82360d6b649d464f75d2655cb966c8f8447ea18", size = 9707007 }, +] + [[package]] name = "semantic-kernel" version = "1.18.2" @@ -4667,6 +6266,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, ] +[[package]] +name = "sgmllib3k" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/bd/3704a8c3e0942d711c1299ebf7b9091930adae6675d7c8f476a7ce48653c/sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9", size = 5750 } + [[package]] name = "shapely" version = "2.0.6" @@ -4705,6 +6310,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, ] +[[package]] +name = "simple-websocket" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wsproto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b0/d4/bfa032f961103eba93de583b161f0e6a5b63cebb8f2c7d0c6e6efe1e3d2e/simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4", size = 17300 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/59/0782e51887ac6b07ffd1570e0364cf901ebc36345fea669969d2084baebb/simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c", size = 13842 }, +] + [[package]] name = "simsimd" version = "6.2.1" @@ -4765,55 +6382,230 @@ wheels = [ ] [[package]] -name = "six" -version = "1.17.0" +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "smart-open" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/30/1f41c3d3b8cec82024b4b277bfd4e5b18b765ae7279eb9871fa25c503778/smart_open-7.1.0.tar.gz", hash = "sha256:a4f09f84f0f6d3637c6543aca7b5487438877a21360e7368ccf1f704789752ba", size = 72044 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/18/9a8d9f01957aa1f8bbc5676d54c2e33102d247e146c1a3679d3bd5cc2e3a/smart_open-7.1.0-py3-none-any.whl", hash = "sha256:4b8489bb6058196258bafe901730c7db0dcf4f083f316e97269c66f45502055b", size = 61746 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, +] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "speechrecognition" +version = "3.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/67/b91500f0796806659c37ba4da26750148ea98cd4e00d951facfdf4f440b3/speechrecognition-3.14.0.tar.gz", hash = "sha256:8f23d0125422fac358a05697ceffb5d7387a3f699fc2dcf829ee692fb15471c2", size = 32860450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/25/447b3a61afbc1d7e713ba56df0156aab1450442db752f1e6741d6a9f41df/SpeechRecognition-3.14.0-py3-none-any.whl", hash = "sha256:28303ae2b6abc13408963a91f838996f181f1c256936f94b8c021b51fcd4a3f5", size = 32852277 }, +] + +[[package]] +name = "sphinx" +version = "8.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125 }, +] + +[[package]] +name = "sphinx-autobuild" +version = "2024.10.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "sphinx" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908 }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343 }, +] + +[[package]] +name = "sphinx-design" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, +] + +[[package]] +name = "sphinxcontrib-apidoc" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pbr" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/8c/a4fe93b51a1026c217731337cfe50569b8521d3e254dd451126bed208cd8/sphinxcontrib-apidoc-0.5.0.tar.gz", hash = "sha256:65efcd92212a5f823715fb95ee098b458a6bb09a5ee617d9ed3dead97177cd55", size = 16117 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/35/453ba8b0f407b9b86520eba5122fe28e87230266cfae9524a623b524485e/sphinxcontrib_apidoc-0.5.0-py3-none-any.whl", hash = "sha256:c671d644d6dc468be91b813dcddf74d87893bff74fe8f1b8b01b69408f0fb776", size = 8603 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, ] [[package]] -name = "smart-open" -version = "7.1.0" +name = "sphinxcontrib-devhelp" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wrapt" }, +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, ] -sdist = { url = "https://files.pythonhosted.org/packages/21/30/1f41c3d3b8cec82024b4b277bfd4e5b18b765ae7279eb9871fa25c503778/smart_open-7.1.0.tar.gz", hash = "sha256:a4f09f84f0f6d3637c6543aca7b5487438877a21360e7368ccf1f704789752ba", size = 72044 } + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/18/9a8d9f01957aa1f8bbc5676d54c2e33102d247e146c1a3679d3bd5cc2e3a/smart_open-7.1.0-py3-none-any.whl", hash = "sha256:4b8489bb6058196258bafe901730c7db0dcf4f083f316e97269c66f45502055b", size = 61746 }, + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, ] [[package]] -name = "sniffio" -version = "1.3.1" +name = "sphinxcontrib-jsmath" +version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, ] [[package]] -name = "soupsieve" -version = "2.6" +name = "sphinxcontrib-qthelp" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, ] [[package]] -name = "speechrecognition" -version = "3.14.0" +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "sphinxext-rediraffe" +version = "0.2.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "sphinx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/67/b91500f0796806659c37ba4da26750148ea98cd4e00d951facfdf4f440b3/speechrecognition-3.14.0.tar.gz", hash = "sha256:8f23d0125422fac358a05697ceffb5d7387a3f699fc2dcf829ee692fb15471c2", size = 32860450 } +sdist = { url = "https://files.pythonhosted.org/packages/1f/b4/e5fbb493f796430230189a1ce5f9beff1ac1b98619fc71ed35deca6059a5/sphinxext-rediraffe-0.2.7.tar.gz", hash = "sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d", size = 8735 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/25/447b3a61afbc1d7e713ba56df0156aab1450442db752f1e6741d6a9f41df/SpeechRecognition-3.14.0-py3-none-any.whl", hash = "sha256:28303ae2b6abc13408963a91f838996f181f1c256936f94b8c021b51fcd4a3f5", size = 32852277 }, + { url = "https://files.pythonhosted.org/packages/76/4f/c8797e796199e55cf6c8979ecdf5f4b09b81e93f87b3193c759faea63263/sphinxext_rediraffe-0.2.7-py3-none-any.whl", hash = "sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c", size = 8267 }, +] + +[[package]] +name = "spider-client" +version = "0.0.27" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "requests" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/70/fc/a2a4cc112c467f89921328d005c0ac2df9c81f62c8a6d445f747252f5856/spider-client-0.0.27.tar.gz", hash = "sha256:c3feaf5c491bd9a6c509efa0c8789452497073d9f68e70fc90e7626a6a8365aa", size = 5755 } [[package]] name = "sqlalchemy" @@ -4852,6 +6644,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/36/59cc97c365f2f79ac9f3f51446cae56dfd82c4f2dd98497e6be6de20fb91/SQLAlchemy-2.0.37-py3-none-any.whl", hash = "sha256:a8998bf9f8658bd3839cbc44ddbe982955641863da0c1efe5b00c1ab4f5c16b1", size = 1894113 }, ] +[package.optional-dependencies] +asyncio = [ + { name = "greenlet" }, +] + [[package]] name = "sqlmodel" version = "0.0.22" @@ -4924,6 +6721,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/9a/e466a1b887a1441141e52dbcc98152f013d85076576da6eed2357f2016ae/statsmodels-0.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:7f7917a51766b4e074da283c507a25048ad29a18e527207883d73535e0dc6184", size = 9823866 }, ] +[[package]] +name = "striprtf" +version = "0.0.26" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/20/3d419008265346452d09e5dadfd5d045b64b40d8fc31af40588e6c76997a/striprtf-0.0.26.tar.gz", hash = "sha256:fdb2bba7ac440072d1c41eab50d8d74ae88f60a8b6575c6e2c7805dc462093aa", size = 6258 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/cf/0fea4f4ba3fc2772ac2419278aa9f6964124d4302117d61bc055758e000c/striprtf-0.0.26-py3-none-any.whl", hash = "sha256:8c8f9d32083cdc2e8bfb149455aa1cc5a4e0a035893bedc75db8b73becb3a1bb", size = 6914 }, +] + [[package]] name = "sympy" version = "1.13.1" @@ -4936,6 +6742,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 }, ] +[[package]] +name = "syncer" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8d/dd/d4dd75843692690d81f0a4b929212a1614b25d4896aa7c72f4c3546c7e3d/syncer-2.0.3.tar.gz", hash = "sha256:4340eb54b54368724a78c5c0763824470201804fe9180129daf3635cb500550f", size = 11512 } + [[package]] name = "tabulate" version = "0.9.0" @@ -4945,6 +6757,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, ] +[[package]] +name = "tavily-python" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "requests" }, + { name = "tiktoken" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ca/50/7f4acafe72ffd10d3578ddec76f993af5af81504bc7315ea54862f2705b9/tavily_python-0.5.0.tar.gz", hash = "sha256:2c60b88203b630e1b37fc711913a1090ced6719b3f21089f25ec06e9e1602822", size = 16455 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/99/05776f7150a5b3f8d853377144a3a634131964c0fce38307537674a9a674/tavily_python-0.5.0-py3-none-any.whl", hash = "sha256:e874f6a04a56cdda80a505fe0b4f5d61d25372bd52a83e6773926fb297dcaa29", size = 14361 }, +] + [[package]] name = "tenacity" version = "9.0.0" @@ -4954,6 +6780,77 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, ] +[[package]] +name = "text-unidecode" +version = "1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154 }, +] + +[[package]] +name = "textual" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", extra = ["linkify", "plugins"] }, + { name = "platformdirs" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/b6/59b1de04bb4dca0f21ed7ba0b19309ed7f3f5de4396edf20cc2855e53085/textual-1.0.0.tar.gz", hash = "sha256:bec9fe63547c1c552569d1b75d309038b7d456c03f86dfa3706ddb099b151399", size = 1532733 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/bb/5fb6656c625019cd653d5215237d7cd6e0b12e7eae4195c3d1c91b2136fc/textual-1.0.0-py3-none-any.whl", hash = "sha256:2d4a701781c05104925e463ae370c630567c70c2880e92ab838052e3e23c986f", size = 660456 }, +] + +[[package]] +name = "textual-dev" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "click" }, + { name = "msgpack" }, + { name = "textual" }, + { name = "textual-serve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/d3/ed0b20f6de0af1b7062c402d59d256029c0daa055ad9e04c27471b450cdd/textual_dev-1.7.0.tar.gz", hash = "sha256:bf1a50eaaff4cd6a863535dd53f06dbbd62617c371604f66f56de3908220ccd5", size = 25935 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/4b/3c1eb9cbc39f2f28d27e10ef2fe42bfe0cf3c2f8445a454c124948d6169b/textual_dev-1.7.0-py3-none-any.whl", hash = "sha256:a93a846aeb6a06edb7808504d9c301565f7f4bf2e7046d56583ed755af356c8d", size = 27221 }, +] + +[[package]] +name = "textual-imageview" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pillow" }, + { name = "rich" }, + { name = "textual" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/31/3d8a517bd8694ee0d70fd260fbc20590f00a5fcde6ca1ce2edb174c000ac/textual_imageview-0.1.1.tar.gz", hash = "sha256:4299d8ed677db0adb8fe945687470cf1421dcafd2a5dddab54b6ee8ef2ab3320", size = 3232614 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/56/c0514dcfdb2b67333bf4e653ca9cf0fda51004932d3b246bf835376cbaba/textual_imageview-0.1.1-py3-none-any.whl", hash = "sha256:335c8043e2f1f735b1b2ec1753a743d6762578175cd2cedae3ce67e2694800a4", size = 8875 }, +] + +[[package]] +name = "textual-serve" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "aiohttp-jinja2" }, + { name = "jinja2" }, + { name = "rich" }, + { name = "textual" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/6c/57248070f525ea8a9a02d9f58dc2747c609b615b0bda1306aaeb80a233bd/textual_serve-1.1.1.tar.gz", hash = "sha256:71c662472c462e5e368defc660ee6e8eae3bfda88ca40c050c55474686eb0c54", size = 445957 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/a9/01d35770fde8d889e1fe28b726188cf28801e57afd369c614cd2bc100ee4/textual_serve-1.1.1-py3-none-any.whl", hash = "sha256:568782f1c0e60e3f7039d9121e1cb5c2f4ca1aaf6d6bd7aeb833d5763a534cb2", size = 445034 }, +] + [[package]] name = "threadpoolctl" version = "3.5.0" @@ -4993,6 +6890,36 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/e2/39d4aa02a52bba73b2cd21ba4533c84425ff8786cc63c511d68c8897376e/tiktoken-0.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:d8f3192733ac4d77977432947d563d7e1b310b96497acd3c196c9bddb36ed9db", size = 883824 }, ] +[[package]] +name = "tinysegmenter" +version = "0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/17/82/86982e4b6d16e4febc79c2a1d68ee3b707e8a020c5d2bc4af8052d0f136a/tinysegmenter-0.3.tar.gz", hash = "sha256:ed1f6d2e806a4758a73be589754384cbadadc7e1a414c81a166fc9adf2d40c6d", size = 16893 } + +[[package]] +name = "tldextract" +version = "5.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "idna" }, + { name = "requests" }, + { name = "requests-file" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/4f/eee4bebcbad25a798bf55601d3a4aee52003bebcf9e55fce08b91ca541a9/tldextract-5.1.3.tar.gz", hash = "sha256:d43c7284c23f5dc8a42fd0fee2abede2ff74cc622674e4cb07f514ab3330c338", size = 125033 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/86/aebe15fa40a992c446be5cf14e70e58a251277494c14d26bdbcff0e658fd/tldextract-5.1.3-py3-none-any.whl", hash = "sha256:78de310cc2ca018692de5ddf320f9d6bd7c5cf857d0fd4f2175f0cdf4440ea75", size = 104923 }, +] + +[[package]] +name = "tokenize-rt" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/0a/5854d8ced8c1e00193d1353d13db82d7f813f99bd5dcb776ce3e2a4c0d19/tokenize_rt-6.1.0.tar.gz", hash = "sha256:e8ee836616c0877ab7c7b54776d2fefcc3bde714449a206762425ae114b53c86", size = 5506 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/ba/576aac29b10dfa49a6ce650001d1bb31f81e734660555eaf144bfe5b8995/tokenize_rt-6.1.0-py2.py3-none-any.whl", hash = "sha256:d706141cdec4aa5f358945abe36b911b8cbdc844545da99e811250c0cee9b6fc", size = 6015 }, +] + [[package]] name = "tokenizers" version = "0.21.0" @@ -5047,6 +6974,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675 }, +] + [[package]] name = "torch" version = "2.5.1" @@ -5056,21 +6992,21 @@ dependencies = [ { name = "fsspec" }, { name = "jinja2" }, { name = "networkx" }, - { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, - { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools", marker = "python_full_version >= '3.12'" }, { name = "sympy" }, - { name = "triton", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "typing-extensions" }, ] wheels = [ @@ -5111,7 +7047,7 @@ name = "tqdm" version = "4.67.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 } wheels = [ @@ -5154,12 +7090,44 @@ torch = [ { name = "torch" }, ] +[[package]] +name = "trio" +version = "0.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "cffi", marker = "(implementation_name != 'pypy' and os_name == 'nt' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'pypy' and os_name == 'nt' and sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "outcome" }, + { name = "sniffio" }, + { name = "sortedcontainers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/73/57efab729506a8d4b89814f1e356ec8f3369de0ed4fd7e7616974d09646d/trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", size = 580318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/04/9954a59e1fb6732f5436225c9af963811d7b24ea62a8bf96991f2cb8c26e/trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94", size = 486317 }, +] + +[[package]] +name = "trio-websocket" +version = "0.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "trio" }, + { name = "wsproto" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/36/abad2385853077424a11b818d9fd8350d249d9e31d583cb9c11cd4c85eda/trio-websocket-0.11.1.tar.gz", hash = "sha256:18c11793647703c158b1f6e62de638acada927344d534e3c7628eedcb746839f", size = 26511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/be/a9ae5f50cad5b6f85bd2574c2c923730098530096e170c1ce7452394d7aa/trio_websocket-0.11.1-py3-none-any.whl", hash = "sha256:520d046b0d030cf970b8b2b2e00c4c2245b3807853ecd44214acd33d74581638", size = 17408 }, +] + [[package]] name = "triton" version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'" }, + { name = "filelock", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 }, @@ -5182,6 +7150,85 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/cc/0a838ba5ca64dc832aa43f727bd586309846b0ffb2ce52422543e6075e8a/typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847", size = 44908 }, ] +[[package]] +name = "types-aiofiles" +version = "24.1.0.20241221" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/5e/f984b9ddc7eecdf31e683e692d933f3672276ed95aad6adb9aea9ecbdc29/types_aiofiles-24.1.0.20241221.tar.gz", hash = "sha256:c40f6c290b0af9e902f7f3fa91213cf5bb67f37086fb21dc0ff458253586ad55", size = 14081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/da/77902220df98ce920444cf3611fa0b1cf0dc2cfa5a137c55e93829aa458e/types_aiofiles-24.1.0.20241221-py3-none-any.whl", hash = "sha256:11d4e102af0627c02e8c1d17736caa3c39de1058bea37e2f4de6ef11a5b652ab", size = 14162 }, +] + +[[package]] +name = "types-docker" +version = "7.1.0.20241229" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-requests" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/4b/7ca6c1fe916ef4c71f145234902bb4da074e410d9cc0bd72572790c3f06d/types_docker-7.1.0.20241229.tar.gz", hash = "sha256:d968f164bb02f934bc2f178515dd4b3c8b2b4e371a9400ec440247c09c139545", size = 29032 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/32/8a1c95566816fef8f7b2407d25981cf0d3ecf2f226ed0ab3a34969994ab7/types_docker-7.1.0.20241229-py3-none-any.whl", hash = "sha256:b760745a6cb0351a19108c0b76e2a43ebc05a686f6c3ec9bc1a991ff9f1cc353", size = 43650 }, +] + +[[package]] +name = "types-pillow" +version = "10.2.0.20240822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/4a/4495264dddaa600d65d68bcedb64dcccf9d9da61adff51f7d2ffd8e4c9ce/types-Pillow-10.2.0.20240822.tar.gz", hash = "sha256:559fb52a2ef991c326e4a0d20accb3bb63a7ba8d40eb493e0ecb0310ba52f0d3", size = 35389 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/23/e81a5354859831fcf54d488d33b80ba6133ea84f874a9c0ec40a4881e133/types_Pillow-10.2.0.20240822-py3-none-any.whl", hash = "sha256:d9dab025aba07aeb12fd50a6799d4eac52a9603488eca09d7662543983f16c5d", size = 54354 }, +] + +[[package]] +name = "types-protobuf" +version = "5.29.1.20241207" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/89/b661a447139f665ccea8e39bfdd52a92f803df4b5de0e6001a3537feaacb/types_protobuf-5.29.1.20241207.tar.gz", hash = "sha256:2ebcadb8ab3ef2e3e2f067e0882906d64ba0dc65fc5b0fd7a8b692315b4a0be9", size = 59190 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/6e/cdf152187019d6f6d04066b23e48659d961b527e9c6d43b48459d160e332/types_protobuf-5.29.1.20241207-py3-none-any.whl", hash = "sha256:92893c42083e9b718c678badc0af7a9a1307b92afe1599e5cba5f3d35b668b2f", size = 73902 }, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, +] + +[[package]] +name = "types-pytz" +version = "2024.2.0.20241221" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/26/516311b02b5a215e721155fb65db8a965d061372e388d6125ebce8d674b0/types_pytz-2024.2.0.20241221.tar.gz", hash = "sha256:06d7cde9613e9f7504766a0554a270c369434b50e00975b3a4a0f6eed0f2c1a9", size = 10213 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/db/c92ca6920cccd9c2998b013601542e2ac5e59bc805bcff94c94ad254b7df/types_pytz-2024.2.0.20241221-py3-none-any.whl", hash = "sha256:8fc03195329c43637ed4f593663df721fef919b60a969066e22606edf0b53ad5", size = 10008 }, +] + +[[package]] +name = "types-requests" +version = "2.32.0.20241016" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/3c/4f2a430c01a22abd49a583b6b944173e39e7d01b688190a5618bd59a2e22/types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95", size = 18065 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/01/485b3026ff90e5190b5e24f1711522e06c79f4a56c8f4b95848ac072e20f/types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747", size = 15836 }, +] + +[[package]] +name = "types-tabulate" +version = "0.9.0.20241207" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/43/16030404a327e4ff8c692f2273854019ed36718667b2993609dc37d14dd4/types_tabulate-0.9.0.20241207.tar.gz", hash = "sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230", size = 8195 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/86/a9ebfd509cbe74471106dffed320e208c72537f9aeb0a55eaa6b1b5e4d17/types_tabulate-0.9.0.20241207-py3-none-any.whl", hash = "sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85", size = 8307 }, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -5213,6 +7260,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, ] +[[package]] +name = "uc-micro-py" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/7a/146a99696aee0609e3712f2b44c6274566bc368dfe8375191278045186b8/uc-micro-py-1.0.3.tar.gz", hash = "sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a", size = 6043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/87/1f677586e8ac487e29672e4b17455758fce261de06a0d086167bb760361a/uc_micro_py-1.0.3-py3-none-any.whl", hash = "sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5", size = 6229 }, +] + [[package]] name = "umap-learn" version = "0.5.7" @@ -5230,6 +7286,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/8f/671c0e1f2572ba625cbcc1faeba9435e00330c3d6962858711445cf1e817/umap_learn-0.5.7-py3-none-any.whl", hash = "sha256:6a7e0be2facfa365a5ed6588447102bdbef32a0ef449535c25c97ea7e680073c", size = 88815 }, ] +[[package]] +name = "uptrace" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-sdk" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/89/ba1df9328e4bd4b440ac6979e20ec8c63a26f6400598e806cc9dfef764f4/uptrace-1.27.0.tar.gz", hash = "sha256:983f783b2f4303d1d2bdfaf6ace1b7a5f072af47f78a7815f82c51fcf5099cac", size = 7633 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/00/054ac30e9e8312c3c79371c495dd570865eab2a05bfcd640f6242d460c8b/uptrace-1.27.0-py3-none-any.whl", hash = "sha256:d5473efa33c34e3d5738d32d19301dbf004d4e19598c658f2fa9f3f09458f630", size = 8627 }, +] + [[package]] name = "uritemplate" version = "4.1.1" @@ -5248,6 +7319,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, ] +[package.optional-dependencies] +socks = [ + { name = "pysocks" }, +] + [[package]] name = "usearch" version = "2.16.9" @@ -5301,6 +7377,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/59/fddd9df489fe27f492cc97626e03663fb3b9b6ef7ce8597a7cdc5f2cbbad/uvicorn-0.25.0-py3-none-any.whl", hash = "sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c", size = 60303 }, ] +[[package]] +name = "watchfiles" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/48/02d2d2cbf54e134810b2cb40ac79fdb8ce08476184536a4764717a7bc9f4/watchfiles-0.20.0.tar.gz", hash = "sha256:728575b6b94c90dd531514677201e8851708e6e4b5fe7028ac506a200b622019", size = 37041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/db/899832e11fef2d468bf8b3c1c13289b1db4cb7c3410bb2a9612a52fc8b22/watchfiles-0.20.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3796312bd3587e14926013612b23066912cf45a14af71cf2b20db1c12dadf4e9", size = 417357 }, + { url = "https://files.pythonhosted.org/packages/9f/1a/85c914e4db62a3f8197daa98a271ea380a5d200a8d3058bd9f417752bc26/watchfiles-0.20.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d0002d81c89a662b595645fb684a371b98ff90a9c7d8f8630c82f0fde8310458", size = 407258 }, + { url = "https://files.pythonhosted.org/packages/25/ae/b7bddad421af5e33079a2ce639aa58837b715a2da98df16e25ecd310af52/watchfiles-0.20.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:570848706440373b4cd8017f3e850ae17f76dbdf1e9045fc79023b11e1afe490", size = 1331327 }, + { url = "https://files.pythonhosted.org/packages/21/e5/b080cec4e841b1cf338ccbd958cf3232ad1691a590653b2d124b5c79cf6b/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0351d20d03c6f7ad6b2e8a226a5efafb924c7755ee1e34f04c77c3682417fa", size = 1301371 }, + { url = "https://files.pythonhosted.org/packages/05/a0/2fb2c36730995a6b3f060187195dc08ad9ceee67426bdca8a4296024071c/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:007dcc4a401093010b389c044e81172c8a2520dba257c88f8828b3d460c6bb38", size = 1302438 }, + { url = "https://files.pythonhosted.org/packages/13/ea/d11971958ae703cfe443b21f672169cb8bc12dbec5781b910633fa2186ec/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d82dbc1832da83e441d112069833eedd4cf583d983fb8dd666fbefbea9d99c0", size = 1410655 }, + { url = "https://files.pythonhosted.org/packages/6b/81/3f922f3ede53ca9c0b4095f63688ffeea19a49592d0ac62db1eb9632b1e3/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99f4c65fd2fce61a571b2a6fcf747d6868db0bef8a934e8ca235cc8533944d95", size = 1494222 }, + { url = "https://files.pythonhosted.org/packages/e1/46/c9d5ee4871b187d291d62e61c41f9a4d67d4866a89704b0ad16b6949e9bd/watchfiles-0.20.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5392dd327a05f538c56edb1c6ebba6af91afc81b40822452342f6da54907bbdf", size = 1294171 }, + { url = "https://files.pythonhosted.org/packages/59/5e/6b64e3bf9fd4422250f3c716d992dd76dbe55e6fa1e7ebaf2bf88f389707/watchfiles-0.20.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:08dc702529bb06a2b23859110c214db245455532da5eaea602921687cfcd23db", size = 1462256 }, + { url = "https://files.pythonhosted.org/packages/11/c0/75f5a71ac24118ab11bd898e0114cedc72b25924ff2d960d473bddb4ec6e/watchfiles-0.20.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d4e66a857621584869cfbad87039e65dadd7119f0d9bb9dbc957e089e32c164", size = 1461725 }, + { url = "https://files.pythonhosted.org/packages/91/d4/0c0fdcc4293ad1b73db54896fa0de4b37439ae4f25971b5eb1708dd04f9a/watchfiles-0.20.0-cp37-abi3-win32.whl", hash = "sha256:a03d1e6feb7966b417f43c3e3783188167fd69c2063e86bad31e62c4ea794cc5", size = 268193 }, + { url = "https://files.pythonhosted.org/packages/87/79/098b1b1fcb6de16149d23283a2ab5dadce6a06b864e7a182d231f57a1f9e/watchfiles-0.20.0-cp37-abi3-win_amd64.whl", hash = "sha256:eccc8942bcdc7d638a01435d915b913255bbd66f018f1af051cd8afddb339ea3", size = 276723 }, + { url = "https://files.pythonhosted.org/packages/3f/82/45dddf4f5bf8b73ba27382cebb2bb3c0ee922c7ef77d936b86276aa39dca/watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c", size = 265344 }, +] + [[package]] name = "wcwidth" version = "0.2.13" @@ -5310,6 +7410,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, ] +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, +] + [[package]] name = "websockets" version = "14.1" @@ -5370,6 +7479,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498 }, ] +[[package]] +name = "wikipedia" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/35/25e68fbc99e672127cc6fbb14b8ec1ba3dfef035bf1e4c90f78f24a80b7d/wikipedia-1.4.0.tar.gz", hash = "sha256:db0fad1829fdd441b1852306e9856398204dc0786d2996dd2e0c8bb8e26133b2", size = 27748 } + [[package]] name = "win32-setctime" version = "1.2.0" @@ -5421,6 +7540,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594 }, ] +[[package]] +name = "wsproto" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/4a/44d3c295350d776427904d73c189e10aeae66d7f555bb2feee16d1e4ba5a/wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", size = 53425 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/58/e860788190eba3bcce367f74d29c4675466ce8dddfba85f7827588416f01/wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736", size = 24226 }, +] + [[package]] name = "xlsxwriter" version = "3.2.0" From f1d868f41c4055afc32ec9b28e0391ec44112421 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 14:30:52 -0800 Subject: [PATCH 075/110] cleanup delivery logic --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index c2257cbc2b08..52b7d9a3c543 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -216,15 +216,6 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) var registry = _clusterClient.GetGrain(0); //intentionally blocking var targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); - //verify targetAgentTypes is not null - if (targetAgentTypes is null || targetAgentTypes.Count == 0) - { - _logger.LogWarning("No agents found registered for event {Event}.", evt); - } - else - { - await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); - } // alternate path // get the event type and then send to all agents that are subscribed to that event type var eventType = evt.Type; @@ -235,12 +226,10 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) if (_subscriptionsByTopic.TryGetValue(source, out var agentTypesList2)) { agentTypes.AddRange(agentTypesList2); } if (_subscriptionsByTopic.TryGetValue(source + "." + eventType, out var agentTypesList3)) { agentTypes.AddRange(agentTypesList3); } agentTypes = agentTypes.Distinct().ToList(); - if (agentTypes.Count > 0) - { - await DispatchEventToAgentsAsync(agentTypes, evt: evt).ConfigureAwait(false); - } + targetAgentTypes.AddRange(agentTypes); + // instead of an exact match, we can also check for a prefix match where key starts with the eventType - else if (_subscriptionsByTopic.Keys.Any(key => key.StartsWith(eventType))) + if (_subscriptionsByTopic.Keys.Any(key => key.StartsWith(eventType))) { _subscriptionsByTopic.Where( kvp => kvp.Key.StartsWith(eventType)) @@ -249,9 +238,13 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) .ToList() .ForEach(async agentType => { - await DispatchEventToAgentsAsync(new List { agentType }, evt).ConfigureAwait(false); + targetAgentTypes.Add(agentType); }); } + if (targetAgentTypes is not null && targetAgentTypes.Any()) + { + await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); + } else { // log that no agent types were found From 73373e0a0c168fd75677af7577fcad6a8f75977e Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Tue, 21 Jan 2025 17:38:07 -0500 Subject: [PATCH 076/110] separate grpc tests to different ports, clean up start() and stop() --- .../AgentGrpcTests.cs | 100 ++++++++++-------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 9a9b16669330..4d143f2e604f 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -5,7 +5,6 @@ using System.Text.Json; using FluentAssertions; using Google.Protobuf.Reflection; -using Microsoft.AspNetCore.Builder; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -15,13 +14,8 @@ namespace Microsoft.AutoGen.Core.Grpc.Tests; -[Collection(GrpcClusterFixtureCollection.Name)] -public class AgentGrpcTests(GrpcRuntimeFixture fixture) +public class AgentGrpcTests { - private readonly GrpcRuntimeFixture _fixture = fixture; - // need a variable to store the runtime instance - public static WebApplication? Host { get; private set; } - /// /// Verify that if the agent is not initialized via AgentWorker, it should throw the correct exception. /// @@ -29,12 +23,12 @@ public class AgentGrpcTests(GrpcRuntimeFixture fixture) [Fact] public async Task Agent_ShouldThrowException_WhenNotInitialized() { - var agent = ActivatorUtilities.CreateInstance(_fixture.Client.Services); + using var runtime = new GrpcRuntime(); + var (_, agent) = runtime.Start(false); // Do not initialize + + // Expect an exception when calling SubscribeAsync because the agent is uninitialized await Assert.ThrowsAsync( - async () => - { - await agent.SubscribeAsync("TestEvent"); - } + async () => await agent.SubscribeAsync("TestEvent") ); } @@ -45,11 +39,12 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() [Fact] public async Task Agent_ShouldInitializeCorrectly() { - var (worker, agent) = _fixture.Start(); + using var runtime = new GrpcRuntime(); + runtime.Start(); + var (worker, agent) = runtime.Start(); Assert.Equal("GrpcAgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); - _fixture.Stop(); } /// /// Test SubscribeAsync method @@ -58,7 +53,8 @@ public async Task Agent_ShouldInitializeCorrectly() [Fact] public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() { - var (_, agent) = _fixture.Start(); + using var runtime = new GrpcRuntime(); + var (_, agent) = runtime.Start(); await agent.SubscribeAsync("TestEvent"); await Task.Delay(100); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); @@ -83,7 +79,6 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() } } Assert.False(found); - _fixture.Stop(); } /// @@ -93,7 +88,8 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() [Fact] public async Task StoreAsync_and_ReadAsyncTest() { - var (_, agent) = _fixture.Start(); + using var runtime = new GrpcRuntime(); + var (_, agent) = runtime.Start(); Dictionary state = new() { { "testdata", "Active" } @@ -107,7 +103,6 @@ await agent.StoreAsync(new AgentState var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); Assert.Equal("Active", value); - _fixture.Stop(); } /// @@ -117,7 +112,8 @@ await agent.StoreAsync(new AgentState [Fact] public async Task PublishMessageAsync_and_ReceiveMessageTest() { - var (_, agent) = _fixture.Start(); + using var runtime = new GrpcRuntime(); + var (_, agent) = runtime.Start(); await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); var found = false; @@ -137,7 +133,6 @@ await agent.PublishMessageAsync(new TextMessage() }).ConfigureAwait(true); await Task.Delay(10000); Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); - _fixture.Stop(); } [Fact] @@ -192,16 +187,25 @@ public Task Handle(int item) /// This fixture is used to provide a runtime for the agent tests. /// However, it is shared between tests. So operations from one test can affect another. /// -public sealed class GrpcRuntimeFixture +public sealed class GrpcRuntime : IDisposable { - public GrpcRuntimeFixture() + public IHost Client { get; private set; } + public IHost? AppHost { get; private set; } + + public GrpcRuntime() { Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - Environment.SetEnvironmentVariable("ASPNETCORE_HTTPS_PORTS", "53071"); - Environment.SetEnvironmentVariable("AGENT_HOST", "https://localhost:53071"); - AppHost = StartAppHostAsync().GetAwaiter().GetResult(); - Environment.SetEnvironmentVariable("ASPNETCORE_URLS", "https://+;http://+"); - Client = StartClientAsync().GetAwaiter().GetResult(); + AppHost = Host.CreateDefaultBuilder().Build(); + Client = Host.CreateDefaultBuilder().Build(); + } + + private static int GetAvailablePort() + { + using var listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Loopback, 0); + listener.Start(); + int port = ((System.Net.IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + return port; } private static async Task StartClientAsync() @@ -213,33 +217,45 @@ private static async Task StartAppHostAsync() return await Microsoft.AutoGen.Runtime.Grpc.Host.StartAsync(local: false, useGrpc: true).ConfigureAwait(false); } - public IHost Client { get; } - public IHost? AppHost { get; } /// - /// Start - starts the agent + /// Start - gets a new port and starts fresh instances /// - /// IAgentWorker, TestAgent - public (IAgentWorker, TestAgent) Start() + public (IAgentWorker, TestAgent) Start(bool initialize = true) { + int port = GetAvailablePort(); // Get a new port per test run + + // Update environment variables so each test runs independently + Environment.SetEnvironmentVariable("ASPNETCORE_HTTPS_PORTS", port.ToString()); + Environment.SetEnvironmentVariable("AGENT_HOST", $"https://localhost:{port}"); + + AppHost = StartAppHostAsync().GetAwaiter().GetResult(); + Client = StartClientAsync().GetAwaiter().GetResult(); + var agent = ActivatorUtilities.CreateInstance(Client.Services); var worker = Client.Services.GetRequiredService(); - Agent.Initialize(worker, agent); + if (initialize) + { + Agent.Initialize(worker, agent); + } + return (worker, agent); } + /// - /// Stop - stops the agent + /// Stop - stops the agent and ensures cleanup /// - /// void public void Stop() { - IHostApplicationLifetime hostApplicationLifetime = Client.Services.GetRequiredService(); - hostApplicationLifetime.StopApplication(); + Client?.StopAsync().GetAwaiter().GetResult(); + AppHost?.StopAsync().GetAwaiter().GetResult(); } -} -[CollectionDefinition(Name)] -public sealed class GrpcClusterFixtureCollection : ICollectionFixture -{ - public const string Name = nameof(GrpcClusterFixtureCollection); + /// + /// Dispose - Ensures cleanup after each test + /// + public void Dispose() + { + Stop(); + } } From 702cc132c005a31c4d013c17f3f519e2dd258deb Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 15:09:04 -0800 Subject: [PATCH 077/110] ensure its initialized --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 52b7d9a3c543..6ba91afbc166 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -215,7 +215,8 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) var registry = _clusterClient.GetGrain(0); //intentionally blocking - var targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); + var targetAgentTypes = new List(); + targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); // alternate path // get the event type and then send to all agents that are subscribed to that event type var eventType = evt.Type; From 61bf048d384fbaf20fd4a1055c2a5cd70ac34104 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 15:12:13 -0800 Subject: [PATCH 078/110] trying to avoid null --- .../Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 6ba91afbc166..507c3e4936cb 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -216,7 +216,7 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) var registry = _clusterClient.GetGrain(0); //intentionally blocking var targetAgentTypes = new List(); - targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); + targetAgentTypes.AddRange(await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true)); // alternate path // get the event type and then send to all agents that are subscribed to that event type var eventType = evt.Type; From 043ceeeb51de37e33f02f18f8452b00d40bf9d26 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 15:18:03 -0800 Subject: [PATCH 079/110] reducing multiple delivery --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 507c3e4936cb..3e1e0d4d5912 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -216,7 +216,11 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) var registry = _clusterClient.GetGrain(0); //intentionally blocking var targetAgentTypes = new List(); - targetAgentTypes.AddRange(await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true)); + var handlers = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); + if (handlers is not null && handlers.Any()) + { + targetAgentTypes.AddRange(handlers); + } // alternate path // get the event type and then send to all agents that are subscribed to that event type var eventType = evt.Type; @@ -226,9 +230,11 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) if (_subscriptionsByTopic.TryGetValue(eventType, out var agentTypesList)) { agentTypes.AddRange(agentTypesList); } if (_subscriptionsByTopic.TryGetValue(source, out var agentTypesList2)) { agentTypes.AddRange(agentTypesList2); } if (_subscriptionsByTopic.TryGetValue(source + "." + eventType, out var agentTypesList3)) { agentTypes.AddRange(agentTypesList3); } - agentTypes = agentTypes.Distinct().ToList(); - targetAgentTypes.AddRange(agentTypes); - + if (agentTypes is not null && agentTypes.Any()) + { + agentTypes = agentTypes.Distinct().ToList(); + targetAgentTypes.AddRange(agentTypes); + } // instead of an exact match, we can also check for a prefix match where key starts with the eventType if (_subscriptionsByTopic.Keys.Any(key => key.StartsWith(eventType))) { @@ -244,7 +250,7 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) } if (targetAgentTypes is not null && targetAgentTypes.Any()) { - await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); + await DispatchEventToAgentsAsync(targetAgentTypes.Distinct(), evt).ConfigureAwait(false); } else { From 8b65de9f14a2039e5ba7b868559ca6f2d840ac35 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 15:27:06 -0800 Subject: [PATCH 080/110] trying to reduce the number of deliveries --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 3e1e0d4d5912..01ebc265bc83 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -217,7 +217,7 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) //intentionally blocking var targetAgentTypes = new List(); var handlers = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); - if (handlers is not null && handlers.Any()) + if (handlers is not null && handlers.Count > 0) { targetAgentTypes.AddRange(handlers); } @@ -230,7 +230,7 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) if (_subscriptionsByTopic.TryGetValue(eventType, out var agentTypesList)) { agentTypes.AddRange(agentTypesList); } if (_subscriptionsByTopic.TryGetValue(source, out var agentTypesList2)) { agentTypes.AddRange(agentTypesList2); } if (_subscriptionsByTopic.TryGetValue(source + "." + eventType, out var agentTypesList3)) { agentTypes.AddRange(agentTypesList3); } - if (agentTypes is not null && agentTypes.Any()) + if (agentTypes is not null && agentTypes.Count > 0) { agentTypes = agentTypes.Distinct().ToList(); targetAgentTypes.AddRange(agentTypes); @@ -250,7 +250,8 @@ private async ValueTask DispatchEventAsync(CloudEvent evt) } if (targetAgentTypes is not null && targetAgentTypes.Any()) { - await DispatchEventToAgentsAsync(targetAgentTypes.Distinct(), evt).ConfigureAwait(false); + targetAgentTypes = targetAgentTypes.Distinct().ToList(); + await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); } else { From 4689eccecd19b13ea77105d8015a4279377391a2 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 16:30:57 -0800 Subject: [PATCH 081/110] fix open channel test --- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 4 +- .../GrpcGatewayServiceTests.cs | 42 +++++++++---------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 01ebc265bc83..93468b2ddb76 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -149,9 +149,9 @@ internal async Task ConnectToWorkerProcess(IAsyncStreamReader requestSt { _logger.LogInformation("Received new connection from {Peer}.", context.Peer); var workerProcess = new GrpcWorkerConnection(this, requestStream, responseStream, context); + _workers.GetOrAdd(workerProcess, workerProcess); + _workersByConnection.GetOrAdd(context.Peer, workerProcess); await workerProcess.Connect().ConfigureAwait(false); - _workers[workerProcess] = workerProcess; - _workersByConnection[context.Peer] = workerProcess; } internal async Task SendMessageAsync(GrpcWorkerConnection connection, CloudEvent cloudEvent, CancellationToken cancellationToken = default) { diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 5be9404adc66..2d002f432ac6 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -31,7 +31,7 @@ public async Task Test_OpenChannel() using var client = new TestGrpcClient(); gateway._workers.Count.Should().Be(0); - await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); + await OpenChannel(service, client); gateway._workers.Count.Should().Be(1); } @@ -42,12 +42,9 @@ public async Task Test_Message_Exchange_Through_Gateway() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - - await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - + await OpenChannel(service: service, client); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); @@ -61,7 +58,6 @@ public async Task Test_Message_Exchange_Through_Gateway() // Simulate an agent, by publishing a new message in the request stream var helloEvent = new Hello { Message = $"Hello test-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); client.AddMessage(new Message { CloudEvent = helloEvent }); - var helloMessageReceived = await client.ReadNext(); helloMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(Hello))); helloMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); @@ -74,15 +70,11 @@ public async Task Test_Message_Goes_To_Right_Worker() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - - await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - + await OpenChannel(service: service, client); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); - } [Fact] @@ -92,12 +84,9 @@ public async Task Test_RegisterAgent_Should_Succeed() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - - await service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); - + await OpenChannel(service: service, client); var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); response.Success.Should().BeTrue(); } @@ -109,10 +98,8 @@ public async Task Test_RegisterAgent_Should_Fail_For_Wrong_ConnectionId() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); using var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), "faulty_connection_id"), client.CallContext); response.Success.Should().BeFalse(); } @@ -124,9 +111,7 @@ public async Task Test_SaveState() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); var callContext = TestServerCallContext.Create(); - - var response = await service.SaveState(new AgentState { AgentId = new AgentId { Key = "", Type = "" } }, callContext); - + var response = await service.SaveState(new AgentState { AgentId = new AgentId { Key = "Test", Type = "test" } }, callContext); response.Should().NotBeNull(); } @@ -137,9 +122,7 @@ public async Task Test_GetState() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); var callContext = TestServerCallContext.Create(); - var response = await service.GetState(new AgentId { Key = "", Type = "" }, callContext); - response.Should().NotBeNull(); } @@ -152,10 +135,23 @@ private RegisterAgentTypeRequest CreateRegistrationRequest(AgentsMetadata eventT }; registration.Events.AddRange(eventTypes.GetEventsForAgent(type)?.ToList()); registration.Topics.AddRange(eventTypes.GetTopicsForAgent(type)?.ToList()); - return registration; } + private Task OpenChannel(GrpcGatewayService service, TestGrpcClient client) + { + var completion = new TaskCompletionSource(); + var _ = Task.Run(() => + { + completion.SetResult( + service.OpenChannel( + client.RequestStream, + client.ResponseStream, + client.CallContext + )); + }); + return completion.Task; + } private string GetFullName(Type type) { return ReflectionHelper.GetMessageDescriptor(type)!.FullName; From ad70e5daa675171f2dc4989f72bcd198c14bf536 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 16:59:58 -0800 Subject: [PATCH 082/110] update silobuilder test cluster --- .../Helpers/Orleans/SiloBuilderConfigurator.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs index fb345777a82b..bb960f7b1107 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Orleans/SiloBuilderConfigurator.cs @@ -15,7 +15,8 @@ public void Configure(ISiloBuilder siloBuilder) services.AddSerializer(a => a.AddProtobufSerializer()); }); siloBuilder.AddMemoryStreams("StreamProvider") - .AddMemoryGrainStorage("PubSubStore") - .AddMemoryGrainStorage("AgentStateStore"); + .AddMemoryGrainStorage("PubSubStore") + .AddMemoryGrainStorage("AgentRegistryStore") + .AddMemoryGrainStorage("AgentStateStore"); } } From dd1e45abcf37e6cb7e061a48712d80e807f444fa Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 17:34:11 -0800 Subject: [PATCH 083/110] cleanup open channel with cancellation --- .../GrpcGatewayServiceTests.cs | 24 ++++++++----------- .../Helpers/Grpc/TestGrpcClient.cs | 4 +++- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 2d002f432ac6..0a227c6862d9 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -21,18 +21,19 @@ public GrpcGatewayServiceTests(ClusterFixture fixture) { _fixture = fixture; } - // Test broadcast Event [Fact] public async Task Test_OpenChannel() { var logger = Mock.Of>(); var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); - using var client = new TestGrpcClient(); + var client = new TestGrpcClient(); gateway._workers.Count.Should().Be(0); - await OpenChannel(service, client); + var task = OpenChannel(service, client); gateway._workers.Count.Should().Be(1); + client.Dispose(); + await task; } [Fact] @@ -61,6 +62,8 @@ public async Task Test_Message_Exchange_Through_Gateway() var helloMessageReceived = await client.ReadNext(); helloMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(Hello))); helloMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); + client.Dispose(); + } [Fact] @@ -89,6 +92,8 @@ public async Task Test_RegisterAgent_Should_Succeed() await OpenChannel(service: service, client); var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); response.Success.Should().BeTrue(); + client.Dispose(); + } [Fact] @@ -102,6 +107,7 @@ public async Task Test_RegisterAgent_Should_Fail_For_Wrong_ConnectionId() var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), "faulty_connection_id"), client.CallContext); response.Success.Should().BeFalse(); + client.Dispose(); } [Fact] @@ -140,17 +146,7 @@ private RegisterAgentTypeRequest CreateRegistrationRequest(AgentsMetadata eventT private Task OpenChannel(GrpcGatewayService service, TestGrpcClient client) { - var completion = new TaskCompletionSource(); - var _ = Task.Run(() => - { - completion.SetResult( - service.OpenChannel( - client.RequestStream, - client.ResponseStream, - client.CallContext - )); - }); - return completion.Task; + return service.OpenChannel(client.RequestStream, client.ResponseStream, client.CallContext); } private string GetFullName(Type type) { diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs index 6795c9f9237f..e47f26eda159 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Helpers/Grpc/TestGrpcClient.cs @@ -10,9 +10,10 @@ internal sealed class TestGrpcClient : IDisposable public TestServerStreamWriter ResponseStream { get; } public TestServerCallContext CallContext { get; } + private CancellationTokenSource CallContextCancellation = new(); public TestGrpcClient() { - CallContext = TestServerCallContext.Create(); + CallContext = TestServerCallContext.Create(cancellationToken: CallContextCancellation.Token); RequestStream = new TestAsyncStreamReader(CallContext); ResponseStream = new TestServerStreamWriter(CallContext); } @@ -30,6 +31,7 @@ public void AddMessage(Message message) public void Dispose() { + CallContextCancellation.Cancel(); RequestStream.Dispose(); ResponseStream.Dispose(); } From cdea4209585fa58bfc530bff4ecea939f886297d Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 18:08:26 -0800 Subject: [PATCH 084/110] continue test cleanup --- .../GrpcGatewayServiceTests.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 0a227c6862d9..f33ae2bf1e61 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -42,10 +42,10 @@ public async Task Test_Message_Exchange_Through_Gateway() var logger = Mock.Of>(); var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); - using var client = new TestGrpcClient(); + var client = new TestGrpcClient(); var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - await OpenChannel(service: service, client); + var task = OpenChannel(service: service, client); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); @@ -63,7 +63,7 @@ public async Task Test_Message_Exchange_Through_Gateway() helloMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(Hello))); helloMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); client.Dispose(); - + await task; } [Fact] @@ -72,12 +72,14 @@ public async Task Test_Message_Goes_To_Right_Worker() var logger = Mock.Of>(); var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); - using var client = new TestGrpcClient(); + var client = new TestGrpcClient(); var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - await OpenChannel(service: service, client); + var task = OpenChannel(service: service, client); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); + client.Dispose(); + await task; } [Fact] @@ -86,14 +88,14 @@ public async Task Test_RegisterAgent_Should_Succeed() var logger = Mock.Of>(); var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); - using var client = new TestGrpcClient(); + var client = new TestGrpcClient(); var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - await OpenChannel(service: service, client); + var task = OpenChannel(service: service, client); var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); response.Success.Should().BeTrue(); client.Dispose(); - + await task; } [Fact] @@ -102,7 +104,7 @@ public async Task Test_RegisterAgent_Should_Fail_For_Wrong_ConnectionId() var logger = Mock.Of>(); var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); - using var client = new TestGrpcClient(); + var client = new TestGrpcClient(); var assembly = typeof(PBAgent).Assembly; var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), "faulty_connection_id"), client.CallContext); From 474a616cc40e082386ae896839d8f41b4925b3fe Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 19:12:43 -0800 Subject: [PATCH 085/110] remove unused --- dotnet/AutoGen.sln | 2 -- 1 file changed, 2 deletions(-) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 76a759e37692..3765c7c6f1c8 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -136,8 +136,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.AgentHost EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.Grpc.Tests", "test\Microsoft.AutoGen.Runtime.Grpc.Tests\Microsoft.AutoGen.Runtime.Grpc.Tests.csproj", "{0E7983BB-2602-421E-8B37-332E52870A10}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Tests.Shared", "test\Microsoft.AutoGen.Tests.Shared\Microsoft.AutoGen.Tests.Shared.csproj", "{14F90F79-580E-454D-BA7A-ED6D9723020D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Tests", "test\Microsoft.AutoGen.Core.Tests\Microsoft.AutoGen.Core.Tests.csproj", "{EAFFE339-26CB-4019-991D-BCCE8E7D33A1}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevTeam.ServiceDefaults", "samples\dev-team\DevTeam.ServiceDefaults\DevTeam.ServiceDefaults.csproj", "{599E1971-1DA9-453F-A7A8-42510BBC95C2}" From 97f24f1991819d3541ee34cc525d95cd1348a616 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 20:27:59 -0800 Subject: [PATCH 086/110] cleaning up dispatch and impoving test reliability --- dotnet/AutoGen.sln | 1 - .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 60 ++++++------------- .../Services/Grpc/GrpcWorkerConnection.cs | 3 +- .../Services/Orleans/RegistryGrain.cs | 32 +++++++--- .../AgentGrpcTests.cs | 4 +- 5 files changed, 46 insertions(+), 54 deletions(-) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 3765c7c6f1c8..28e133c5cca5 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -438,7 +438,6 @@ Global {3892C83E-7F5D-41DF-A88C-4854EAD38856} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {4CB42139-DEE4-40B9-AA81-1E4CCAA2F338} = {18BF8DD7-0585-48BF-8F97-AD333080CE06} {0E7983BB-2602-421E-8B37-332E52870A10} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} - {14F90F79-580E-454D-BA7A-ED6D9723020D} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {599E1971-1DA9-453F-A7A8-42510BBC95C2} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} {33A28A4B-123B-4416-9631-0F759B8D6172} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 93468b2ddb76..31cc4367af1f 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -157,7 +157,7 @@ internal async Task SendMessageAsync(GrpcWorkerConnection connection, CloudEvent { await connection.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); } - internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Message message) + internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Message message, CancellationToken cancellationToken = default) { _logger.LogInformation("Received message {Message} from connection {Connection}.", message, connection); switch (message.MessageCase) @@ -169,7 +169,7 @@ internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Mess DispatchResponse(connection, message.Response); break; case Message.MessageOneofCase.CloudEvent: - await DispatchEventAsync(message.CloudEvent); + await DispatchEventAsync(message.CloudEvent, cancellationToken); break; case Message.MessageOneofCase.RegisterAgentTypeRequest: await RegisterAgentTypeAsync(connection, message.RegisterAgentTypeRequest); @@ -210,53 +210,32 @@ private async ValueTask RegisterAgentTypeAsync(GrpcWorkerConnection connection, }; await connection.ResponseStream.WriteAsync(response).ConfigureAwait(false); } - private async ValueTask DispatchEventAsync(CloudEvent evt) + private async ValueTask DispatchEventAsync(CloudEvent evt, CancellationToken cancellationToken = default) { - var registry = _clusterClient.GetGrain(0); //intentionally blocking - var targetAgentTypes = new List(); - var handlers = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); - if (handlers is not null && handlers.Count > 0) - { - targetAgentTypes.AddRange(handlers); - } - // alternate path - // get the event type and then send to all agents that are subscribed to that event type - var eventType = evt.Type; - var source = evt.Source; - var agentTypes = new List(); - // ensure that we get agentTypes as an async enumerable list - try to get the value of agentTypes by topic and then cast it to an async enumerable list - if (_subscriptionsByTopic.TryGetValue(eventType, out var agentTypesList)) { agentTypes.AddRange(agentTypesList); } - if (_subscriptionsByTopic.TryGetValue(source, out var agentTypesList2)) { agentTypes.AddRange(agentTypesList2); } - if (_subscriptionsByTopic.TryGetValue(source + "." + eventType, out var agentTypesList3)) { agentTypes.AddRange(agentTypesList3); } - if (agentTypes is not null && agentTypes.Count > 0) - { - agentTypes = agentTypes.Distinct().ToList(); - targetAgentTypes.AddRange(agentTypes); - } - // instead of an exact match, we can also check for a prefix match where key starts with the eventType - if (_subscriptionsByTopic.Keys.Any(key => key.StartsWith(eventType))) - { - _subscriptionsByTopic.Where( - kvp => kvp.Key.StartsWith(eventType)) - .SelectMany(kvp => kvp.Value) - .Distinct() - .ToList() - .ForEach(async agentType => - { - targetAgentTypes.Add(agentType); - }); - } - if (targetAgentTypes is not null && targetAgentTypes.Any()) + var targetAgentTypes = await registry.GetSubscribedAndHandlingAgents(evt.Source, evt.Type).ConfigureAwait(true); + if (targetAgentTypes is not null && targetAgentTypes.Count > 0) { targetAgentTypes = targetAgentTypes.Distinct().ToList(); - await DispatchEventToAgentsAsync(targetAgentTypes, evt).ConfigureAwait(false); + var tasks = new List(targetAgentTypes.Count); + foreach (var agentType in targetAgentTypes) + { + if (_supportedAgentTypes.TryGetValue(agentType, out var connections)) + { + // if the connection is alive, add it to the set, if not remove the connection from the list + var activeConnections = connections.Where(c => c.Completion?.IsCompleted == false).ToList(); + foreach (var connection in activeConnections) + { + tasks.Add(this.SendMessageAsync(connection, evt, cancellationToken)); + } + } + } } else { // log that no agent types were found - _logger.LogWarning("No agent types found for event type {EventType}.", eventType); + _logger.LogWarning("No agent types found for event type {EventType}.", evt.Type); } } private async ValueTask DispatchRequestAsync(GrpcWorkerConnection connection, RpcRequest request) @@ -403,7 +382,6 @@ public async ValueTask UnsubscribeAsync(SubscriptionReques }; } } - public ValueTask> GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default) { return _gatewayRegistry.GetSubscriptions(nameof(type)); diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs index 00c777953688..65046642ed01 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcWorkerConnection.cs @@ -84,9 +84,8 @@ public async Task RunReadPump() { await foreach (var message in RequestStream.ReadAllAsync(_shutdownCancellationToken.Token)) { - // Fire and forget - _gateway.OnReceivedMessageAsync(this, message).Ignore(); + _gateway.OnReceivedMessageAsync(this, message, _shutdownCancellationToken.Token).Ignore(); } } catch (OperationCanceledException) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 5dce2b5ef649..26b0d379e14c 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -21,24 +21,40 @@ public override Task OnActivateAsync(CancellationToken cancellationToken) public ValueTask> GetSubscribedAndHandlingAgents(string topic, string eventType) { + List agents = []; // get all agent types that are subscribed to the topic if (state.State.TopicToAgentTypesMap.TryGetValue(topic, out var subscribedAgentTypes)) { // get all agent types that are handling the event if (state.State.EventsToAgentTypesMap.TryGetValue(eventType, out var handlingAgents)) { - // return the intersection of the two sets - return new(subscribedAgentTypes.Intersect(handlingAgents).ToList()); - } - else - { - return new(); + agents.AddRange(subscribedAgentTypes.Intersect(handlingAgents).ToList()); } } - else + if (state.State.TopicToAgentTypesMap.TryGetValue(eventType, out var eventHandlingAgents)) + { + agents.AddRange(eventHandlingAgents.ToList()); + } + if (state.State.TopicToAgentTypesMap.TryGetValue(topic + "." + eventType, out var combo)) + { + agents.AddRange(combo.ToList()); + } + // instead of an exact match, we can also check for a prefix match where key starts with the eventType + if (state.State.TopicToAgentTypesMap.Keys.Any(key => key.StartsWith(eventType))) { - return new(); + state.State.TopicToAgentTypesMap.Where( + kvp => kvp.Key.StartsWith(eventType)) + .SelectMany(kvp => kvp.Value) + .Distinct() + .ToList() + .ForEach(async agentType => + { + agents.Add(agentType); + }); } + agents = agents.Distinct().ToList(); + + return new ValueTask>(agents); } public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) { diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index 4d143f2e604f..aeac2fa5b2e0 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -40,9 +40,9 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() public async Task Agent_ShouldInitializeCorrectly() { using var runtime = new GrpcRuntime(); - runtime.Start(); var (worker, agent) = runtime.Start(); Assert.Equal("GrpcAgentWorker", worker.GetType().Name); + await Task.Delay(5000); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); } @@ -68,7 +68,7 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() } Assert.True(found); await agent.UnsubscribeAsync("TestEvent").ConfigureAwait(true); - await Task.Delay(500); + await Task.Delay(1000); subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); found = false; foreach (var subscription in subscriptions) From 045dcbbad38119457ca0dcab7f4ac87382aaacf0 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 20:30:24 -0800 Subject: [PATCH 087/110] format --- .../Runtime.Grpc/Services/Orleans/RegistryGrain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 26b0d379e14c..775ad1c65e94 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -53,7 +53,7 @@ public ValueTask> GetSubscribedAndHandlingAgents(string topic, stri }); } agents = agents.Distinct().ToList(); - + return new ValueTask>(agents); } public ValueTask<(IGateway? Worker, bool NewPlacement)> GetOrPlaceAgent(AgentId agentId) From b1cc82073f237a9b25cd95a5683c5871c320a239 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Tue, 21 Jan 2025 20:43:35 -0800 Subject: [PATCH 088/110] re-add missing project --- dotnet/AutoGen.sln | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 28e133c5cca5..55cd26736573 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -142,6 +142,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevTeam.ServiceDefaults", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Grpc.Tests", "test\Microsoft.AutoGen.Core.Grpc.Tests\Microsoft.AutoGen.Core.Grpc.Tests.csproj", "{33A28A4B-123B-4416-9631-0F759B8D6172}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.Tests.Shared", "test\Microsoft.Autogen.Tests.Shared\Microsoft.Autogen.Tests.Shared.csproj", "{58AD8E1D-83BD-4950-A324-1A20677D78D9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -376,6 +378,10 @@ Global {33A28A4B-123B-4416-9631-0F759B8D6172}.Debug|Any CPU.Build.0 = Debug|Any CPU {33A28A4B-123B-4416-9631-0F759B8D6172}.Release|Any CPU.ActiveCfg = Release|Any CPU {33A28A4B-123B-4416-9631-0F759B8D6172}.Release|Any CPU.Build.0 = Release|Any CPU + {58AD8E1D-83BD-4950-A324-1A20677D78D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58AD8E1D-83BD-4950-A324-1A20677D78D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58AD8E1D-83BD-4950-A324-1A20677D78D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58AD8E1D-83BD-4950-A324-1A20677D78D9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -441,6 +447,7 @@ Global {EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} {599E1971-1DA9-453F-A7A8-42510BBC95C2} = {05B9C173-6441-4DCA-9AC4-E897EF75F331} {33A28A4B-123B-4416-9631-0F759B8D6172} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} + {58AD8E1D-83BD-4950-A324-1A20677D78D9} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B} From 47ad20518dc02bdb9f216352ce4c03035b82255d Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 22 Jan 2025 08:35:01 -0800 Subject: [PATCH 089/110] running gen-proto --- .../runtimes/grpc/protos/agent_worker_pb2.py | 32 +++++----- .../runtimes/grpc/protos/agent_worker_pb2.pyi | 16 +++++ .../grpc/protos/agent_worker_pb2_grpc.py | 61 ++++++++++++++----- .../grpc/protos/agent_worker_pb2_grpc.pyi | 29 +++++++-- 4 files changed, 103 insertions(+), 35 deletions(-) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py index 76cd7f159b1a..24dde61576de 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.py @@ -16,7 +16,7 @@ from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x61gent_worker.proto\x12\x06\x61gents\x1a\x10\x63loudevent.proto\x1a\x19google/protobuf/any.proto\"\'\n\x07TopicId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"$\n\x07\x41gentId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"E\n\x07Payload\x12\x11\n\tdata_type\x18\x01 \x01(\t\x12\x19\n\x11\x64\x61ta_content_type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x89\x02\n\nRpcRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12$\n\x06source\x18\x02 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12\x1f\n\x06target\x18\x03 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0e\n\x06method\x18\x04 \x01(\t\x12 \n\x07payload\x18\x05 \x01(\x0b\x32\x0f.agents.Payload\x12\x32\n\x08metadata\x18\x06 \x03(\x0b\x32 .agents.RpcRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\xb8\x01\n\x0bRpcResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12 \n\x07payload\x18\x02 \x01(\x0b\x32\x0f.agents.Payload\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x33\n\x08metadata\x18\x04 \x03(\x0b\x32!.agents.RpcResponse.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe4\x01\n\x05\x45vent\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x14\n\x0ctopic_source\x18\x02 \x01(\t\x12$\n\x06source\x18\x03 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12 \n\x07payload\x18\x04 \x01(\x0b\x32\x0f.agents.Payload\x12-\n\x08metadata\x18\x05 \x03(\x0b\x32\x1b.agents.Event.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\\\n\x18RegisterAgentTypeRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06\x65vents\x18\x03 \x03(\t\x12\x0e\n\x06topics\x18\x04 \x03(\t\"^\n\x19RegisterAgentTypeResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\":\n\x10TypeSubscription\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"G\n\x16TypePrefixSubscription\x12\x19\n\x11topic_type_prefix\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"\x96\x01\n\x0cSubscription\x12\x34\n\x10typeSubscription\x18\x01 \x01(\x0b\x32\x18.agents.TypeSubscriptionH\x00\x12@\n\x16typePrefixSubscription\x18\x02 \x01(\x0b\x32\x1e.agents.TypePrefixSubscriptionH\x00\x42\x0e\n\x0csubscription\"U\n\x13SubscriptionRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12*\n\x0csubscription\x18\x02 \x01(\x0b\x32\x14.agents.Subscription\"Y\n\x14SubscriptionResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x9d\x01\n\nAgentState\x12!\n\x08\x61gent_id\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0c\n\x04\x65Tag\x18\x02 \x01(\t\x12\x15\n\x0b\x62inary_data\x18\x03 \x01(\x0cH\x00\x12\x13\n\ttext_data\x18\x04 \x01(\tH\x00\x12*\n\nproto_data\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x06\n\x04\x64\x61ta\"j\n\x10GetStateResponse\x12\'\n\x0b\x61gent_state\x18\x01 \x01(\x0b\x32\x12.agents.AgentState\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"B\n\x11SaveStateResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\xa1\x03\n\x07Message\x12%\n\x07request\x18\x01 \x01(\x0b\x32\x12.agents.RpcRequestH\x00\x12\'\n\x08response\x18\x02 \x01(\x0b\x32\x13.agents.RpcResponseH\x00\x12\x33\n\ncloudEvent\x18\x03 \x01(\x0b\x32\x1d.io.cloudevents.v1.CloudEventH\x00\x12\x44\n\x18registerAgentTypeRequest\x18\x04 \x01(\x0b\x32 .agents.RegisterAgentTypeRequestH\x00\x12\x46\n\x19registerAgentTypeResponse\x18\x05 \x01(\x0b\x32!.agents.RegisterAgentTypeResponseH\x00\x12:\n\x13SubscriptionRequest\x18\x06 \x01(\x0b\x32\x1b.agents.SubscriptionRequestH\x00\x12<\n\x14SubscriptionResponse\x18\x07 \x01(\x0b\x32\x1c.agents.SubscriptionResponseH\x00\x42\t\n\x07message2\xa7\x03\n\x08\x41gentRpc\x12\x33\n\x0bOpenChannel\x12\x0f.agents.Message\x1a\x0f.agents.Message(\x01\x30\x01\x12\x35\n\x08GetState\x12\x0f.agents.AgentId\x1a\x18.agents.GetStateResponse\x12:\n\tSaveState\x12\x12.agents.AgentState\x1a\x19.agents.SaveStateResponse\x12T\n\rRegisterAgent\x12 .agents.RegisterAgentTypeRequest\x1a!.agents.RegisterAgentTypeResponse\x12L\n\x0f\x41\x64\x64Subscription\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponse\x12O\n\x12RemoveSubscription\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponseB\x1e\xaa\x02\x1bMicrosoft.AutoGen.Contractsb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x61gent_worker.proto\x12\x06\x61gents\x1a\x10\x63loudevent.proto\x1a\x19google/protobuf/any.proto\"\'\n\x07TopicId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06source\x18\x02 \x01(\t\"$\n\x07\x41gentId\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"E\n\x07Payload\x12\x11\n\tdata_type\x18\x01 \x01(\t\x12\x19\n\x11\x64\x61ta_content_type\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x89\x02\n\nRpcRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12$\n\x06source\x18\x02 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12\x1f\n\x06target\x18\x03 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0e\n\x06method\x18\x04 \x01(\t\x12 \n\x07payload\x18\x05 \x01(\x0b\x32\x0f.agents.Payload\x12\x32\n\x08metadata\x18\x06 \x03(\x0b\x32 .agents.RpcRequest.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\xb8\x01\n\x0bRpcResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12 \n\x07payload\x18\x02 \x01(\x0b\x32\x0f.agents.Payload\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12\x33\n\x08metadata\x18\x04 \x03(\x0b\x32!.agents.RpcResponse.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe4\x01\n\x05\x45vent\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x14\n\x0ctopic_source\x18\x02 \x01(\t\x12$\n\x06source\x18\x03 \x01(\x0b\x32\x0f.agents.AgentIdH\x00\x88\x01\x01\x12 \n\x07payload\x18\x04 \x01(\x0b\x32\x0f.agents.Payload\x12-\n\x08metadata\x18\x05 \x03(\x0b\x32\x1b.agents.Event.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\t\n\x07_source\"\\\n\x18RegisterAgentTypeRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06\x65vents\x18\x03 \x03(\t\x12\x0e\n\x06topics\x18\x04 \x03(\t\"^\n\x19RegisterAgentTypeResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\":\n\x10TypeSubscription\x12\x12\n\ntopic_type\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"G\n\x16TypePrefixSubscription\x12\x19\n\x11topic_type_prefix\x18\x01 \x01(\t\x12\x12\n\nagent_type\x18\x02 \x01(\t\"\x96\x01\n\x0cSubscription\x12\x34\n\x10typeSubscription\x18\x01 \x01(\x0b\x32\x18.agents.TypeSubscriptionH\x00\x12@\n\x16typePrefixSubscription\x18\x02 \x01(\x0b\x32\x1e.agents.TypePrefixSubscriptionH\x00\x42\x0e\n\x0csubscription\"?\n\x10SubscriptionList\x12+\n\rsubscriptions\x18\x01 \x03(\x0b\x32\x14.agents.Subscription\"U\n\x13SubscriptionRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12*\n\x0csubscription\x18\x02 \x01(\x0b\x32\x14.agents.Subscription\"Y\n\x14SubscriptionResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x9d\x01\n\nAgentState\x12!\n\x08\x61gent_id\x18\x01 \x01(\x0b\x32\x0f.agents.AgentId\x12\x0c\n\x04\x65Tag\x18\x02 \x01(\t\x12\x15\n\x0b\x62inary_data\x18\x03 \x01(\x0cH\x00\x12\x13\n\ttext_data\x18\x04 \x01(\tH\x00\x12*\n\nproto_data\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x06\n\x04\x64\x61ta\"j\n\x10GetStateResponse\x12\'\n\x0b\x61gent_state\x18\x01 \x01(\x0b\x32\x12.agents.AgentState\x12\x0f\n\x07success\x18\x02 \x01(\x08\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"B\n\x11SaveStateResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\xa1\x03\n\x07Message\x12%\n\x07request\x18\x01 \x01(\x0b\x32\x12.agents.RpcRequestH\x00\x12\'\n\x08response\x18\x02 \x01(\x0b\x32\x13.agents.RpcResponseH\x00\x12\x33\n\ncloudEvent\x18\x03 \x01(\x0b\x32\x1d.io.cloudevents.v1.CloudEventH\x00\x12\x44\n\x18registerAgentTypeRequest\x18\x04 \x01(\x0b\x32 .agents.RegisterAgentTypeRequestH\x00\x12\x46\n\x19registerAgentTypeResponse\x18\x05 \x01(\x0b\x32!.agents.RegisterAgentTypeResponseH\x00\x12:\n\x13SubscriptionRequest\x18\x06 \x01(\x0b\x32\x1b.agents.SubscriptionRequestH\x00\x12<\n\x14SubscriptionResponse\x18\x07 \x01(\x0b\x32\x1c.agents.SubscriptionResponseH\x00\x42\t\n\x07message2\xd9\x03\n\x08\x41gentRpc\x12\x33\n\x0bOpenChannel\x12\x0f.agents.Message\x1a\x0f.agents.Message(\x01\x30\x01\x12\x35\n\x08GetState\x12\x0f.agents.AgentId\x1a\x18.agents.GetStateResponse\x12:\n\tSaveState\x12\x12.agents.AgentState\x1a\x19.agents.SaveStateResponse\x12T\n\rRegisterAgent\x12 .agents.RegisterAgentTypeRequest\x1a!.agents.RegisterAgentTypeResponse\x12\x46\n\tSubscribe\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponse\x12H\n\x0bUnsubscribe\x12\x1b.agents.SubscriptionRequest\x1a\x1c.agents.SubscriptionResponse\x12=\n\x10GetSubscriptions\x12\x0f.agents.AgentId\x1a\x18.agents.SubscriptionListB\x1e\xaa\x02\x1bMicrosoft.AutoGen.Contractsb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -58,18 +58,20 @@ _globals['_TYPEPREFIXSUBSCRIPTION']._serialized_end=1232 _globals['_SUBSCRIPTION']._serialized_start=1235 _globals['_SUBSCRIPTION']._serialized_end=1385 - _globals['_SUBSCRIPTIONREQUEST']._serialized_start=1387 - _globals['_SUBSCRIPTIONREQUEST']._serialized_end=1472 - _globals['_SUBSCRIPTIONRESPONSE']._serialized_start=1474 - _globals['_SUBSCRIPTIONRESPONSE']._serialized_end=1563 - _globals['_AGENTSTATE']._serialized_start=1566 - _globals['_AGENTSTATE']._serialized_end=1723 - _globals['_GETSTATERESPONSE']._serialized_start=1725 - _globals['_GETSTATERESPONSE']._serialized_end=1831 - _globals['_SAVESTATERESPONSE']._serialized_start=1833 - _globals['_SAVESTATERESPONSE']._serialized_end=1899 - _globals['_MESSAGE']._serialized_start=1902 - _globals['_MESSAGE']._serialized_end=2319 - _globals['_AGENTRPC']._serialized_start=2322 - _globals['_AGENTRPC']._serialized_end=2745 + _globals['_SUBSCRIPTIONLIST']._serialized_start=1387 + _globals['_SUBSCRIPTIONLIST']._serialized_end=1450 + _globals['_SUBSCRIPTIONREQUEST']._serialized_start=1452 + _globals['_SUBSCRIPTIONREQUEST']._serialized_end=1537 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_start=1539 + _globals['_SUBSCRIPTIONRESPONSE']._serialized_end=1628 + _globals['_AGENTSTATE']._serialized_start=1631 + _globals['_AGENTSTATE']._serialized_end=1788 + _globals['_GETSTATERESPONSE']._serialized_start=1790 + _globals['_GETSTATERESPONSE']._serialized_end=1896 + _globals['_SAVESTATERESPONSE']._serialized_start=1898 + _globals['_SAVESTATERESPONSE']._serialized_end=1964 + _globals['_MESSAGE']._serialized_start=1967 + _globals['_MESSAGE']._serialized_end=2384 + _globals['_AGENTRPC']._serialized_start=2387 + _globals['_AGENTRPC']._serialized_end=2860 # @@protoc_insertion_point(module_scope) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi index ff0ec2e9c801..899c625e53e3 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2.pyi @@ -321,6 +321,22 @@ class Subscription(google.protobuf.message.Message): global___Subscription = Subscription +@typing.final +class SubscriptionList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SUBSCRIPTIONS_FIELD_NUMBER: builtins.int + @property + def subscriptions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Subscription]: ... + def __init__( + self, + *, + subscriptions: collections.abc.Iterable[global___Subscription] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["subscriptions", b"subscriptions"]) -> None: ... + +global___SubscriptionList = SubscriptionList + @typing.final class SubscriptionRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py index c363d9968034..d5c4a33f0e00 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.py @@ -34,16 +34,21 @@ def __init__(self, channel): request_serializer=agent__worker__pb2.RegisterAgentTypeRequest.SerializeToString, response_deserializer=agent__worker__pb2.RegisterAgentTypeResponse.FromString, ) - self.AddSubscription = channel.unary_unary( - '/agents.AgentRpc/AddSubscription', + self.Subscribe = channel.unary_unary( + '/agents.AgentRpc/Subscribe', request_serializer=agent__worker__pb2.SubscriptionRequest.SerializeToString, response_deserializer=agent__worker__pb2.SubscriptionResponse.FromString, ) - self.RemoveSubscription = channel.unary_unary( - '/agents.AgentRpc/RemoveSubscription', + self.Unsubscribe = channel.unary_unary( + '/agents.AgentRpc/Unsubscribe', request_serializer=agent__worker__pb2.SubscriptionRequest.SerializeToString, response_deserializer=agent__worker__pb2.SubscriptionResponse.FromString, ) + self.GetSubscriptions = channel.unary_unary( + '/agents.AgentRpc/GetSubscriptions', + request_serializer=agent__worker__pb2.AgentId.SerializeToString, + response_deserializer=agent__worker__pb2.SubscriptionList.FromString, + ) class AgentRpcServicer(object): @@ -73,13 +78,19 @@ def RegisterAgent(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') - def AddSubscription(self, request, context): + def Subscribe(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Unsubscribe(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') - def RemoveSubscription(self, request, context): + def GetSubscriptions(self, request, context): """Missing associated documentation comment in .proto file.""" context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -108,16 +119,21 @@ def add_AgentRpcServicer_to_server(servicer, server): request_deserializer=agent__worker__pb2.RegisterAgentTypeRequest.FromString, response_serializer=agent__worker__pb2.RegisterAgentTypeResponse.SerializeToString, ), - 'AddSubscription': grpc.unary_unary_rpc_method_handler( - servicer.AddSubscription, + 'Subscribe': grpc.unary_unary_rpc_method_handler( + servicer.Subscribe, request_deserializer=agent__worker__pb2.SubscriptionRequest.FromString, response_serializer=agent__worker__pb2.SubscriptionResponse.SerializeToString, ), - 'RemoveSubscription': grpc.unary_unary_rpc_method_handler( - servicer.RemoveSubscription, + 'Unsubscribe': grpc.unary_unary_rpc_method_handler( + servicer.Unsubscribe, request_deserializer=agent__worker__pb2.SubscriptionRequest.FromString, response_serializer=agent__worker__pb2.SubscriptionResponse.SerializeToString, ), + 'GetSubscriptions': grpc.unary_unary_rpc_method_handler( + servicer.GetSubscriptions, + request_deserializer=agent__worker__pb2.AgentId.FromString, + response_serializer=agent__worker__pb2.SubscriptionList.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'agents.AgentRpc', rpc_method_handlers) @@ -197,7 +213,7 @@ def RegisterAgent(request, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def AddSubscription(request, + def Subscribe(request, target, options=(), channel_credentials=None, @@ -207,14 +223,14 @@ def AddSubscription(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/AddSubscription', + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/Subscribe', agent__worker__pb2.SubscriptionRequest.SerializeToString, agent__worker__pb2.SubscriptionResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def RemoveSubscription(request, + def Unsubscribe(request, target, options=(), channel_credentials=None, @@ -224,8 +240,25 @@ def RemoveSubscription(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/RemoveSubscription', + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/Unsubscribe', agent__worker__pb2.SubscriptionRequest.SerializeToString, agent__worker__pb2.SubscriptionResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetSubscriptions(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/agents.AgentRpc/GetSubscriptions', + agent__worker__pb2.AgentId.SerializeToString, + agent__worker__pb2.SubscriptionList.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi index 94539461f70c..15ebf39d0d96 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/protos/agent_worker_pb2_grpc.pyi @@ -39,16 +39,21 @@ class AgentRpcStub: agent_worker_pb2.RegisterAgentTypeResponse, ] - AddSubscription: grpc.UnaryUnaryMultiCallable[ + Subscribe: grpc.UnaryUnaryMultiCallable[ agent_worker_pb2.SubscriptionRequest, agent_worker_pb2.SubscriptionResponse, ] - RemoveSubscription: grpc.UnaryUnaryMultiCallable[ + Unsubscribe: grpc.UnaryUnaryMultiCallable[ agent_worker_pb2.SubscriptionRequest, agent_worker_pb2.SubscriptionResponse, ] + GetSubscriptions: grpc.UnaryUnaryMultiCallable[ + agent_worker_pb2.AgentId, + agent_worker_pb2.SubscriptionList, + ] + class AgentRpcAsyncStub: OpenChannel: grpc.aio.StreamStreamMultiCallable[ agent_worker_pb2.Message, @@ -70,16 +75,21 @@ class AgentRpcAsyncStub: agent_worker_pb2.RegisterAgentTypeResponse, ] - AddSubscription: grpc.aio.UnaryUnaryMultiCallable[ + Subscribe: grpc.aio.UnaryUnaryMultiCallable[ agent_worker_pb2.SubscriptionRequest, agent_worker_pb2.SubscriptionResponse, ] - RemoveSubscription: grpc.aio.UnaryUnaryMultiCallable[ + Unsubscribe: grpc.aio.UnaryUnaryMultiCallable[ agent_worker_pb2.SubscriptionRequest, agent_worker_pb2.SubscriptionResponse, ] + GetSubscriptions: grpc.aio.UnaryUnaryMultiCallable[ + agent_worker_pb2.AgentId, + agent_worker_pb2.SubscriptionList, + ] + class AgentRpcServicer(metaclass=abc.ABCMeta): @abc.abstractmethod def OpenChannel( @@ -110,17 +120,24 @@ class AgentRpcServicer(metaclass=abc.ABCMeta): ) -> typing.Union[agent_worker_pb2.RegisterAgentTypeResponse, collections.abc.Awaitable[agent_worker_pb2.RegisterAgentTypeResponse]]: ... @abc.abstractmethod - def AddSubscription( + def Subscribe( self, request: agent_worker_pb2.SubscriptionRequest, context: _ServicerContext, ) -> typing.Union[agent_worker_pb2.SubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.SubscriptionResponse]]: ... @abc.abstractmethod - def RemoveSubscription( + def Unsubscribe( self, request: agent_worker_pb2.SubscriptionRequest, context: _ServicerContext, ) -> typing.Union[agent_worker_pb2.SubscriptionResponse, collections.abc.Awaitable[agent_worker_pb2.SubscriptionResponse]]: ... + @abc.abstractmethod + def GetSubscriptions( + self, + request: agent_worker_pb2.AgentId, + context: _ServicerContext, + ) -> typing.Union[agent_worker_pb2.SubscriptionList, collections.abc.Awaitable[agent_worker_pb2.SubscriptionList]]: ... + def add_AgentRpcServicer_to_server(servicer: AgentRpcServicer, server: typing.Union[grpc.Server, grpc.aio.Server]) -> None: ... From f5b5c2832d93a654ab0d546343ab09e6f444b3da Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 13:33:46 -0500 Subject: [PATCH 090/110] reverse build and format --- .github/workflows/dotnet-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 67105c844801..f34e9ab68ebc 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -93,15 +93,15 @@ jobs: run: | # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config dotnet restore -bl + - name: Build + run: | + echo "Build AutoGen" + dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true - name: Format check run: | echo "Format check" echo "If you see any error in this step, please run 'dotnet format' locally to format the code." dotnet format --verify-no-changes -v diag --no-restore - - name: Build - run: | - echo "Build AutoGen" - dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true - name: Unit Test run: dotnet test --no-build -bl --configuration Release --filter type=!integration From 6e85aceb8b3a745de90ce3f8e71671d212711fca Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 13:39:34 -0500 Subject: [PATCH 091/110] revert --- .github/workflows/dotnet-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index f34e9ab68ebc..67105c844801 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -93,15 +93,15 @@ jobs: run: | # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config dotnet restore -bl - - name: Build - run: | - echo "Build AutoGen" - dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true - name: Format check run: | echo "Format check" echo "If you see any error in this step, please run 'dotnet format' locally to format the code." dotnet format --verify-no-changes -v diag --no-restore + - name: Build + run: | + echo "Build AutoGen" + dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true - name: Unit Test run: dotnet test --no-build -bl --configuration Release --filter type=!integration From 5263e3ab7fbb0b173f4f1d02dca79bc3c7bb66eb Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:04:41 -0500 Subject: [PATCH 092/110] print out restore paths --- .github/workflows/dotnet-build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 67105c844801..e03ce1242048 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -149,6 +149,11 @@ jobs: run: dotnet --version && dotnet dev-certs https --trust - name: Restore dependencies run: | + ls /home/runner/work/autogen/autogen/dotnet/test/ + ls /home/runner/work/autogen/autogen/dotnet/test/Microsoft.AutoGen.Tests.Shared + ls /home/runner/work/autogen/autogen/dotnet/src + ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen + ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen/AgentHost dotnet restore -bl - name: Build run: | From a0e086b7a9b69aa90334d4a5b075ef805c07632c Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:09:31 -0500 Subject: [PATCH 093/110] print paths --- .github/workflows/dotnet-build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index e03ce1242048..370431b0a890 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -92,6 +92,11 @@ jobs: - name: Restore dependencies run: | # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config + ls /home/runner/work/autogen/autogen/dotnet/test/ + ls /home/runner/work/autogen/autogen/dotnet/test/Microsoft.AutoGen.Tests.Shared + ls /home/runner/work/autogen/autogen/dotnet/src + ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen + ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen/AgentHost dotnet restore -bl - name: Format check run: | @@ -149,11 +154,6 @@ jobs: run: dotnet --version && dotnet dev-certs https --trust - name: Restore dependencies run: | - ls /home/runner/work/autogen/autogen/dotnet/test/ - ls /home/runner/work/autogen/autogen/dotnet/test/Microsoft.AutoGen.Tests.Shared - ls /home/runner/work/autogen/autogen/dotnet/src - ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen - ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen/AgentHost dotnet restore -bl - name: Build run: | From 742b44e4234f24cf530fa80cbcb24e7d26dabc61 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 22 Jan 2025 11:11:53 -0800 Subject: [PATCH 094/110] add using in .csproj --- .../GrpcGatewayServiceTests.cs | 1 - .../Microsoft.AutoGen.Runtime.Grpc.Tests.csproj | 1 + dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index f33ae2bf1e61..ce9f80e53a87 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -8,7 +8,6 @@ using Microsoft.AutoGen.Runtime.Grpc.Tests.Helpers.Orleans; using Microsoft.Extensions.Logging; using Moq; -using Tests.Events; using NewMessageReceived = Tests.Events.NewMessageReceived; namespace Microsoft.AutoGen.Runtime.Grpc.Tests; diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj index 23e3794606e1..ab0899c0f169 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/Microsoft.AutoGen.Runtime.Grpc.Tests.csproj @@ -20,6 +20,7 @@ + diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs index 655a14cb418a..1984501871a9 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/TestAgent.cs @@ -5,7 +5,6 @@ using Microsoft.AutoGen.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Tests.Events; namespace Microsoft.AutoGen.Runtime.Grpc.Tests; From ab1ea0296bcb21d2d67db0c146a7136b83b09be5 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 22 Jan 2025 11:16:30 -0800 Subject: [PATCH 095/110] fix build error --- .github/workflows/dotnet-build.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 370431b0a890..c21f8c76d37f 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -92,11 +92,9 @@ jobs: - name: Restore dependencies run: | # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config - ls /home/runner/work/autogen/autogen/dotnet/test/ - ls /home/runner/work/autogen/autogen/dotnet/test/Microsoft.AutoGen.Tests.Shared - ls /home/runner/work/autogen/autogen/dotnet/src - ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen - ls /home/runner/work/autogen/autogen/dotnet/src/Microsoft.AutoGen/AgentHost + + # ls all sub-directories under dotnet folder + ls -R ./dotnet dotnet restore -bl - name: Format check run: | From 5676b6bf185a67e910b00154da811cd3e2c04a69 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 22 Jan 2025 11:19:02 -0800 Subject: [PATCH 096/110] fix build error --- .github/workflows/dotnet-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index c21f8c76d37f..5491f56293dc 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -94,7 +94,7 @@ jobs: # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config # ls all sub-directories under dotnet folder - ls -R ./dotnet + ls -R . dotnet restore -bl - name: Format check run: | From 6df60dce716db891cf4c3ac819e7860bb907b561 Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:44:33 -0500 Subject: [PATCH 097/110] partial move --- dotnet/AutoGen.sln | 2 +- .../Microsoft.Autogen.Tests.Shared.csproj2} | 0 .../Protos/messages.proto | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename dotnet/test/{Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj => Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2} (100%) rename dotnet/test/{Microsoft.Autogen.Tests.Shared => Microsoft.Autogen.Tests.Shared2}/Protos/messages.proto (100%) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index 55cd26736573..e3115912a20d 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -142,7 +142,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevTeam.ServiceDefaults", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Grpc.Tests", "test\Microsoft.AutoGen.Core.Grpc.Tests\Microsoft.AutoGen.Core.Grpc.Tests.csproj", "{33A28A4B-123B-4416-9631-0F759B8D6172}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.Tests.Shared", "test\Microsoft.Autogen.Tests.Shared\Microsoft.Autogen.Tests.Shared.csproj", "{58AD8E1D-83BD-4950-A324-1A20677D78D9}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Tests.Shared", "test\Microsoft.AutoGen.Tests.Shared\Microsoft.AutoGen.Tests.Shared.csproj", "{58AD8E1D-83BD-4950-A324-1A20677D78D9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj b/dotnet/test/Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2 similarity index 100% rename from dotnet/test/Microsoft.Autogen.Tests.Shared/Microsoft.Autogen.Tests.Shared.csproj rename to dotnet/test/Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2 diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto b/dotnet/test/Microsoft.Autogen.Tests.Shared2/Protos/messages.proto similarity index 100% rename from dotnet/test/Microsoft.Autogen.Tests.Shared/Protos/messages.proto rename to dotnet/test/Microsoft.Autogen.Tests.Shared2/Protos/messages.proto From 9a975aee570e0ffde17c02ec377d2f268da1418c Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:45:43 -0500 Subject: [PATCH 098/110] part 2 move --- .../Microsoft.AutoGen.Tests.Shared.csproj} | 0 .../Protos/messages.proto | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename dotnet/test/{Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2 => Microsoft.AutoGen.Tests.Shared/Microsoft.AutoGen.Tests.Shared.csproj} (100%) rename dotnet/test/{Microsoft.Autogen.Tests.Shared2 => Microsoft.AutoGen.Tests.Shared}/Protos/messages.proto (100%) diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2 b/dotnet/test/Microsoft.AutoGen.Tests.Shared/Microsoft.AutoGen.Tests.Shared.csproj similarity index 100% rename from dotnet/test/Microsoft.Autogen.Tests.Shared2/Microsoft.Autogen.Tests.Shared.csproj2 rename to dotnet/test/Microsoft.AutoGen.Tests.Shared/Microsoft.AutoGen.Tests.Shared.csproj diff --git a/dotnet/test/Microsoft.Autogen.Tests.Shared2/Protos/messages.proto b/dotnet/test/Microsoft.AutoGen.Tests.Shared/Protos/messages.proto similarity index 100% rename from dotnet/test/Microsoft.Autogen.Tests.Shared2/Protos/messages.proto rename to dotnet/test/Microsoft.AutoGen.Tests.Shared/Protos/messages.proto From 8871b6543e89d74a8057871fa7ef304b3b57aee7 Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:51:13 -0500 Subject: [PATCH 099/110] partial move agenthost --- dotnet/AutoGen.sln | 2 +- dotnet/samples/Hello/Hello.AppHost/Hello.AppHost.csproj | 2 +- ...gen.AgentHost.csproj => Microsoft.Autogen.AgentHost.csproj2} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename dotnet/src/Microsoft.AutoGen/AgentHost/{Microsoft.Autogen.AgentHost.csproj => Microsoft.Autogen.AgentHost.csproj2} (100%) diff --git a/dotnet/AutoGen.sln b/dotnet/AutoGen.sln index e3115912a20d..7c747bd70cc2 100644 --- a/dotnet/AutoGen.sln +++ b/dotnet/AutoGen.sln @@ -132,7 +132,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.G EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Agents", "src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj", "{3892C83E-7F5D-41DF-A88C-4854EAD38856}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Autogen.AgentHost", "src\Microsoft.AutoGen\AgentHost\Microsoft.Autogen.AgentHost.csproj", "{4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.AgentHost", "src\Microsoft.AutoGen\AgentHost\Microsoft.AutoGen.AgentHost.csproj", "{4CB42139-DEE4-40B9-AA81-1E4CCAA2F338}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Runtime.Grpc.Tests", "test\Microsoft.AutoGen.Runtime.Grpc.Tests\Microsoft.AutoGen.Runtime.Grpc.Tests.csproj", "{0E7983BB-2602-421E-8B37-332E52870A10}" EndProject diff --git a/dotnet/samples/Hello/Hello.AppHost/Hello.AppHost.csproj b/dotnet/samples/Hello/Hello.AppHost/Hello.AppHost.csproj index aa714b1b727b..275544280aba 100644 --- a/dotnet/samples/Hello/Hello.AppHost/Hello.AppHost.csproj +++ b/dotnet/samples/Hello/Hello.AppHost/Hello.AppHost.csproj @@ -18,7 +18,7 @@ - + diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj b/dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj2 similarity index 100% rename from dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj rename to dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj2 From 80b9fe2838564fa7224eab8b298067ca7d63af95 Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:51:42 -0500 Subject: [PATCH 100/110] full move agenthost --- ...togen.AgentHost.csproj2 => Microsoft.AutoGen.AgentHost.csproj} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dotnet/src/Microsoft.AutoGen/AgentHost/{Microsoft.Autogen.AgentHost.csproj2 => Microsoft.AutoGen.AgentHost.csproj} (100%) diff --git a/dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj2 b/dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.AutoGen.AgentHost.csproj similarity index 100% rename from dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.Autogen.AgentHost.csproj2 rename to dotnet/src/Microsoft.AutoGen/AgentHost/Microsoft.AutoGen.AgentHost.csproj From 89988f115ebd2fa767fe5fd70970bf6c7ae7849c Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:52:56 -0500 Subject: [PATCH 101/110] revert ls in restore --- .github/workflows/dotnet-build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/dotnet-build.yml b/.github/workflows/dotnet-build.yml index 5491f56293dc..67105c844801 100644 --- a/.github/workflows/dotnet-build.yml +++ b/.github/workflows/dotnet-build.yml @@ -92,9 +92,6 @@ jobs: - name: Restore dependencies run: | # dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config - - # ls all sub-directories under dotnet folder - ls -R . dotnet restore -bl - name: Format check run: | From a9891c03eb743f8614d5b6cc8fe928d1108a9a12 Mon Sep 17 00:00:00 2001 From: Griffin Bassman Date: Wed, 22 Jan 2025 14:59:44 -0500 Subject: [PATCH 102/110] fix case in program.cs --- dotnet/samples/Hello/Hello.AppHost/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/Hello/Hello.AppHost/Program.cs b/dotnet/samples/Hello/Hello.AppHost/Program.cs index 31dbeb8c2db7..05cc4cae1efc 100644 --- a/dotnet/samples/Hello/Hello.AppHost/Program.cs +++ b/dotnet/samples/Hello/Hello.AppHost/Program.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Hosting; var builder = DistributedApplication.CreateBuilder(args); -var backend = builder.AddProject("backend").WithExternalHttpEndpoints(); +var backend = builder.AddProject("backend").WithExternalHttpEndpoints(); var client = builder.AddProject("HelloAgentsDotNET") .WithReference(backend) .WithEnvironment("AGENT_HOST", backend.GetEndpoint("https")) From 6ee2d09fd8468e1bef9f7e91c8559df5da3f4ba9 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 22 Jan 2025 14:53:15 -0800 Subject: [PATCH 103/110] add alternate settings so that we can debug without painful timeouts breaking connections --- .../GrpcAgentWorkerHostBuilderExtension.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs index c22a2b551806..91e2beacba69 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorkerHostBuilderExtension.cs @@ -22,14 +22,27 @@ public static IHostApplicationBuilder AddGrpcAgentWorker(this IHostApplicationBu options.Address = new Uri(agentServiceAddress ?? builder.Configuration["AGENT_HOST"] ?? _defaultAgentServiceAddress); options.ChannelOptionsActions.Add(channelOptions => { - LoggerFactory loggerFactory = new LoggerFactory(); - channelOptions.HttpHandler = new SocketsHttpHandler + var loggerFactory = new LoggerFactory(); + if (Debugger.IsAttached) { - EnableMultipleHttp2Connections = true, - KeepAlivePingDelay = TimeSpan.FromSeconds(20), - KeepAlivePingTimeout = TimeSpan.FromSeconds(10), - KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always - }; + channelOptions.HttpHandler = new SocketsHttpHandler + { + EnableMultipleHttp2Connections = false, + KeepAlivePingDelay = TimeSpan.FromSeconds(200), + KeepAlivePingTimeout = TimeSpan.FromSeconds(100), + KeepAlivePingPolicy = HttpKeepAlivePingPolicy.Always + }; + } + else + { + channelOptions.HttpHandler = new SocketsHttpHandler + { + EnableMultipleHttp2Connections = true, + KeepAlivePingDelay = TimeSpan.FromSeconds(20), + KeepAlivePingTimeout = TimeSpan.FromSeconds(10), + KeepAlivePingPolicy = HttpKeepAlivePingPolicy.WithActiveRequests + }; + } var methodConfig = new MethodConfig { From 9934896bb562b4b32b09a64c9b0f606be1a3770a Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Wed, 22 Jan 2025 15:43:57 -0800 Subject: [PATCH 104/110] update topic id so that the xlang messages flow to the dotnet agent in the HelloAgents sample. --- .../samples/core_xlang_hello_python_agent/hello_python_agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/core_xlang_hello_python_agent/hello_python_agent.py b/python/samples/core_xlang_hello_python_agent/hello_python_agent.py index 178b91de8826..07cd21fa1365 100644 --- a/python/samples/core_xlang_hello_python_agent/hello_python_agent.py +++ b/python/samples/core_xlang_hello_python_agent/hello_python_agent.py @@ -60,7 +60,7 @@ async def main() -> None: await runtime.publish_message( message=output_message, - topic_id=DefaultTopicId("agents.Output", "HelloAgents/python"), + topic_id=DefaultTopicId("agents.Output", "HelloAgents"), sender=AgentId("HelloAgents", "python"), ) await runtime.stop_when_signal() From edb8d047351a7ed86606cdc86d75dd10df714bf7 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 23 Jan 2025 13:16:36 -0800 Subject: [PATCH 105/110] remove WebApplication from tests. --- dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index 1e7b5ff10166..d796b609c4ca 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -218,7 +218,7 @@ public sealed class InMemoryAgentRuntimeFixture { public InMemoryAgentRuntimeFixture() { - var builder = WebApplication.CreateBuilder(); + var builder = new HostApplicationBuilder(); builder.Services.TryAddSingleton(DistributedContextPropagator.Current); builder.AddAgentWorker() .AddAgent(nameof(TestAgent)); From 893489f4aba322f2b9e040447686121b768f8908 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 23 Jan 2025 14:31:13 -0800 Subject: [PATCH 106/110] merge from main --- protos/agent_worker.proto | 48 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index 543b3fba1321..f12943da2bc8 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -48,14 +48,12 @@ message Event { } message RegisterAgentTypeRequest { - string request_id = 1; + string request_id = 1; // TODO: remove once message based requests are removed string type = 2; - repeated string events = 3; - repeated string topics = 4; } message RegisterAgentTypeResponse { - string request_id = 1; + string request_id = 1; // TODO: remove once message based requests are removed bool success = 2; optional string error = 3; } @@ -71,35 +69,46 @@ message TypePrefixSubscription { } message Subscription { + string id = 1; oneof subscription { - TypeSubscription typeSubscription = 1; - TypePrefixSubscription typePrefixSubscription = 2; + TypeSubscription typeSubscription = 2; + TypePrefixSubscription typePrefixSubscription = 3; } } -message SubscriptionList { - repeated Subscription subscriptions = 1; -} - -message SubscriptionRequest { - string request_id = 1; +message AddSubscriptionRequest { + string request_id = 1; // TODO: remove once message based requests are removed Subscription subscription = 2; } -message SubscriptionResponse { - string request_id = 1; +message AddSubscriptionResponse { + string request_id = 1; // TODO: remove once message based requests are removed bool success = 2; optional string error = 3; } +message RemoveSubscriptionRequest { + string id = 1; +} + +message RemoveSubscriptionResponse { + bool success = 1; + optional string error = 2; +} + +message GetSubscriptionsRequest {} +message GetSubscriptionsResponse { + repeated Subscription subscriptions = 1; +} + service AgentRpc { rpc OpenChannel (stream Message) returns (stream Message); rpc GetState(AgentId) returns (GetStateResponse); rpc SaveState(AgentState) returns (SaveStateResponse); rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse); - rpc Subscribe(SubscriptionRequest) returns (SubscriptionResponse); - rpc Unsubscribe(SubscriptionRequest) returns (SubscriptionResponse); - rpc GetSubscriptions(AgentId) returns (SubscriptionList); + rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse); + rpc RemoveSubscription(RemoveSubscriptionRequest) returns (RemoveSubscriptionResponse); + rpc GetSubscriptions(GetSubscriptionsRequest) returns (GetSubscriptionsResponse); } message AgentState { @@ -130,8 +139,7 @@ message Message { io.cloudevents.v1.CloudEvent cloudEvent = 3; RegisterAgentTypeRequest registerAgentTypeRequest = 4; RegisterAgentTypeResponse registerAgentTypeResponse = 5; - SubscriptionRequest SubscriptionRequest = 6; - SubscriptionResponse SubscriptionResponse = 7; + AddSubscriptionRequest addSubscriptionRequest = 6; + AddSubscriptionResponse addSubscriptionResponse = 7; } } - From 7e5bee7607c55455071cb299e579a7d5bed31a11 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Thu, 23 Jan 2025 15:51:53 -0800 Subject: [PATCH 107/110] the half of the changes related to the inmemory runtime. --- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 46 +++++++----- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 71 ++++++++++++++----- .../Microsoft.AutoGen/Core/IAgentWorker.cs | 6 +- .../Core/UninitializedAgentWorker.cs | 5 +- 4 files changed, 88 insertions(+), 40 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index af87ce12d644..6a7952c6f1c2 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -42,7 +42,6 @@ protected Agent( { EventTypes = eventTypes; AgentId = new AgentId(this.GetType().Name, Guid.NewGuid().ToString()); - AgentId = new AgentId(this.GetType().Name, Guid.NewGuid().ToString()); _logger = logger ?? LoggerFactory.Create(builder => { }).CreateLogger(); _handlersByMessageType = new(GetType().GetHandlersLookupTable()); Worker = new UninitializedAgentWorker(); @@ -64,7 +63,7 @@ private async ValueTask AddImplicitSubscriptionsAsync() foreach (var topicType in topicTypes) { - var subscriptionRequest = new SubscriptionRequest + var subscriptionRequest = new AddSubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -176,19 +175,11 @@ await this.InvokeWithActivityAsync( } public async ValueTask> GetSubscriptionsAsync() { - return await Worker.GetSubscriptionsAsync(GetType()).ConfigureAwait(false); - } - public async ValueTask SubscribeAsync(string topic) - { - return await UpdateSubscriptionAsync(topic, true).ConfigureAwait(true); - } - public async ValueTask UnsubscribeAsync(string topic) - { - return await UpdateSubscriptionAsync(topic, false).ConfigureAwait(true); + return await Worker.GetSubscriptionsAsync().ConfigureAwait(false); } - private async ValueTask UpdateSubscriptionAsync(string topic, bool subscribe) + public async ValueTask SubscribeAsync(string topic) { - SubscriptionRequest subscriptionRequest = new() + AddSubscriptionRequest subscriptionRequest = new() { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -200,15 +191,38 @@ private async ValueTask UpdateSubscriptionAsync(string top } } }; - var subscriptionResponse = subscribe - ? await Worker.SubscribeAsync(subscriptionRequest).ConfigureAwait(true) - : await Worker.UnsubscribeAsync(subscriptionRequest).ConfigureAwait(true); + var subscriptionResponse = await Worker.SubscribeAsync(subscriptionRequest).ConfigureAwait(true); if (!subscriptionResponse.Success) { _logger.LogError($"{GetType}{AgentId.Key}: Failed to unsubscribe from topic {topic}"); } return subscriptionResponse; } + public async ValueTask UnsubscribeAsync(Guid id) + { + RemoveSubscriptionRequest subscriptionRequest = new() + { + Id = id.ToString() + }; + var subscriptionResponse = await Worker.UnsubscribeAsync(subscriptionRequest).ConfigureAwait(true); + if (!subscriptionResponse.Success) + { + _logger.LogError($"{GetType}{AgentId.Key}: Failed to unsubscribe from Subscription {id}"); + } + return subscriptionResponse; + } + public async ValueTask UnsubscribeAsync(string topic) + { + var subscriptions = await GetSubscriptionsAsync().ConfigureAwait(false); + var subscription = subscriptions.FirstOrDefault(s => s.TypeSubscription.TopicType == topic); + if (subscription == null) + { + var error = $"{GetType}{AgentId.Key}: Subscription not found for topic {topic}"; + _logger.LogError(error); + return new RemoveSubscriptionResponse { Success = false, Error = error }; + } + return await UnsubscribeAsync(subscription.Id).ConfigureAwait(true); + } public async Task StoreAsync(AgentState state, CancellationToken cancellationToken = default) { await Worker.StoreAsync(state, cancellationToken).ConfigureAwait(false); diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index aaf6c795d14d..a43b4a2d9226 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -33,6 +33,7 @@ public class AgentWorker( private readonly IEnumerable> _configuredAgentTypes = configuredAgentTypes; private readonly ConcurrentDictionary> _subscriptionsByAgentType = new(); private readonly ConcurrentDictionary> _subscriptionsByTopic = new(); + private readonly ConcurrentDictionary> _subscriptionsByGuid = new(); private readonly CancellationTokenSource _shutdownCancellationToken = new(); private Task? _mailboxTask; private readonly object _channelLock = new(); @@ -114,10 +115,10 @@ public async Task RunMessagePump() agentToInvoke.ReceiveMessage(msg); } break; - case Message msg when msg.SubscriptionRequest != null: - await SubscribeAsync(msg.SubscriptionRequest).ConfigureAwait(true); + case Message msg when msg.AddSubscriptionRequest != null: + await SubscribeAsync(msg.AddSubscriptionRequest).ConfigureAwait(true); break; - case Message msg when msg.SubscriptionResponse != null: + case Message msg when msg.AddSubscriptionResponse != null: break; case Message msg when msg.RegisterAgentTypeResponse != null: break; @@ -134,13 +135,17 @@ public async Task RunMessagePump() } } } - public async ValueTask SubscribeAsync(SubscriptionRequest subscription, CancellationToken cancellationToken = default) + public async ValueTask SubscribeAsync(AddSubscriptionRequest subscription, CancellationToken cancellationToken = default) { var topic = subscription.Subscription.TypeSubscription.TopicType; var agentType = subscription.Subscription.TypeSubscription.AgentType; + var id = Guid.NewGuid(); + subscription.Subscription.Id = id.ToString(); + var sub = new Dictionary { { topic, agentType } }; + _subscriptionsByGuid.GetOrAdd(id, static _ => new Dictionary()).Add(topic, agentType); _subscriptionsByAgentType.GetOrAdd(key: agentType, _ => []).Add(subscription.Subscription); _subscriptionsByTopic.GetOrAdd(topic, _ => []).Add(agentType); - var response = new SubscriptionResponse + var response = new AddSubscriptionResponse { RequestId = subscription.RequestId, Error = "", @@ -148,33 +153,53 @@ public async ValueTask SubscribeAsync(SubscriptionRequest }; return response; } - public async ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public async ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default) { - var topic = request.Subscription.TypeSubscription.TopicType; - var agentType = request.Subscription.TypeSubscription.AgentType; - if (_subscriptionsByAgentType.TryGetValue(agentType, out var subscriptions)) + if (!Guid.TryParse(request.Id, out var id)) { - while (subscriptions.Remove(request.Subscription)) + var removeSubscriptionResponse = new RemoveSubscriptionResponse { - //ensures all instances are removed - } + Error = "Invalid subscription ID", + Success = false + }; + return removeSubscriptionResponse; } - if (_subscriptionsByTopic.TryGetValue(topic, out var agentTypes)) + if (_subscriptionsByGuid.TryGetValue(id, out var sub)) { - while (agentTypes.Remove(agentType)) + foreach (var (topic, agentType) in sub) { - //ensures all instances are removed + if (_subscriptionsByTopic.TryGetValue(topic, out var innerAgentTypes)) + { + while (innerAgentTypes.Remove(agentType)) + { + //ensures all instances are removed + } + _subscriptionsByTopic.AddOrUpdate(topic, innerAgentTypes, (_, _) => innerAgentTypes); + } + if (_subscriptionsByAgentType.TryGetValue(agentType, out var innerSubscriptions)) + { + foreach (var subscription in innerSubscriptions) + { + if (subscription.Id == id.ToString()) + { + while (innerSubscriptions.Remove(subscription)) + { + //ensures all instances are removed + } + } + } + _subscriptionsByAgentType.AddOrUpdate(agentType, innerSubscriptions, (_, _) => innerSubscriptions); + } } + _subscriptionsByGuid.TryRemove(id, out _); } - var response = new SubscriptionResponse + var response = new RemoveSubscriptionResponse { - RequestId = request.RequestId, Error = "", Success = true }; return response; } - public async Task StartAsync(CancellationToken cancellationToken) { StartCore(); @@ -250,7 +275,6 @@ private Agent GetOrActivateAgent(AgentId agentId) return agent; } - public ValueTask> GetSubscriptionsAsync(Type type) { if (_subscriptionsByAgentType.TryGetValue(type.Name, out var subscriptions)) @@ -259,4 +283,13 @@ public ValueTask> GetSubscriptionsAsync(Type type) } return new ValueTask>([]); } + public ValueTask> GetSubscriptionsAsync() + { + var subscriptions = new List(); + foreach (var (_, value) in _subscriptionsByAgentType) + { + subscriptions.AddRange(value); + } + return new ValueTask>(subscriptions); + } } diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs index a8be598aa7ca..5109ecf2dcf8 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs @@ -12,7 +12,7 @@ public interface IAgentWorker ValueTask SendMessageAsync(Message message, CancellationToken cancellationToken = default); ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default); ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); - ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); - ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default); - ValueTask> GetSubscriptionsAsync(Type type); + ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default); + ValueTask> GetSubscriptionsAsync(); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index fec7fef60cc5..6c7ed71f3d2d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -15,8 +15,9 @@ public class UninitializedAgentWorker() : IAgentWorker public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask> GetSubscriptionsAsync(Type type) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - public ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask> GetSubscriptionsAsync() => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public class AgentInitalizedIncorrectlyException(string message) : Exception(message) { } From 811d76fd0a132e81b27c66d8daeaf34c551c2ac3 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 24 Jan 2025 17:30:35 -0800 Subject: [PATCH 108/110] backing off someof the prior proto changes, updating the tests and methods that depended upon them, --- .../Core.Grpc/GrpcAgentWorker.cs | 49 ++++----- dotnet/src/Microsoft.AutoGen/Core/Agent.cs | 36 ++++-- .../src/Microsoft.AutoGen/Core/AgentWorker.cs | 9 +- .../Microsoft.AutoGen/Core/IAgentWorker.cs | 2 +- .../Core/UninitializedAgentWorker.cs | 2 +- .../Runtime.Grpc/Abstractions/IGateway.cs | 6 +- .../Runtime.Grpc/Abstractions/IRegistry.cs | 7 +- .../Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 49 +++------ .../Services/Grpc/GrpcGatewayService.cs | 11 +- .../Services/Orleans/AgentsRegistryState.cs | 3 + .../Services/Orleans/RegistryGrain.cs | 104 +++++++++++------- ....cs => AddSubscriptionRequestSurrogate.cs} | 20 ++-- ...cs => AddSubscriptionResponseSurrogate.cs} | 20 ++-- .../Surrogates/GetSubscriptionsRequest.cs | 35 ++++++ .../RegisterAgentTypeRequestSurrogate.cs | 6 +- .../Surrogates/RemoveSubscriptionRequest.cs | 35 ++++++ .../Surrogates/RemoveSubscriptionResponse.cs | 39 +++++++ .../Surrogates/SubscriptionSurrogate.cs | 5 + .../AgentGrpcTests.cs | 15 +-- .../AgentTests.cs | 61 +++++----- .../GrpcGatewayServiceTests.cs | 88 ++++++++++----- 21 files changed, 393 insertions(+), 209 deletions(-) rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{SubscriptionRequestSurrogate.cs => AddSubscriptionRequestSurrogate.cs} (51%) rename dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/{SubscriptionResponseSurrogate.cs => AddSubscriptionResponseSurrogate.cs} (53%) create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/GetSubscriptionsRequest.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionRequest.cs create mode 100644 dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionResponse.cs diff --git a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs index 79e7c57042cd..c40ded0abb67 100644 --- a/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core.Grpc/GrpcAgentWorker.cs @@ -81,10 +81,10 @@ private async Task RunReadPump() _logger.LogError($"Failed to register agent type '{message.RegisterAgentTypeResponse.Error}'"); } break; - case Message.MessageOneofCase.SubscriptionResponse: - if (!message.SubscriptionResponse.Success) + case Message.MessageOneofCase.AddSubscriptionResponse: + if (!message.AddSubscriptionResponse.Success) { - _logger.LogError($"Failed to add subscription '{message.SubscriptionResponse.Error}'"); + _logger.LogError($"Failed to add subscription '{message.AddSubscriptionResponse.Error}'"); } break; case Message.MessageOneofCase.CloudEvent: @@ -227,7 +227,7 @@ private async ValueTask RegisterAgentTypeAsync(string type, Type agentType, Canc agents.Add(agentType); } - var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic); + var topicTypes = agentType.GetCustomAttributes().Select(t => t.Topic).ToList(); /* var response = await _client.RegisterAgentAsync(new RegisterAgentTypeRequest { Type = type, @@ -240,16 +240,19 @@ await WriteChannelAsync(new Message { RequestId = Guid.NewGuid().ToString(), Type = type, - Topics = { topicTypes }, - Events = { events } + //Topics = { topicTypes }, //future + //Events = { events } //future } }, cancellationToken).ConfigureAwait(false); - + if (!topicTypes.Any()) + { + topicTypes.Add(agentType.Name); + } foreach (var topic in topicTypes) { var subscriptionRequest = new Message { - SubscriptionRequest = new SubscriptionRequest + AddSubscriptionRequest = new AddSubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -262,13 +265,12 @@ await WriteChannelAsync(new Message } } }; - await _client.SubscribeAsync(subscriptionRequest.SubscriptionRequest, null, null, cancellationToken); - //await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); + await _client.AddSubscriptionAsync(subscriptionRequest.AddSubscriptionRequest, null, null, cancellationToken); foreach (var e in events) { subscriptionRequest = new Message { - SubscriptionRequest = new SubscriptionRequest + AddSubscriptionRequest = new AddSubscriptionRequest { RequestId = Guid.NewGuid().ToString(), Subscription = new Subscription @@ -281,8 +283,7 @@ await WriteChannelAsync(new Message } } }; - await _client.SubscribeAsync(subscriptionRequest.SubscriptionRequest, null, null, cancellationToken); - //await WriteChannelAsync(subscriptionRequest, cancellationToken).ConfigureAwait(true); + await _client.AddSubscriptionAsync(subscriptionRequest.AddSubscriptionRequest, null, null, cancellationToken); } } } @@ -433,24 +434,20 @@ public async ValueTask ReadAsync(AgentId agentId, CancellationToken throw new KeyNotFoundException($"Failed to read AgentState for {agentId}."); } } - - public ValueTask> GetSubscriptionsAsync(Type type) + public async ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default) { - var agentId = new AgentId { Type = type.Name }; - var response = _client.GetSubscriptions(agentId); - return new ValueTask>([.. response.Subscriptions]); + var response = await _client.GetSubscriptionsAsync(request, null, null, cancellationToken); + return response.Subscriptions.ToList(); } - - public ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default) { - var response = _client.Subscribe(request, null, null, cancellationToken); - return new ValueTask(response); + var response = _client.AddSubscription(request, null, null, cancellationToken); + return new ValueTask(response); } - - public ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default) { - var response = _client.Unsubscribe(request, null, null, cancellationToken); - return new ValueTask(response); + var response = _client.RemoveSubscription(request, null, null, cancellationToken); + return new ValueTask(response); } } diff --git a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs index 6a7952c6f1c2..fe6103e70c7d 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/Agent.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/Agent.cs @@ -175,7 +175,8 @@ await this.InvokeWithActivityAsync( } public async ValueTask> GetSubscriptionsAsync() { - return await Worker.GetSubscriptionsAsync().ConfigureAwait(false); + GetSubscriptionsRequest request = new(); + return await Worker.GetSubscriptionsAsync(request).ConfigureAwait(false); } public async ValueTask SubscribeAsync(string topic) { @@ -221,7 +222,8 @@ public async ValueTask UnsubscribeAsync(string topic _logger.LogError(error); return new RemoveSubscriptionResponse { Success = false, Error = error }; } - return await UnsubscribeAsync(subscription.Id).ConfigureAwait(true); + var id = Guid.Parse(subscription.Id); + return await UnsubscribeAsync(id).ConfigureAwait(true); } public async Task StoreAsync(AgentState state, CancellationToken cancellationToken = default) { @@ -326,16 +328,32 @@ private string SetTopic(string? topic = null, string? source = null, string? key /// A task representing the asynchronous operation. public async ValueTask PublishMessageAsync(T message, string topic, string source, string key, CancellationToken token = default) where T : IMessage { - - var topicTypes = this.GetType().GetCustomAttributes().Select(t => t.Topic); - if (!topicTypes.Any()) + // if there are no topic types, use the agent's default topic subscription attribute and the agent's type and key + if (string.IsNullOrWhiteSpace(topic)) { - topicTypes = topicTypes.Append(string.IsNullOrWhiteSpace(source) ? this.AgentId.Type + "." + this.AgentId.Key : source); + if (string.IsNullOrWhiteSpace(topic)) + { + topic = this.AgentId.Type + "." + this.AgentId.Key; + } + else + { + topic = topic + "." + source + "." + key; + } + + var topicTypes = this.GetType().GetCustomAttributes().Select(t => t.Topic); + if (!topicTypes.Any()) + { + topicTypes = topicTypes.Append(string.IsNullOrWhiteSpace(source) ? this.AgentId.Type + "." + this.AgentId.Key : source); + } + topicTypes = topicTypes.Append(SetTopic(topic, source, key)); + foreach (var t in topicTypes) + { + await PublishEventAsync(t, message, token).ConfigureAwait(false); + } } - topicTypes = topicTypes.Append(SetTopic(topic, source, key)); - foreach (var t in topicTypes) + else { - await PublishEventAsync(t, message, token).ConfigureAwait(false); + await PublishEventAsync(topic, message, token).ConfigureAwait(false); } } public async ValueTask PublishMessageAsync(T message, string topic, string source, CancellationToken token = default) where T : IMessage diff --git a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs index a43b4a2d9226..b2d94d2475b5 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/AgentWorker.cs @@ -176,18 +176,17 @@ public async ValueTask UnsubscribeAsync(RemoveSubscr } _subscriptionsByTopic.AddOrUpdate(topic, innerAgentTypes, (_, _) => innerAgentTypes); } + var toRemove = new List(); if (_subscriptionsByAgentType.TryGetValue(agentType, out var innerSubscriptions)) { foreach (var subscription in innerSubscriptions) { if (subscription.Id == id.ToString()) { - while (innerSubscriptions.Remove(subscription)) - { - //ensures all instances are removed - } + toRemove.Add(subscription); } } + foreach (var subscription in toRemove) { innerSubscriptions.Remove(subscription); } _subscriptionsByAgentType.AddOrUpdate(agentType, innerSubscriptions, (_, _) => innerSubscriptions); } } @@ -283,7 +282,7 @@ public ValueTask> GetSubscriptionsAsync(Type type) } return new ValueTask>([]); } - public ValueTask> GetSubscriptionsAsync() + public ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default) { var subscriptions = new List(); foreach (var (_, value) in _subscriptionsByAgentType) diff --git a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs index 5109ecf2dcf8..f3e8bc7308ec 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/IAgentWorker.cs @@ -14,5 +14,5 @@ public interface IAgentWorker ValueTask ReadAsync(AgentId agentId, CancellationToken cancellationToken = default); ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default); ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default); - ValueTask> GetSubscriptionsAsync(); + ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default); } diff --git a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs index 6c7ed71f3d2d..4aa14ac22ce3 100644 --- a/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs +++ b/dotnet/src/Microsoft.AutoGen/Core/UninitializedAgentWorker.cs @@ -15,7 +15,7 @@ public class UninitializedAgentWorker() : IAgentWorker public ValueTask SendResponseAsync(RpcResponse response, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask StoreAsync(AgentState value, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask> GetSubscriptionsAsync(Type type) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); - public ValueTask> GetSubscriptionsAsync() => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); + public ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default) => throw new AgentInitalizedIncorrectlyException(AgentNotInitializedMessage); public class AgentInitalizedIncorrectlyException(string message) : Exception(message) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs index 02aeb6bf0c3f..33bb94f7c49b 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IGateway.cs @@ -11,8 +11,8 @@ public interface IGateway : IGrainObserver ValueTask StoreAsync(Contracts.AgentState value); ValueTask ReadAsync(AgentId agentId); ValueTask RegisterAgentTypeAsync(RegisterAgentTypeRequest request); - ValueTask SubscribeAsync(SubscriptionRequest request); - ValueTask UnsubscribeAsync(SubscriptionRequest request); - ValueTask> GetSubscriptionsAsync(Type type); + ValueTask SubscribeAsync(AddSubscriptionRequest request); + ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request); + ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request); Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs index 08007dd4ad62..436fa038774e 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Abstractions/IRegistry.cs @@ -67,19 +67,18 @@ public interface IRegistry /// /// The subscription request. /// A task representing the asynchronous operation. - ValueTask SubscribeAsync(SubscriptionRequest request); + ValueTask SubscribeAsync(AddSubscriptionRequest request); /// /// Unsubscribes an agent from a topic. /// /// The unsubscription request. /// A task representing the asynchronous operation. - ValueTask UnsubscribeAsync(SubscriptionRequest request); // TODO: This should have its own request type. + ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request); // TODO: This should have its own request type. /// /// Gets the subscriptions for a specified agent type. /// - /// The type of the agent. /// A task representing the asynchronous operation, with the subscriptions as the result. - ValueTask> GetSubscriptions(string agentType); + ValueTask> GetSubscriptions(GetSubscriptionsRequest request); } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 31cc4367af1f..913b7b5bbeb4 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -101,12 +101,12 @@ public async ValueTask RegisterAgentTypeAsync(Registe }; } } - public async ValueTask SubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public async ValueTask SubscribeAsync(AddSubscriptionRequest request, CancellationToken cancellationToken = default) { try { await _gatewayRegistry.SubscribeAsync(request).ConfigureAwait(true); - return new SubscriptionResponse + return new AddSubscriptionResponse { Success = true, RequestId = request.RequestId @@ -114,7 +114,7 @@ public async ValueTask SubscribeAsync(SubscriptionRequest } catch (Exception ex) { - return new SubscriptionResponse + return new AddSubscriptionResponse { Success = false, RequestId = request.RequestId, @@ -174,8 +174,8 @@ internal async Task OnReceivedMessageAsync(GrpcWorkerConnection connection, Mess case Message.MessageOneofCase.RegisterAgentTypeRequest: await RegisterAgentTypeAsync(connection, message.RegisterAgentTypeRequest); break; - case Message.MessageOneofCase.SubscriptionRequest: - await AddSubscriptionAsync(connection, message.SubscriptionRequest); + case Message.MessageOneofCase.AddSubscriptionRequest: + await AddSubscriptionAsync(connection, message.AddSubscriptionRequest); break; default: // if it wasn't recognized return bad request @@ -297,7 +297,7 @@ private static async ValueTask RespondBadRequestAsync(GrpcWorkerConnection conne { throw new RpcException(new Status(StatusCode.InvalidArgument, error)); } - private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, SubscriptionRequest request) + private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, AddSubscriptionRequest request) { var topic = ""; var agentType = ""; @@ -317,7 +317,7 @@ private async ValueTask AddSubscriptionAsync(GrpcWorkerConnection connection, Su //var response = new SubscriptionResponse { RequestId = request.RequestId, Error = "", Success = true }; Message response = new() { - SubscriptionResponse = new() + AddSubscriptionResponse = new() { RequestId = request.RequestId, Error = "", @@ -361,73 +361,60 @@ public async Task SendMessageAsync(IConnection connection, CloudEvent cloudEvent await queue.ResponseStream.WriteAsync(new Message { CloudEvent = cloudEvent }, cancellationToken).ConfigureAwait(false); } - public async ValueTask UnsubscribeAsync(SubscriptionRequest request, CancellationToken cancellationToken = default) + public async ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request, CancellationToken cancellationToken = default) { try { await _gatewayRegistry.UnsubscribeAsync(request).ConfigureAwait(true); - return new SubscriptionResponse + return new RemoveSubscriptionResponse + { Success = true, - RequestId = request.RequestId }; } catch (Exception ex) { - return new SubscriptionResponse + return new RemoveSubscriptionResponse { Success = false, - RequestId = request.RequestId, Error = ex.Message }; } - } - public ValueTask> GetSubscriptionsAsync(Type type, CancellationToken cancellationToken = default) + } + public ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default) { - return _gatewayRegistry.GetSubscriptions(nameof(type)); + return _gatewayRegistry.GetSubscriptions(request); } - public ValueTask> GetSubscriptionsAsync(string type, CancellationToken cancellationToken = default) - { - return _gatewayRegistry.GetSubscriptions(type); - } - async ValueTask IGateway.InvokeRequestAsync(RpcRequest request) { return await InvokeRequestAsync(request, default).ConfigureAwait(false); } - async ValueTask IGateway.BroadcastEventAsync(CloudEvent evt) { await BroadcastEventAsync(evt, default).ConfigureAwait(false); } - ValueTask IGateway.StoreAsync(AgentState value) { return StoreAsync(value, default); } - ValueTask IGateway.ReadAsync(AgentId agentId) { return ReadAsync(agentId, default); } - ValueTask IGateway.RegisterAgentTypeAsync(RegisterAgentTypeRequest request) { return RegisterAgentTypeAsync(request, default); } - - ValueTask IGateway.SubscribeAsync(SubscriptionRequest request) + ValueTask IGateway.SubscribeAsync(AddSubscriptionRequest request) { return SubscribeAsync(request, default); } - - ValueTask IGateway.UnsubscribeAsync(SubscriptionRequest request) + ValueTask IGateway.UnsubscribeAsync(RemoveSubscriptionRequest request) { return UnsubscribeAsync(request, default); } - - ValueTask> IGateway.GetSubscriptionsAsync(Type type) + ValueTask> IGateway.GetSubscriptionsAsync(GetSubscriptionsRequest request) { - return GetSubscriptionsAsync(type, default); + return GetSubscriptionsAsync(request); } } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs index 5c33e90e164e..9481922943c9 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGatewayService.cs @@ -39,20 +39,19 @@ public override async Task SaveState(AgentState request, Serv Success = true // TODO: Implement error handling }; } - public override async Task Subscribe(SubscriptionRequest request, ServerCallContext context) + public override async Task AddSubscription(AddSubscriptionRequest request, ServerCallContext context) { request.RequestId = context.Peer; return await Gateway.SubscribeAsync(request).ConfigureAwait(true); } - public override async Task Unsubscribe(SubscriptionRequest request, ServerCallContext context) + public override async Task RemoveSubscription(RemoveSubscriptionRequest request, ServerCallContext context) { - request.RequestId = context.Peer; return await Gateway.UnsubscribeAsync(request).ConfigureAwait(true); } - public override async Task GetSubscriptions(AgentId request, ServerCallContext context) + public override async Task GetSubscriptions(GetSubscriptionsRequest request, ServerCallContext context) { - var subscriptions = await Gateway.GetSubscriptionsAsync(request.Type); - return new SubscriptionList { Subscriptions = { subscriptions } }; + var subscriptions = await Gateway.GetSubscriptionsAsync(request); + return new GetSubscriptionsResponse { Subscriptions = { subscriptions } }; } public override async Task RegisterAgent(RegisterAgentTypeRequest request, ServerCallContext context) { diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs index 3e69bd3cc3a9..8be5e8dd5873 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/AgentsRegistryState.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // AgentsRegistryState.cs +using Microsoft.AutoGen.Contracts; + namespace Microsoft.AutoGen.Runtime.Grpc; public class AgentsRegistryState @@ -9,4 +11,5 @@ public class AgentsRegistryState public Dictionary> AgentsToTopicsMap { get; set; } = []; public Dictionary> TopicToAgentTypesMap { get; set; } = []; public Dictionary> EventsToAgentTypesMap { get; set; } = []; + public Dictionary> GuidSubscriptionsMap { get; set; } = []; } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs index 775ad1c65e94..4129a0bc413b 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/RegistryGrain.cs @@ -25,11 +25,12 @@ public ValueTask> GetSubscribedAndHandlingAgents(string topic, stri // get all agent types that are subscribed to the topic if (state.State.TopicToAgentTypesMap.TryGetValue(topic, out var subscribedAgentTypes)) { - // get all agent types that are handling the event + /*// get all agent types that are handling the event if (state.State.EventsToAgentTypesMap.TryGetValue(eventType, out var handlingAgents)) { agents.AddRange(subscribedAgentTypes.Intersect(handlingAgents).ToList()); - } + }*/ + agents.AddRange(subscribedAgentTypes.ToList()); } if (state.State.TopicToAgentTypesMap.TryGetValue(eventType, out var eventHandlingAgents)) { @@ -96,20 +97,21 @@ public ValueTask RemoveWorker(IGateway worker) } return ValueTask.CompletedTask; } - public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, IGateway worker) + public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, IGateway gateway) { if (!_supportedAgentTypes.TryGetValue(registration.Type, out var supportedAgentTypes)) { supportedAgentTypes = _supportedAgentTypes[registration.Type] = []; } - if (!supportedAgentTypes.Contains(worker)) + if (!supportedAgentTypes.Contains(gateway)) { - supportedAgentTypes.Add(worker); + supportedAgentTypes.Add(gateway); } - var workerState = GetOrAddWorker(worker); + var workerState = GetOrAddWorker(gateway); workerState.SupportedTypes.Add(registration.Type); + /* future state.State.AgentsToEventsMap[registration.Type] = new HashSet(registration.Events); state.State.AgentsToTopicsMap[registration.Type] = new HashSet(registration.Topics); @@ -136,6 +138,7 @@ public async ValueTask RegisterAgentType(RegisterAgentTypeRequest registration, eventSet.Add(registration.Type); } + */ await state.WriteStateAsync().ConfigureAwait(false); } public ValueTask AddWorker(IGateway worker) @@ -200,9 +203,11 @@ private WorkerState GetOrAddWorker(IGateway worker) return null; } - public async ValueTask SubscribeAsync(SubscriptionRequest sub) + public async ValueTask SubscribeAsync(AddSubscriptionRequest subscription) { - switch (sub.Subscription.SubscriptionCase) + var guid = Guid.NewGuid().ToString(); + subscription.Subscription.Id = guid; + switch (subscription.Subscription.SubscriptionCase) { //TODO: this doesnt look right case Subscription.SubscriptionOneofCase.TypePrefixSubscription: @@ -210,22 +215,31 @@ public async ValueTask SubscribeAsync(SubscriptionRequest sub) case Subscription.SubscriptionOneofCase.TypeSubscription: { // add the topic to the set of topics for the agent type - state.State.AgentsToTopicsMap.TryGetValue(sub.Subscription.TypeSubscription.AgentType, out var topics); + state.State.AgentsToTopicsMap.TryGetValue(subscription.Subscription.TypeSubscription.AgentType, out var topics); if (topics is null) { topics = new HashSet(); - state.State.AgentsToTopicsMap[sub.Subscription.TypeSubscription.AgentType] = topics; + state.State.AgentsToTopicsMap[subscription.Subscription.TypeSubscription.AgentType] = topics; } - topics.Add(sub.Subscription.TypeSubscription.TopicType); + topics.Add(subscription.Subscription.TypeSubscription.TopicType); // add the agent type to the set of agent types for the topic - state.State.TopicToAgentTypesMap.TryGetValue(sub.Subscription.TypeSubscription.TopicType, out var agents); + state.State.TopicToAgentTypesMap.TryGetValue(subscription.Subscription.TypeSubscription.TopicType, out var agents); if (agents is null) { agents = new HashSet(); - state.State.TopicToAgentTypesMap[sub.Subscription.TypeSubscription.TopicType] = agents; + state.State.TopicToAgentTypesMap[subscription.Subscription.TypeSubscription.TopicType] = agents; + } + agents.Add(subscription.Subscription.TypeSubscription.AgentType); + + // add the subscription by Guid + state.State.GuidSubscriptionsMap.TryGetValue(guid, out var existingSubscriptions); + if (existingSubscriptions is null) + { + existingSubscriptions = new HashSet(); + state.State.GuidSubscriptionsMap[guid] = existingSubscriptions; } - agents.Add(sub.Subscription.TypeSubscription.AgentType); + existingSubscriptions.Add(subscription.Subscription); break; } default: @@ -233,37 +247,42 @@ public async ValueTask SubscribeAsync(SubscriptionRequest sub) } await state.WriteStateAsync().ConfigureAwait(false); } - public async ValueTask UnsubscribeAsync(SubscriptionRequest request) + public async ValueTask UnsubscribeAsync(RemoveSubscriptionRequest request) { - switch (request.Subscription.SubscriptionCase) + var guid = request.Id; + // does the guid parse? + if (!Guid.TryParse(guid, out var _)) { - case Subscription.SubscriptionOneofCase.TypePrefixSubscription: - break; - case Subscription.SubscriptionOneofCase.TypeSubscription: + throw new InvalidOperationException("Invalid subscription id"); + } + if (state.State.GuidSubscriptionsMap.TryGetValue(guid, out var subscriptions)) + { + foreach (var subscription in subscriptions) + { + switch (subscription.SubscriptionCase) { - // remove the topic from the set of topics for the agent type - state.State.AgentsToTopicsMap.TryGetValue(request.Subscription.TypeSubscription.AgentType, out var topics); - if (topics is not null) - { - while (topics.Remove(request.Subscription.TypeSubscription.TopicType)) + case Subscription.SubscriptionOneofCase.TypeSubscription: { - // ensures all instances are removed - } - } + // remove the topic from the set of topics for the agent type + state.State.AgentsToTopicsMap.TryGetValue(subscription.TypeSubscription.AgentType, out var topics); + topics?.Remove(subscription.TypeSubscription.TopicType); - // remove the agent type from the set of agent types for the topic - state.State.TopicToAgentTypesMap.TryGetValue(request.Subscription.TypeSubscription.TopicType, out var agents); - if (agents is not null) - { - while (agents.Remove(request.Subscription.TypeSubscription.AgentType)) - { - // ensures all instances are removed + // remove the agent type from the set of agent types for the topic + state.State.TopicToAgentTypesMap.TryGetValue(subscription.TypeSubscription.TopicType, out var agents); + agents?.Remove(subscription.TypeSubscription.AgentType); + + //remove the subscription by Guid + state.State.GuidSubscriptionsMap.TryGetValue(guid, out var existingSubscriptions); + existingSubscriptions?.Remove(subscription); + break; } - } - break; + case Subscription.SubscriptionOneofCase.TypePrefixSubscription: + break; + default: + throw new InvalidOperationException("Invalid subscription type"); } - default: - throw new InvalidOperationException("Invalid subscription type"); + } + state.State.GuidSubscriptionsMap.Remove(guid); } await state.WriteStateAsync().ConfigureAwait(false); } @@ -287,6 +306,15 @@ public ValueTask> GetSubscriptions(string agentType) } return new(subscriptions); } + public ValueTask> GetSubscriptions(GetSubscriptionsRequest request) + { + var subscriptions = new List(); + foreach (var kvp in state.State.GuidSubscriptionsMap) + { + subscriptions.AddRange(kvp.Value); + } + return new(subscriptions); + } private sealed class WorkerState { diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs similarity index 51% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs index f273b0b2347c..e732c3ffc982 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionRequestSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionRequestSurrogate.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// SubscriptionRequestSurrogate.cs +// AddSubscriptionRequestSurrogate.cs using Microsoft.AutoGen.Contracts; namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; [GenerateSerializer] -public struct SubscriptionRequestSurrogate +public struct AddSubscriptionRequestSurrogate { [Id(0)] public string RequestId; @@ -15,13 +15,13 @@ public struct SubscriptionRequestSurrogate } [RegisterConverter] -public sealed class SubscriptionRequestSurrogateConverter : - IConverter +public sealed class AddSubscriptionRequestSurrogateConverter : + IConverter { - public SubscriptionRequest ConvertFromSurrogate( - in SubscriptionRequestSurrogate surrogate) + public AddSubscriptionRequest ConvertFromSurrogate( + in AddSubscriptionRequestSurrogate surrogate) { - var request = new SubscriptionRequest() + var request = new AddSubscriptionRequest() { RequestId = surrogate.RequestId, Subscription = surrogate.Subscription @@ -29,9 +29,9 @@ public SubscriptionRequest ConvertFromSurrogate( return request; } - public SubscriptionRequestSurrogate ConvertToSurrogate( - in SubscriptionRequest value) => - new SubscriptionRequestSurrogate + public AddSubscriptionRequestSurrogate ConvertToSurrogate( + in AddSubscriptionRequest value) => + new AddSubscriptionRequestSurrogate { RequestId = value.RequestId, Subscription = value.Subscription diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs similarity index 53% rename from dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs rename to dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs index 5e8938643dcc..d35a3c5f6f89 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionResponseSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/AddSubscriptionResponseSurrogate.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. -// SubscriptionResponseSurrogate.cs +// AddSubscriptionResponseSurrogate.cs using Microsoft.AutoGen.Contracts; namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; [GenerateSerializer] -public struct SubscriptionResponseSurrogate +public struct AddSubscriptionResponseSurrogate { [Id(0)] public string RequestId; @@ -17,21 +17,21 @@ public struct SubscriptionResponseSurrogate } [RegisterConverter] -public sealed class SubscriptionResponseSurrogateConverter : - IConverter +public sealed class AddSubscriptionResponseSurrogateConverter : + IConverter { - public SubscriptionResponse ConvertFromSurrogate( - in SubscriptionResponseSurrogate surrogate) => - new SubscriptionResponse + public AddSubscriptionResponse ConvertFromSurrogate( + in AddSubscriptionResponseSurrogate surrogate) => + new AddSubscriptionResponse { RequestId = surrogate.RequestId, Success = surrogate.Success, Error = surrogate.Error }; - public SubscriptionResponseSurrogate ConvertToSurrogate( - in SubscriptionResponse value) => - new SubscriptionResponseSurrogate + public AddSubscriptionResponseSurrogate ConvertToSurrogate( + in AddSubscriptionResponse value) => + new AddSubscriptionResponseSurrogate { RequestId = value.RequestId, Success = value.Success, diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/GetSubscriptionsRequest.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/GetSubscriptionsRequest.cs new file mode 100644 index 000000000000..ef06ef2260ca --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/GetSubscriptionsRequest.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// GetSubscriptionsRequest.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct GetSubscriptionsRequestSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public Subscription Subscription; +} + +[RegisterConverter] +public sealed class GetSubscriptionsRequestSurrogateConverter : + IConverter +{ + public GetSubscriptionsRequest ConvertFromSurrogate( + in GetSubscriptionsRequestSurrogate surrogate) + { + var request = new GetSubscriptionsRequest() + { + }; + return request; + } + + public GetSubscriptionsRequestSurrogate ConvertToSurrogate( + in GetSubscriptionsRequest value) => + new GetSubscriptionsRequestSurrogate + { + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs index 5d8b6fd25a03..a4bc2347bc95 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RegisterAgentTypeRequestSurrogate.cs @@ -31,8 +31,9 @@ public RegisterAgentTypeRequest ConvertFromSurrogate( RequestId = surrogate.RequestId, Type = surrogate.Type }; + /* future request.Events.Add(surrogate.Events); - request.Topics.Add(surrogate.Topics); + request.Topics.Add(surrogate.Topics);*/ return request; } @@ -42,7 +43,8 @@ public RegisterAgentTypeRequestSurrogate ConvertToSurrogate( { RequestId = value.RequestId, Type = value.Type, + /* future Events = value.Events, - Topics = value.Topics + Topics = value.Topics */ }; } diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionRequest.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionRequest.cs new file mode 100644 index 000000000000..73c0844d5871 --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionRequest.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RemoveSubscriptionRequest.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RemoveSubscriptionRequestSurrogate +{ + [Id(0)] + public string Id; +} + +[RegisterConverter] +public sealed class RemoveSubscriptionRequestConverter : + IConverter +{ + public RemoveSubscriptionRequest ConvertFromSurrogate( + in RemoveSubscriptionRequestSurrogate surrogate) + { + var request = new RemoveSubscriptionRequest() + { + Id = surrogate.Id + }; + return request; + } + + public RemoveSubscriptionRequestSurrogate ConvertToSurrogate( + in RemoveSubscriptionRequest value) => + new RemoveSubscriptionRequestSurrogate + { + Id = value.Id + }; +} diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionResponse.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionResponse.cs new file mode 100644 index 000000000000..da006b8f54dd --- /dev/null +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/RemoveSubscriptionResponse.cs @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// RemoveSubscriptionResponse.cs + +using Microsoft.AutoGen.Contracts; + +namespace Microsoft.AutoGen.Runtime.Grpc.Orleans.Surrogates; + +[GenerateSerializer] +public struct RemoveSubscriptionResponseSurrogate +{ + [Id(0)] + public string RequestId; + [Id(1)] + public bool Success; + [Id(2)] + public string Error; +} + +[RegisterConverter] +public sealed class SubscriptionResponseSurrogateConverter : + IConverter +{ + public RemoveSubscriptionResponse ConvertFromSurrogate( + in RemoveSubscriptionResponseSurrogate surrogate) => + new RemoveSubscriptionResponse + { + Success = surrogate.Success, + Error = surrogate.Error + }; + + public RemoveSubscriptionResponseSurrogate ConvertToSurrogate( + in RemoveSubscriptionResponse value) => + new RemoveSubscriptionResponseSurrogate + { + Success = value.Success, + Error = value.Error + }; +} + diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs index abf18143929d..1fd56c176278 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Orleans/Surrogates/SubscriptionSurrogate.cs @@ -12,6 +12,8 @@ public struct SubscriptionSurrogate public TypeSubscription? TypeSubscription; [Id(1)] public TypePrefixSubscription? TypePrefixSubscription; + [Id(2)] + public string Id; } [RegisterConverter] @@ -25,6 +27,7 @@ public Subscription ConvertFromSurrogate( { return new Subscription { + Id = surrogate.Id, TypeSubscription = surrogate.TypeSubscription }; } @@ -32,6 +35,7 @@ public Subscription ConvertFromSurrogate( { return new Subscription { + Id = surrogate.Id, TypePrefixSubscription = surrogate.TypePrefixSubscription }; } @@ -42,6 +46,7 @@ public SubscriptionSurrogate ConvertToSurrogate( { return new SubscriptionSurrogate { + Id = value.Id, TypeSubscription = value.TypeSubscription, TypePrefixSubscription = value.TypePrefixSubscription }; diff --git a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs index aeac2fa5b2e0..3594abad842d 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Grpc.Tests/AgentGrpcTests.cs @@ -114,25 +114,26 @@ public async Task PublishMessageAsync_and_ReceiveMessageTest() { using var runtime = new GrpcRuntime(); var (_, agent) = runtime.Start(); - await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); + var topicType = "TestTopic"; + await agent.SubscribeAsync(topicType).ConfigureAwait(true); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); var found = false; foreach (var subscription in subscriptions) { - if (subscription.TypeSubscription.TopicType == "TestEvent") + if (subscription.TypeSubscription.TopicType == topicType) { found = true; } } Assert.True(found); - await agent.PublishMessageAsync(new TextMessage() { - Source = "TestEvent", + Source = topicType, TextMessage_ = "buffer" - }).ConfigureAwait(true); - await Task.Delay(10000); - Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); + }, topicType).ConfigureAwait(true); + await Task.Delay(100); + Assert.True(TestAgent.ReceivedMessages.ContainsKey(topicType)); + runtime.Stop(); } [Fact] diff --git a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs index d796b609c4ca..aa0cf91d981f 100644 --- a/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Core.Tests/AgentTests.cs @@ -6,7 +6,6 @@ using System.Text.Json; using FluentAssertions; using Google.Protobuf.Reflection; -using Microsoft.AspNetCore.Builder; using Microsoft.AutoGen.Contracts; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -18,13 +17,8 @@ namespace Microsoft.AutoGen.Core.Tests; [Collection(ClusterFixtureCollection.Name)] -public class AgentTests(InMemoryAgentRuntimeFixture fixture) +public class AgentTests() { - private readonly IServiceProvider _serviceProvider = fixture.AppHost.Services; - private readonly InMemoryAgentRuntimeFixture _fixture = fixture; - // need a variable to store the runtime instance - public static WebApplication? Host { get; private set; } - /// /// Verify that if the agent is not initialized via AgentWorker, it should throw the correct exception. /// @@ -32,7 +26,8 @@ public class AgentTests(InMemoryAgentRuntimeFixture fixture) [Fact] public async Task Agent_ShouldThrowException_WhenNotInitialized() { - var agent = ActivatorUtilities.CreateInstance(_serviceProvider); + using var runtime = new InMemoryAgentRuntimeFixture(); + var agent = ActivatorUtilities.CreateInstance(runtime.AppHost.Services); await Assert.ThrowsAsync( async () => { @@ -48,11 +43,12 @@ public async Task Agent_ShouldThrowException_WhenNotInitialized() [Fact] public async Task Agent_ShouldInitializeCorrectly() { - var (worker, agent) = _fixture.Start(); + var runtime = new InMemoryAgentRuntimeFixture(); + var (worker, agent) = runtime.Start(); Assert.Equal("AgentWorker", worker.GetType().Name); var subscriptions = await agent.GetSubscriptionsAsync(); Assert.Equal(2, subscriptions.Count); - _fixture.Stop(); + runtime.Stop(); } /// /// Test SubscribeAsync method @@ -61,7 +57,8 @@ public async Task Agent_ShouldInitializeCorrectly() [Fact] public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() { - var (_, agent) = _fixture.Start(); + var runtime = new InMemoryAgentRuntimeFixture(); + var (_, agent) = runtime.Start(); await agent.SubscribeAsync("TestEvent"); await Task.Delay(100); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); @@ -86,7 +83,7 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() } } Assert.False(found); - _fixture.Stop(); + runtime.Stop(); } /// @@ -96,7 +93,8 @@ public async Task SubscribeAsync_UnsubscribeAsync_and_GetSubscriptionsTest() [Fact] public async Task StoreAsync_and_ReadAsyncTest() { - var (_, agent) = _fixture.Start(); + var runtime = new InMemoryAgentRuntimeFixture(); + var (_, agent) = runtime.Start(); Dictionary state = new() { { "testdata", "Active" } @@ -110,7 +108,7 @@ await agent.StoreAsync(new AgentState var read = JsonSerializer.Deserialize>(readState.TextData) ?? new Dictionary { { "data", "No state data found" } }; read.TryGetValue("testdata", out var value); Assert.Equal("Active", value); - _fixture.Stop(); + runtime.Stop(); } /// @@ -120,13 +118,15 @@ await agent.StoreAsync(new AgentState [Fact] public async Task PublishMessageAsync_and_ReceiveMessageTest() { - var (_, agent) = _fixture.Start(); - await agent.SubscribeAsync("TestEvent").ConfigureAwait(true); + var runtime = new InMemoryAgentRuntimeFixture(); + var (_, agent) = runtime.Start(); + var topicType = "TestTopic"; + await agent.SubscribeAsync(topicType).ConfigureAwait(true); var subscriptions = await agent.GetSubscriptionsAsync().ConfigureAwait(true); var found = false; foreach (var subscription in subscriptions) { - if (subscription.TypeSubscription.TopicType == "TestEvent") + if (subscription.TypeSubscription.TopicType == topicType) { found = true; } @@ -134,12 +134,12 @@ public async Task PublishMessageAsync_and_ReceiveMessageTest() Assert.True(found); await agent.PublishMessageAsync(new TextMessage() { - Source = "TestEvent", + Source = topicType, TextMessage_ = "buffer" - }).ConfigureAwait(true); + }, topicType).ConfigureAwait(true); await Task.Delay(100); - Assert.True(TestAgent.ReceivedMessages.ContainsKey("TestEvent")); - _fixture.Stop(); + Assert.True(TestAgent.ReceivedMessages.ContainsKey(topicType)); + runtime.Stop(); } [Fact] @@ -158,7 +158,8 @@ public async Task InvokeCorrectHandler() [Fact] public async Task DelegateMessageToTestAgentAsync() { - var client = _fixture.AppHost.Services.GetRequiredService(); + var runtime = new InMemoryAgentRuntimeFixture(); + var client = runtime.AppHost.Services.GetRequiredService(); await client.PublishMessageAsync(new TextMessage() { Source = nameof(DelegateMessageToTestAgentAsync), @@ -214,7 +215,7 @@ public Task Handle(int item) /// This fixture is used to provide a runtime for the agent tests. /// However, it is shared between tests. So operations from one test can affect another. /// -public sealed class InMemoryAgentRuntimeFixture +public sealed class InMemoryAgentRuntimeFixture : IDisposable { public InMemoryAgentRuntimeFixture() { @@ -239,13 +240,19 @@ public InMemoryAgentRuntimeFixture() return (worker, agent); } /// - /// Stop - stops the agent + /// Stop - stops the agent and ensures cleanup /// - /// void public void Stop() { - IHostApplicationLifetime hostApplicationLifetime = AppHost.Services.GetRequiredService(); - hostApplicationLifetime.StopApplication(); + AppHost?.StopAsync().GetAwaiter().GetResult(); + } + + /// + /// Dispose - Ensures cleanup after each test + /// + public void Dispose() + { + Stop(); } } diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index ce9f80e53a87..71a0863b27ab 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -42,11 +42,9 @@ public async Task Test_Message_Exchange_Through_Gateway() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; - var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); var task = OpenChannel(service: service, client); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); + await service.RegisterAgent(await CreateRegistrationRequest(service,typeof(PBAgent), client.CallContext.Peer), client.CallContext); + await service.RegisterAgent(await CreateRegistrationRequest(service, typeof(GMAgent), client.CallContext.Peer), client.CallContext); var inputEvent = new NewMessageReceived { Message = $"Start-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); @@ -54,6 +52,8 @@ public async Task Test_Message_Exchange_Through_Gateway() var newMessageReceived = await client.ReadNext(); newMessageReceived!.CloudEvent.Type.Should().Be(GetFullName(typeof(NewMessageReceived))); newMessageReceived.CloudEvent.Source.Should().Be("gh-gh-gh"); + var secondMessage = await client.ReadNext(); + secondMessage!.CloudEvent.Type.Should().Be(GetFullName(typeof(NewMessageReceived))); // Simulate an agent, by publishing a new message in the request stream var helloEvent = new Hello { Message = $"Hello test-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); @@ -65,22 +65,6 @@ public async Task Test_Message_Exchange_Through_Gateway() await task; } - [Fact] - public async Task Test_Message_Goes_To_Right_Worker() - { - var logger = Mock.Of>(); - var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); - var service = new GrpcGatewayService(gateway); - var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; - var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - var task = OpenChannel(service: service, client); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); - await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(GMAgent), client.CallContext.Peer), client.CallContext); - client.Dispose(); - await task; - } - [Fact] public async Task Test_RegisterAgent_Should_Succeed() { @@ -88,10 +72,8 @@ public async Task Test_RegisterAgent_Should_Succeed() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; - var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); var task = OpenChannel(service: service, client); - var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), client.CallContext.Peer), client.CallContext); + var response = await service.RegisterAgent(await CreateRegistrationRequest(service, typeof(PBAgent), client.CallContext.Peer), client.CallContext); response.Success.Should().BeTrue(); client.Dispose(); await task; @@ -104,9 +86,7 @@ public async Task Test_RegisterAgent_Should_Fail_For_Wrong_ConnectionId() var gateway = new GrpcGateway(_fixture.Cluster.Client, logger); var service = new GrpcGatewayService(gateway); var client = new TestGrpcClient(); - var assembly = typeof(PBAgent).Assembly; - var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); - var response = await service.RegisterAgent(CreateRegistrationRequest(eventTypes, typeof(PBAgent), "faulty_connection_id"), client.CallContext); + var response = await service.RegisterAgent(await CreateRegistrationRequest(service, typeof(PBAgent), "faulty_connection_id"), client.CallContext); response.Success.Should().BeFalse(); client.Dispose(); } @@ -133,15 +113,65 @@ public async Task Test_GetState() response.Should().NotBeNull(); } - private RegisterAgentTypeRequest CreateRegistrationRequest(AgentsMetadata eventTypes, Type type, string requestId) + private async Task CreateRegistrationRequest(GrpcGatewayService service, Type type, string requestId) { var registration = new RegisterAgentTypeRequest { Type = type.Name, RequestId = requestId }; - registration.Events.AddRange(eventTypes.GetEventsForAgent(type)?.ToList()); - registration.Topics.AddRange(eventTypes.GetTopicsForAgent(type)?.ToList()); + var assembly = type.Assembly; + var eventTypes = ReflectionHelper.GetAgentsMetadata(assembly); + var events = eventTypes.GetEventsForAgent(type)?.ToList(); + var topics = eventTypes.GetTopicsForAgent(type)?.ToList(); + if (events is not null && topics is not null) { events.AddRange(topics); } + var client = new TestGrpcClient(); + + if (events != null) + { + foreach (var e in events) + { + var subscriptionRequest = new Message + { + AddSubscriptionRequest = new AddSubscriptionRequest + { + RequestId = Guid.NewGuid().ToString(), + Subscription = new Subscription + { + TypeSubscription = new TypeSubscription + { + AgentType = type.Name, + TopicType = type.Name + "." + e + } + } + } + }; + await service.AddSubscription(subscriptionRequest.AddSubscriptionRequest, client.CallContext); + } + } + var topicTypes = type.GetCustomAttributes(typeof(TopicSubscriptionAttribute), true).Cast().Select(t => t.Topic).ToList(); + if (topicTypes != null) + { + foreach (var topicType in topicTypes) + { + var subscriptionRequest = new Message + { + AddSubscriptionRequest = new AddSubscriptionRequest + { + RequestId = Guid.NewGuid().ToString(), + Subscription = new Subscription + { + TypeSubscription = new TypeSubscription + { + AgentType = type.Name, + TopicType = topicType + } + } + } + }; + await service.AddSubscription(subscriptionRequest.AddSubscriptionRequest, client.CallContext); + } + } return registration; } From 0ffba79f5b80ab448f355648152228418d964b48 Mon Sep 17 00:00:00 2001 From: Ryan Sweet Date: Fri, 24 Jan 2025 17:35:10 -0800 Subject: [PATCH 109/110] format --- .../Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs | 2 +- .../GrpcGatewayServiceTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs index 913b7b5bbeb4..0f730df718f2 100644 --- a/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs +++ b/dotnet/src/Microsoft.AutoGen/Runtime.Grpc/Services/Grpc/GrpcGateway.cs @@ -380,7 +380,7 @@ public async ValueTask UnsubscribeAsync(RemoveSubscr Error = ex.Message }; } - } + } public ValueTask> GetSubscriptionsAsync(GetSubscriptionsRequest request, CancellationToken cancellationToken = default) { return _gatewayRegistry.GetSubscriptions(request); diff --git a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs index 71a0863b27ab..89f17f2fe755 100644 --- a/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs +++ b/dotnet/test/Microsoft.AutoGen.Runtime.Grpc.Tests/GrpcGatewayServiceTests.cs @@ -43,7 +43,7 @@ public async Task Test_Message_Exchange_Through_Gateway() var service = new GrpcGatewayService(gateway); var client = new TestGrpcClient(); var task = OpenChannel(service: service, client); - await service.RegisterAgent(await CreateRegistrationRequest(service,typeof(PBAgent), client.CallContext.Peer), client.CallContext); + await service.RegisterAgent(await CreateRegistrationRequest(service, typeof(PBAgent), client.CallContext.Peer), client.CallContext); await service.RegisterAgent(await CreateRegistrationRequest(service, typeof(GMAgent), client.CallContext.Peer), client.CallContext); var inputEvent = new NewMessageReceived { Message = $"Start-{client.CallContext.Peer}" }.ToCloudEvent("gh-gh-gh", "gh-gh-gh"); From da4923a4e37c8e082052c5f211aa2247d644e7a8 Mon Sep 17 00:00:00 2001 From: Jack Gerrits Date: Fri, 24 Jan 2025 20:58:21 -0500 Subject: [PATCH 110/110] undo changes --- protos/agent_worker.proto | 1 + .../src/autogen_ext/runtimes/grpc/_worker_runtime.py | 6 +++--- .../runtimes/grpc/_worker_runtime_host_servicer.py | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/protos/agent_worker.proto b/protos/agent_worker.proto index f12943da2bc8..0cf1581aff39 100644 --- a/protos/agent_worker.proto +++ b/protos/agent_worker.proto @@ -143,3 +143,4 @@ message Message { AddSubscriptionResponse addSubscriptionResponse = 7; } } + diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py index 5235efc68eba..ee41a1f58628 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py @@ -275,7 +275,7 @@ async def _run_read_loop(self) -> None: message = await self._host_connection.recv() oneofcase = agent_worker_pb2.Message.WhichOneof(message, "message") match oneofcase: - case "registerAgentTypeRequest" | "SubscriptionRequest": + case "registerAgentTypeRequest" | "addSubscriptionRequest": logger.warning(f"Cant handle {oneofcase}, skipping.") case "request": task = asyncio.create_task(self._process_request(message.request)) @@ -299,9 +299,9 @@ async def _run_read_loop(self) -> None: self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "SubscriptionResponse": + case "addSubscriptionResponse": task = asyncio.create_task( - self._process_add_subscription_response(message.SubscriptionResponse) + self._process_add_subscription_response(message.addSubscriptionResponse) ) self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) diff --git a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py index a401a8a6033c..e5c7d53df3ad 100644 --- a/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py +++ b/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host_servicer.py @@ -138,13 +138,13 @@ async def _receive_messages( self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "SubscriptionRequest": - add_subscription: agent_worker_pb2.SubscriptionRequest = message.SubscriptionRequest + case "addSubscriptionRequest": + add_subscription: agent_worker_pb2.AddSubscriptionRequest = message.addSubscriptionRequest task = asyncio.create_task(self._process_add_subscription_request(add_subscription, client_id)) self._background_tasks.add(task) task.add_done_callback(self._raise_on_exception) task.add_done_callback(self._background_tasks.discard) - case "registerAgentTypeResponse" | "SubscriptionResponse": + case "registerAgentTypeResponse" | "addSubscriptionResponse": logger.warning(f"Received unexpected message type: {oneofcase}") case None: logger.warning("Received empty message")