diff --git a/.github/actions/python-setup/action.yml b/.github/actions/python-setup/action.yml new file mode 100644 index 0000000000..7850392a75 --- /dev/null +++ b/.github/actions/python-setup/action.yml @@ -0,0 +1,25 @@ +name: Reusable Setup UV +description: Reusable workflow to setup uv environment + +inputs: + python-version: + description: The Python version to set up + required: true + os: + description: The operating system to set up + required: true + +runs: + using: "composite" + steps: + - name: Set up uv + uses: astral-sh/setup-uv@v6 + with: + version-file: "python/pyproject.toml" + enable-cache: true + cache-suffix: ${{ inputs.os }}-${{ inputs.python-version }} + cache-dependency-glob: "**/uv.lock" + - name: Install the project + shell: bash + run: | + cd python && uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index e4bd5155c1..a39445c643 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -28,15 +28,15 @@ jobs: UV_PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ matrix.python-version }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: uv sync --all-extras --dev + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - uses: actions/cache@v4 with: path: ~/.cache/pre-commit diff --git a/.github/workflows/python-docs.yml b/.github/workflows/python-docs.yml new file mode 100644 index 0000000000..de57a379ba --- /dev/null +++ b/.github/workflows/python-docs.yml @@ -0,0 +1,39 @@ +name: Python - Create Docs + +on: + workflow_dispatch: + release: + types: [published] + +permissions: + contents: write + id-token: write +env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache + +jobs: + python-build-docs: + if: github.event_name == 'release' && startsWith(github.event.release.tag_name, 'python-') + name: Python Build Docs + runs-on: ubuntu-latest + environment: "integration" + env: + UV_PYTHON: "3.11" + defaults: + run: + working-directory: python + steps: + - uses: actions/checkout@v5 + - name: Set up uv + uses: astral-sh/setup-uv@v6 + with: + version-file: "python/pyproject.toml" + enable-cache: true + cache-suffix: ${{ runner.os }}-${{ env.UV_PYTHON }} + cache-dependency-glob: "**/uv.lock" + - name: Install dependencies + run: uv sync --all-packages --dev --docs + - name: Build the docs + run: uv run poe docs-full + # Upload docs to learn gh diff --git a/.github/workflows/python-merge-tests.yml b/.github/workflows/python-merge-tests.yml index 950394bae6..c0d967ab31 100644 --- a/.github/workflows/python-merge-tests.yml +++ b/.github/workflows/python-merge-tests.yml @@ -67,16 +67,15 @@ jobs: working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ matrix.python-version }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: | - uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - name: Test with pytest timeout-minutes: 10 run: uv run poe --directory ./packages/${{ env.PACKAGE_NAME }} test -n logical --dist loadfile --dist worksteal --junitxml=coverage.xml @@ -128,16 +127,15 @@ jobs: working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ matrix.python-version }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: | - uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - name: Azure CLI Login if: github.event_name != 'pull_request' uses: azure/login@v2 @@ -195,16 +193,15 @@ jobs: working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ matrix.python-version }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: | - uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - name: Azure CLI Login if: github.event_name != 'pull_request' uses: azure/login@v2 diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 39935650ef..97f1ef2481 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -24,13 +24,15 @@ jobs: working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ env.UV_PYTHON }} - cache-dependency-glob: "**/uv.lock" + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - name: Set environment variables run: | # Extract package name from tag (format: python--) diff --git a/.github/workflows/python-test-coverage.yml b/.github/workflows/python-test-coverage.yml index c3f014235f..11b665adad 100644 --- a/.github/workflows/python-test-coverage.yml +++ b/.github/workflows/python-test-coverage.yml @@ -26,15 +26,15 @@ jobs: - name: Save PR number run: | echo ${{ github.event.number }} > ./pr_number - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ env.UV_PYTHON }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: uv sync --all-extras --dev + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache - name: Run all tests with coverage report run: uv run poe all-tests -n logical --dist loadfile --dist worksteal --cov-report=xml:python-coverage.xml -q --junitxml=pytest.xml - name: Upload coverage report diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 20413071e7..ef31032840 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -27,17 +27,15 @@ jobs: working-directory: python steps: - uses: actions/checkout@v5 - - name: Set up uv - uses: astral-sh/setup-uv@v6 + - name: Set up python and install the project + id: python-setup + uses: ./.github/actions/python-setup with: - version-file: "python/pyproject.toml" - enable-cache: true - cache-suffix: ${{ runner.os }}-${{ matrix.python-version }} - cache-dependency-glob: "**/uv.lock" - - name: Install the project - run: | - uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit - + python-version: ${{ matrix.python-version }} + os: ${{ runner.os }} + env: + # Configure a constant location for the uv cache + UV_CACHE_DIR: /tmp/.uv-cache # Main package tests - name: Set environment variables - main - win if: ${{ matrix.os == 'windows-latest' }} @@ -104,28 +102,6 @@ jobs: name: coverage-${{ matrix.OS }}-${{ matrix.python-version }}-${{ env.PACKAGE_NAME }} path: ./python/coverage_${{ matrix.OS }}_${{ matrix.python-version }}_${{ env.PACKAGE_NAME }}.xml - # Workflow package tests - - name: Set environment variables - workflow - win - if: ${{ matrix.os == 'windows-latest' }} - run: | - echo "PACKAGE_NAME=workflow" | Out-File -FilePath $env:GITHUB_ENV -Append - - name: Set environment variables - workflow - if: ${{ matrix.os != 'windows-latest' }} - run: | - echo "PACKAGE_NAME=workflow" >> $GITHUB_ENV - - name: Test with pytest - workflow - run: uv run poe --directory ./packages/${{ env.PACKAGE_NAME }} test -n logical --dist loadfile --dist worksteal --junitxml=coverage.xml - working-directory: ./python - - name: Move coverage file - workflow - run: | - mv ./packages/${{ env.PACKAGE_NAME }}/coverage.xml coverage_${{ matrix.OS }}_${{ matrix.python-version }}_${{ env.PACKAGE_NAME }}.xml - working-directory: ./python - - name: Upload coverage artifact - workflow - uses: actions/upload-artifact@v4 - with: - name: coverage-${{ matrix.OS }}-${{ matrix.python-version }}-${{ env.PACKAGE_NAME }} - path: ./python/coverage_${{ matrix.OS }}_${{ matrix.python-version }}_${{ env.PACKAGE_NAME }}.xml - # Surface failing tests - name: Surface failing tests if: always() diff --git a/.gitignore b/.gitignore index 1df3d497a1..90901d5faf 100644 --- a/.gitignore +++ b/.gitignore @@ -70,7 +70,7 @@ instance/ .scrapy # Sphinx documentation -docs/_build/ +docs/build/ # PyBuilder .pybuilder/ diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx index 2b07e3346d..e662856548 100644 --- a/dotnet/agent-framework-dotnet.slnx +++ b/dotnet/agent-framework-dotnet.slnx @@ -50,6 +50,7 @@ + @@ -190,6 +191,10 @@ + + + + @@ -206,6 +211,10 @@ + + + + diff --git a/dotnet/eng/MSBuild/LegacySupport.props b/dotnet/eng/MSBuild/LegacySupport.props index c921bc59a2..54d65288bd 100644 --- a/dotnet/eng/MSBuild/LegacySupport.props +++ b/dotnet/eng/MSBuild/LegacySupport.props @@ -22,4 +22,12 @@ + + + + + + + + \ No newline at end of file diff --git a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_CustomImplementation/Program.cs b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_CustomImplementation/Program.cs index a2713c80d2..04f8cc8b24 100644 --- a/dotnet/samples/GettingStarted/AgentProviders/Agent_With_CustomImplementation/Program.cs +++ b/dotnet/samples/GettingStarted/AgentProviders/Agent_With_CustomImplementation/Program.cs @@ -39,8 +39,7 @@ namespace SampleApp List responseMessages = CloneAndToUpperCase(messages, this.DisplayName).ToList(); // Notify the thread of the input and output messages. - await NotifyThreadOfNewMessagesAsync(thread, messages, cancellationToken); - await NotifyThreadOfNewMessagesAsync(thread, responseMessages, cancellationToken); + await NotifyThreadOfNewMessagesAsync(thread, messages.Concat(responseMessages), cancellationToken); return new AgentRunResponse { @@ -59,8 +58,7 @@ namespace SampleApp List responseMessages = CloneAndToUpperCase(messages, this.DisplayName).ToList(); // Notify the thread of the input and output messages. - await NotifyThreadOfNewMessagesAsync(thread, messages, cancellationToken); - await NotifyThreadOfNewMessagesAsync(thread, responseMessages, cancellationToken); + await NotifyThreadOfNewMessagesAsync(thread, messages.Concat(responseMessages), cancellationToken); foreach (var message in responseMessages) { diff --git a/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Agent_Step13_Memory.csproj b/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Agent_Step13_Memory.csproj new file mode 100644 index 0000000000..68b0f8d36b --- /dev/null +++ b/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Agent_Step13_Memory.csproj @@ -0,0 +1,22 @@ + + + + Exe + net9.0 + + enable + disable + + + + + + + + + + + + + + diff --git a/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Program.cs b/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Program.cs new file mode 100644 index 0000000000..c91c81bd4b --- /dev/null +++ b/dotnet/samples/GettingStarted/Agents/Agent_Step13_Memory/Program.cs @@ -0,0 +1,152 @@ +// Copyright (c) Microsoft. All rights reserved. + +// This sample shows how to add a basic custom memory component to an agent. +// The memory component subscribes to all messages added to the conversation and +// extracts the user's name and age if provided. +// The component adds a prompt to ask for this information if it is not already known +// and provides it to the model before each invocation if known. + +using System; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Azure.AI.OpenAI; +using Azure.Identity; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.AI.Agents; +using OpenAI; +using OpenAI.Chat; +using SampleApp; + +var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set."); +var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini"; + +ChatClient chatClient = new AzureOpenAIClient( + new Uri(endpoint), + new AzureCliCredential()) + .GetChatClient(deploymentName); + +// Create the agent and provide a factory to add our custom memory component to +// all threads created by the agent. Here each new memory component will have its own +// user info object, so each thread will have its own memory. +// In real world applications/services, where the user info would be persisted in a database, +// and preferably shared between multiple threads used by the same user, ensure that the +// factory reads the user id from the current context and scopes the memory component +// and its storage to that user id. +AIAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions() +{ + Instructions = "You are a friendly assistant. Always address the user by their name.", + AIContextProviderFactory = () => new SampleApp.UserInfoMemory(chatClient.AsIChatClient()) +}); + +// Create a new thread for the conversation. +AgentThread thread = agent.GetNewThread(); + +Console.WriteLine(">> Use thread with blank memory\n"); + +// Invoke the agent and output the text result. +Console.WriteLine(await agent.RunAsync("Hello, what is the square root of 9?", thread)); +Console.WriteLine(await agent.RunAsync("My name is Ruaidhrí", thread)); +Console.WriteLine(await agent.RunAsync("I am 20 years old", thread)); + +// We can serialize the thread. The serialized state will include the state of the memory component. +var threadElement = await thread.SerializeAsync(); + +Console.WriteLine("\n>> Use deserialized thread with previously created memories\n"); + +// Later we can deserialize the thread and continue the conversation with the previous memory component state. +var deserializedThread = await agent.DeserializeThreadAsync(threadElement); +Console.WriteLine(await agent.RunAsync("What is my name and age?", deserializedThread)); + +Console.WriteLine("\n>> Read memories from memory component\n"); + +// It's possible to access the memory component via the thread's AIContextProvider property. +var userInfo = ((UserInfoMemory)deserializedThread.AIContextProvider!).UserInfo; + +// Output the user info that was captured by the memory component. +Console.WriteLine($"MEMORY - User Name: {userInfo.UserName}"); +Console.WriteLine($"MEMORY - User Age: {userInfo.UserAge}"); + +Console.WriteLine("\n>> Use new thread with previously created memories\n"); + +// Create a new thread. +thread = agent.GetNewThread(); + +// It is also possible to add the memory component to an individual thread only instead of all +// threads via the factory above. +// In this case we will also use the same user info object, so this thread will share the same +// memories as the previous thread. +thread.AIContextProvider = new UserInfoMemory(chatClient.AsIChatClient(), userInfo); + +// Invoke the agent and output the text result. +// This time the agent should remember the user's name and use it in the response. +Console.WriteLine(await agent.RunAsync("What is my name and age?", thread)); + +namespace SampleApp +{ + /// + /// Sample memory component that can remember a user's name and age. + /// + internal sealed class UserInfoMemory(IChatClient chatClient, UserInfo? userInfo = null) : AIContextProvider + { + public UserInfo UserInfo { get; set; } = userInfo ?? new(); + + public override async ValueTask InvokedAsync(InvokedContext context, CancellationToken cancellationToken = default) + { + // Try and extract the user name and age from the message if we don't have it already and it's a user message. + if ((this.UserInfo.UserName == null || this.UserInfo.UserAge == null) && context.RequestMessages.Any(x => x.Role == ChatRole.User)) + { + var result = await chatClient.GetResponseAsync( + context.RequestMessages, + new ChatOptions() + { + Instructions = "Extract the user's name and age from the message if present. If not present return nulls." + }, + cancellationToken: cancellationToken); + + this.UserInfo.UserName ??= result.Result.UserName; + this.UserInfo.UserAge ??= result.Result.UserAge; + } + } + + public override ValueTask InvokingAsync(InvokingContext context, CancellationToken cancellationToken = default) + { + StringBuilder instructions = new(); + + // If we don't already know the user's name and age, add instructions to ask for them, otherwise just provide what we have to the context. + instructions.AppendLine( + this.UserInfo.UserName == null ? + "Ask the user for their name and politely decline to answer any questions until they provide it." : + $"The user's name is {this.UserInfo.UserName}."); + + instructions.AppendLine( + this.UserInfo.UserAge == null ? + "Ask the user for their age and politely decline to answer any questions until they provide it." : + $"The user's age is {this.UserInfo.UserAge}."); + + return new ValueTask(new AIContext + { + Instructions = instructions.ToString() + }); + } + + public override ValueTask SerializeAsync(JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + return new ValueTask(JsonSerializer.SerializeToElement(this.UserInfo, jsonSerializerOptions)); + } + + public override ValueTask DeserializeAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + this.UserInfo = JsonSerializer.Deserialize(serializedState, jsonSerializerOptions) ?? new UserInfo(); + return default; + } + } + + internal sealed class UserInfo + { + public string? UserName { get; set; } + public int? UserAge { get; set; } + } +} diff --git a/dotnet/samples/GettingStarted/Agents/README.md b/dotnet/samples/GettingStarted/Agents/README.md index 43da38e0ff..d831fab364 100644 --- a/dotnet/samples/GettingStarted/Agents/README.md +++ b/dotnet/samples/GettingStarted/Agents/README.md @@ -37,7 +37,8 @@ Before you begin, ensure you have the following prerequisites: |[Dependency injection with a simple agent](./Agent_Step09_DependencyInjection/)|This sample demonstrates how to add and resolve an agent with a dependency injection container| |[Exposing a simple agent as MCP tool](./Agent_Step10_AsMcpTool/)|This sample demonstrates how to expose an agent as an MCP tool| |[Using images with a simple agent](./Agent_Step11_UsingImages/)|This sample demonstrates how to use image multi-modality with an AI agent| -|[Exposing a simple agent a function tool](./Agent_Step12_AsFunctionTool/)|This sample demonstrates how to expose an agent as a function tool| +|[Exposing a simple agent as a function tool](./Agent_Step12_AsFunctionTool/)|This sample demonstrates how to expose an agent as a function tool| +|[Using memory with an agent](./Agent_Step12_Memory/)|This sample demonstrates how to create a simple memory component and use it with an agent| ## Running the samples from the console diff --git a/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/CompilerFeatureRequiredAttribute.cs b/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/CompilerFeatureRequiredAttribute.cs new file mode 100644 index 0000000000..74a67d7c6e --- /dev/null +++ b/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/CompilerFeatureRequiredAttribute.cs @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft. All rights reserved. + +#pragma warning disable SA1623 // Property summary documentation should match accessors + +namespace System.Runtime.CompilerServices; + +/// +/// Indicates that compiler support for a particular feature is required for the location where this attribute is applied. +/// +[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] +internal sealed class CompilerFeatureRequiredAttribute : Attribute +{ + public CompilerFeatureRequiredAttribute(string featureName) + { + FeatureName = featureName; + } + + /// + /// The name of the compiler feature. + /// + public string FeatureName { get; } + + /// + /// If true, the compiler can choose to allow access to the location where this attribute is applied if it does not understand . + /// + public bool IsOptional { get; init; } + + /// + /// The used for the ref structs C# feature. + /// + public const string RefStructs = nameof(RefStructs); + + /// + /// The used for the required members C# feature. + /// + public const string RequiredMembers = nameof(RequiredMembers); +} diff --git a/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/README.md b/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/README.md new file mode 100644 index 0000000000..c30799eef0 --- /dev/null +++ b/dotnet/src/LegacySupport/CompilerFeatureRequiredAttribute/README.md @@ -0,0 +1,9 @@ +Enables use of C# required members on older frameworks. + +To use this source in your project, add the following to your `.csproj` file: + +```xml + + true + +``` diff --git a/dotnet/src/LegacySupport/RequiredMemberAttribute/README.md b/dotnet/src/LegacySupport/RequiredMemberAttribute/README.md new file mode 100644 index 0000000000..da8c9bc98c --- /dev/null +++ b/dotnet/src/LegacySupport/RequiredMemberAttribute/README.md @@ -0,0 +1,9 @@ +Enables use of C# required members on older frameworks. + +To use this source in your project, add the following to your `.csproj` file: + +```xml + + true + +``` diff --git a/dotnet/src/LegacySupport/RequiredMemberAttribute/RequiredMemberAttribute.cs b/dotnet/src/LegacySupport/RequiredMemberAttribute/RequiredMemberAttribute.cs new file mode 100644 index 0000000000..1a82954140 --- /dev/null +++ b/dotnet/src/LegacySupport/RequiredMemberAttribute/RequiredMemberAttribute.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.ComponentModel; + +namespace System.Runtime.CompilerServices; + +/// Specifies that a type has required members or that a member is required. +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +[EditorBrowsable(EditorBrowsableState.Never)] +internal sealed class RequiredMemberAttribute : Attribute; diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIAgent.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIAgent.cs index 395f075029..b744a17892 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIAgent.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIAgent.cs @@ -290,6 +290,6 @@ public abstract class AIAgent _ = Throw.IfNull(thread); _ = Throw.IfNull(messages); - await thread.OnNewMessagesAsync(messages, cancellationToken).ConfigureAwait(false); + await thread.MessagesReceivedAsync(messages, cancellationToken).ConfigureAwait(false); } } diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContext.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContext.cs new file mode 100644 index 0000000000..f0c8e64bff --- /dev/null +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContext.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Collections.Generic; + +namespace Microsoft.Extensions.AI.Agents; + +/// +/// A class containing any context that should be provided to the AI model +/// as supplied by an . +/// +/// +/// Each has the ability to provide its own context for each invocation. +/// The class contains the additional context supplied by the . +/// This context will be combined with context supplied by other providers before being passed to the AI model. +/// +public sealed class AIContext +{ + /// + /// Gets or sets any instructions to pass to the AI model in addition to any other prompts + /// that it may already have (in the case of an agent), or chat history that may + /// already exist. + /// + /// + /// These instructions will be transient and only apply to the current invocation. + /// + public string? Instructions { get; set; } + + /// + /// Gets or sets a list of messages to add to the chat history. + /// + /// + /// These messages will permanently be added to the chat history. + /// + public IList? Messages { get; set; } + + /// + /// Gets or sets a list of functions/tools to make available to the AI model for the current invocation. + /// + /// + /// These functions/tools will be transient and only apply to the current invocation. + /// + public IList? Tools { get; set; } +} diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContextProvider.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContextProvider.cs new file mode 100644 index 0000000000..fc6d244051 --- /dev/null +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AIContextProvider.cs @@ -0,0 +1,118 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Extensions.AI.Agents; + +/// +/// Base class for all AI context providers. +/// +/// +/// An AI context provider is a component that can be used to enhance the AI's context management. +/// It can listen to changes in the conversation, provide additional context to +/// the Model/Agent/etc. just before invocation and supply additional function tools. +/// +public abstract class AIContextProvider +{ + /// + /// Called just before the Model/Agent/etc. is invoked + /// Implementers can load any additional context required at this time, + /// and they should return any context that should be passed to the Model/Agent/etc. + /// + /// Contains the event context. + /// The to monitor for cancellation requests. The default is . + /// A task that completes when the context has been rendered and returned. + public abstract ValueTask InvokingAsync(InvokingContext context, CancellationToken cancellationToken = default); + + /// + /// Called just before the Model/Agent/etc. is invoked + /// Implementers can load any additional context required at this time, + /// and they should return any context that should be passed to the Model/Agent/etc. + /// + /// Contains the event context. + /// The to monitor for cancellation requests. The default is . + /// A task that completes when the context has been rendered and returned. + public virtual ValueTask InvokedAsync(InvokedContext context, CancellationToken cancellationToken = default) + { + return default; + } + + /// + /// Serializes the current object's state to a using the specified serialization options. + /// + /// The JSON serialization options to use. + /// The to monitor for cancellation requests. The default is . + /// A representation of the object's state. + public virtual ValueTask SerializeAsync(JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + return default; + } + + /// + /// Deserializes the state contained in the provided into the properties on this object. + /// + /// A representing the state of the object. + /// Optional settings for customizing the JSON deserialization process. + /// The to monitor for cancellation requests. The default is . + /// A that completes when the state has been deserialized. + public virtual ValueTask DeserializeAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + return default; + } + + /// + /// Contains the event context provided to . + /// + public class InvokingContext + { + /// + /// Initializes a new instance of the class. + /// + /// The messages to be sent to the Model/Agent/etc. for this invocation. + /// Thrown if is . + public InvokingContext(IEnumerable requestMessages) + { + RequestMessages = requestMessages ?? throw new ArgumentNullException(nameof(requestMessages)); + } + + /// + /// Gets the messages that will be sent to the Model/Agent/etc. for this invocation. + /// + public IEnumerable RequestMessages { get; private set; } + } + + /// + /// Contains the event conext provided to . + /// + public class InvokedContext + { + /// + /// Initializes a new instance of the class with the specified request messages. + /// + /// The messages that were sent to the Model/Agent/etc. for this invocation. + /// Thrown if is . + public InvokedContext(IEnumerable requestMessages) + { + RequestMessages = requestMessages ?? throw new ArgumentNullException(nameof(requestMessages)); + } + + /// + /// Gets the messages that were sent to the Model/Agent/etc. for this invocation. + /// + public IEnumerable RequestMessages { get; private set; } + + /// + /// Gets the collection of response messages generated by Model/Agent/etc. if the invocation succeeded. + /// + public IEnumerable? ResponseMessages { get; init; } + + /// + /// Gets the that was thrown during the invocation, if the invocation failed. + /// + public Exception? InvokeException { get; init; } + } +} diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs index 74a5c8108e..9b1fbcdb5b 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/AgentThread.cs @@ -27,7 +27,7 @@ public class AgentThread } /// - /// Gets or sets the id of the current thread to support cases where the thread is owned by the agent service. + /// Gets or sets the ID of the underlying service thread to support cases where the chat history is stored by the agent service. /// /// /// @@ -108,6 +108,11 @@ public class AgentThread } } + /// + /// Gets or sets the used by this thread to provide additional context to the AI model before each invocation. + /// + public AIContextProvider? AIContextProvider { get; set; } + /// /// Serializes the current object's state to a using the specified serialization options. /// @@ -120,10 +125,15 @@ public class AgentThread null : await this._messageStore.SerializeStateAsync(jsonSerializerOptions, cancellationToken).ConfigureAwait(false); + var aiContextProviderState = this.AIContextProvider is null ? + null : + await this.AIContextProvider.SerializeAsync(jsonSerializerOptions, cancellationToken).ConfigureAwait(false); + var state = new ThreadState { ConversationId = this.ConversationId, - StoreState = storeState + StoreState = storeState, + AIContextProviderState = aiContextProviderState }; return JsonSerializer.SerializeToElement(state, AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(ThreadState))); @@ -139,7 +149,7 @@ public class AgentThread /// The to monitor for cancellation requests. The default is . /// A task that completes when the context has been updated. /// The thread has been deleted. - protected internal virtual async Task OnNewMessagesAsync(IEnumerable newMessages, CancellationToken cancellationToken = default) + protected internal virtual async Task MessagesReceivedAsync(IEnumerable newMessages, CancellationToken cancellationToken = default) { switch (this) { @@ -186,6 +196,11 @@ public class AgentThread return; } + if (state?.AIContextProviderState.HasValue is true && this.AIContextProvider is not null) + { + await this.AIContextProvider.DeserializeAsync(state.AIContextProviderState.Value, jsonSerializerOptions, cancellationToken).ConfigureAwait(false); + } + // If we don't have any IChatMessageStore state return here. if (state?.StoreState is null || state?.StoreState.Value.ValueKind is JsonValueKind.Undefined or JsonValueKind.Null) { @@ -206,5 +221,7 @@ public class AgentThread public string? ConversationId { get; set; } public JsonElement? StoreState { get; set; } + + public JsonElement? AIContextProviderState { get; set; } } } diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/Microsoft.Extensions.AI.Agents.Abstractions.csproj b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/Microsoft.Extensions.AI.Agents.Abstractions.csproj index 0bdc6a5b49..c4f910dbec 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/Microsoft.Extensions.AI.Agents.Abstractions.csproj +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.Abstractions/Microsoft.Extensions.AI.Agents.Abstractions.csproj @@ -12,6 +12,9 @@ true true true + true + true + true diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/AssistantClientResultExtensions.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/AssistantClientResultExtensions.cs new file mode 100644 index 0000000000..6faf65eacb --- /dev/null +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/AssistantClientResultExtensions.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.ClientModel; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.AI.Agents; + +namespace OpenAI.Assistants; + +/// +/// Provides extension methods for working with where T is . +/// +public static class AssistantExtensions +{ + /// + /// Converts a to a . + /// + /// The client result containing the assistant. + /// The assistant client. + /// Optional chat options. + /// A instance that can be used to perform operations on the assistant. + public static ChatClientAgent AsAIAgent(this ClientResult assistantClientResult, AssistantClient assistantClient, ChatOptions? chatOptions = null) + { + if (assistantClientResult is null) + { + throw new ArgumentNullException(nameof(assistantClientResult)); + } + + return AssistantExtensions.AsAIAgent(assistantClientResult, assistantClient, chatOptions); + } + + /// + /// Converts an to a . + /// + /// The assistant metadata. + /// The assistant client. + /// Optional chat options. + /// A instance that can be used to perform operations on the assistant. + public static ChatClientAgent AsAIAgent(this Assistant assistantMetadata, AssistantClient assistantClient, ChatOptions? chatOptions = null) + { + if (assistantMetadata is null) + { + throw new ArgumentNullException(nameof(assistantMetadata)); + } + if (assistantClient is null) + { + throw new ArgumentNullException(nameof(assistantClient)); + } + +#pragma warning disable CA2000 // Dispose objects before losing scope + var chatClient = assistantClient.AsIChatClient(assistantMetadata.Id); +#pragma warning restore CA2000 // Dispose objects before losing scope + + return new ChatClientAgent(chatClient, options: new() + { + Id = assistantMetadata.Id, + Name = assistantMetadata.Name, + Description = assistantMetadata.Description, + Instructions = assistantMetadata.Instructions, + ChatOptions = chatOptions + }); + } +} diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs b/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs index cfba779c1e..60cd192480 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents.OpenAI/Extensions/OpenAIAssistantClientExtensions.cs @@ -20,6 +20,63 @@ namespace OpenAI; /// public static class OpenAIAssistantClientExtensions { + /// + /// Retrieves an existing server side agent, wrapped as a using the provided . + /// + /// The to create the with. + /// The ID of the server side agent to create a for. + /// Options that should apply to all runs of the agent. + /// The to monitor for cancellation requests. The default is . + /// A instance that can be used to perform operations on the assistant agent. + public static ChatClientAgent GetAIAgent( + this AssistantClient assistantClient, + string agentId, + ChatOptions? chatOptions = null, + CancellationToken cancellationToken = default) + { + if (assistantClient is null) + { + throw new ArgumentNullException(nameof(assistantClient)); + } + + if (string.IsNullOrWhiteSpace(agentId)) + { + throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); + } + + var assistant = assistantClient.GetAssistant(agentId, cancellationToken); + return assistant.AsAIAgent(assistantClient, chatOptions); + } + + /// + /// Retrieves an existing server side agent, wrapped as a using the provided . + /// + /// The to create the with. + /// The ID of the server side agent to create a for. + /// Options that should apply to all runs of the agent. + /// The to monitor for cancellation requests. The default is . + /// A instance that can be used to perform operations on the assistant agent. + public static async Task GetAIAgentAsync( + this AssistantClient assistantClient, + string agentId, + ChatOptions? chatOptions = null, + CancellationToken cancellationToken = default) + { + if (assistantClient is null) + { + throw new ArgumentNullException(nameof(assistantClient)); + } + + if (string.IsNullOrWhiteSpace(agentId)) + { + throw new ArgumentException($"{nameof(agentId)} should not be null or whitespace.", nameof(agentId)); + } + + var assistanceResponse = await assistantClient.GetAssistantAsync(agentId, cancellationToken).ConfigureAwait(false); + + return assistanceResponse.AsAIAgent(assistantClient, chatOptions); + } + /// /// Creates an AI agent from an using the OpenAI Assistant API. /// diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs index 3deafcdc6f..5878cc71c9 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgent.cs @@ -114,7 +114,17 @@ public sealed class ChatClientAgent : AIAgent this._logger.LogAgentChatClientInvokingAgent(nameof(RunAsync), this.Id, agentName, this._chatClientType); - ChatResponse chatResponse = await this.ChatClient.GetResponseAsync(threadMessages, chatOptions, cancellationToken).ConfigureAwait(false); + // Call the IChatClient and notify the AIContextProvider of any failures. + ChatResponse chatResponse; + try + { + chatResponse = await this.ChatClient.GetResponseAsync(threadMessages, chatOptions, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + await NotifyAIContextProviderOfFailureAsync(safeThread, ex, inputMessages, cancellationToken).ConfigureAwait(false); + throw; + } this._logger.LogAgentChatClientInvokedAgent(nameof(RunAsync), this.Id, agentName, this._chatClientType, inputMessages.Count); @@ -122,19 +132,17 @@ public sealed class ChatClientAgent : AIAgent // so let's update it and set the conversation id for the service thread case. this.UpdateThreadWithTypeAndConversationId(safeThread, chatResponse.ConversationId); - // Only notify the thread of new messages if the chatResponse was successful to avoid inconsistent messages state in the thread. - await NotifyThreadOfNewMessagesAsync(safeThread, inputMessages, cancellationToken).ConfigureAwait(false); - // Ensure that the author name is set for each message in the response. foreach (ChatMessage chatResponseMessage in chatResponse.Messages) { chatResponseMessage.AuthorName ??= agentName; } - // Convert the chat response messages to a valid IReadOnlyCollection for notification signatures below. - var chatResponseMessages = chatResponse.Messages as IReadOnlyCollection ?? [.. chatResponse.Messages]; + // Only notify the thread of new messages if the chatResponse was successful to avoid inconsistent message state in the thread. + await NotifyThreadOfNewMessagesAsync(safeThread, inputMessages.Concat(chatResponse.Messages), cancellationToken).ConfigureAwait(false); - await NotifyThreadOfNewMessagesAsync(safeThread, chatResponseMessages, cancellationToken).ConfigureAwait(false); + // Notify the AIContextProvider of all new messages. + await NotifyAIContextProviderOfSuccessAsync(safeThread, inputMessages, chatResponse.Messages, cancellationToken).ConfigureAwait(false); return new(chatResponse) { AgentId = this.Id }; } @@ -156,15 +164,34 @@ public sealed class ChatClientAgent : AIAgent this._logger.LogAgentChatClientInvokingAgent(nameof(RunStreamingAsync), this.Id, loggingAgentName, this._chatClientType); - // Using the enumerator to ensure we consider the case where no updates are returned for notification. - var responseUpdatesEnumerator = this.ChatClient.GetStreamingResponseAsync(threadMessages, chatOptions, cancellationToken).GetAsyncEnumerator(cancellationToken); + List responseUpdates = []; + + IAsyncEnumerator responseUpdatesEnumerator; + + try + { + // Using the enumerator to ensure we consider the case where no updates are returned for notification. + responseUpdatesEnumerator = this.ChatClient.GetStreamingResponseAsync(threadMessages, chatOptions, cancellationToken).GetAsyncEnumerator(cancellationToken); + } + catch (Exception ex) + { + await NotifyAIContextProviderOfFailureAsync(safeThread, ex, inputMessages, cancellationToken).ConfigureAwait(false); + throw; + } this._logger.LogAgentChatClientInvokedStreamingAgent(nameof(RunStreamingAsync), this.Id, loggingAgentName, this._chatClientType); - List responseUpdates = []; - - // Ensure we start the streaming request - var hasUpdates = await responseUpdatesEnumerator.MoveNextAsync().ConfigureAwait(false); + bool hasUpdates; + try + { + // Ensure we start the streaming request + hasUpdates = await responseUpdatesEnumerator.MoveNextAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + await NotifyAIContextProviderOfFailureAsync(safeThread, ex, inputMessages, cancellationToken).ConfigureAwait(false); + throw; + } while (hasUpdates) { @@ -176,20 +203,28 @@ public sealed class ChatClientAgent : AIAgent yield return new(update) { AgentId = this.Id }; } - hasUpdates = await responseUpdatesEnumerator.MoveNextAsync().ConfigureAwait(false); + try + { + hasUpdates = await responseUpdatesEnumerator.MoveNextAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + await NotifyAIContextProviderOfFailureAsync(safeThread, ex, inputMessages, cancellationToken).ConfigureAwait(false); + throw; + } } var chatResponse = responseUpdates.ToChatResponse(); - var chatResponseMessages = chatResponse.Messages as IReadOnlyCollection ?? [.. chatResponse.Messages]; // We can derive the type of supported thread from whether we have a conversation id, // so let's update it and set the conversation id for the service thread case. this.UpdateThreadWithTypeAndConversationId(safeThread, chatResponse.ConversationId); // To avoid inconsistent state we only notify the thread of the input messages if no error occurs after the initial request. - await NotifyThreadOfNewMessagesAsync(safeThread, inputMessages, cancellationToken).ConfigureAwait(false); + await NotifyThreadOfNewMessagesAsync(safeThread, inputMessages.Concat(chatResponse.Messages), cancellationToken).ConfigureAwait(false); - await NotifyThreadOfNewMessagesAsync(safeThread, chatResponseMessages, cancellationToken).ConfigureAwait(false); + // Notify the AIContextProvider of all new messages. + await NotifyAIContextProviderOfSuccessAsync(safeThread, inputMessages, chatResponse.Messages, cancellationToken).ConfigureAwait(false); } /// @@ -204,12 +239,40 @@ public sealed class ChatClientAgent : AIAgent /// public override AgentThread GetNewThread() { - var thread = new AgentThread { MessageStore = this._agentOptions?.ChatMessageStoreFactory?.Invoke() }; + var thread = new AgentThread + { + MessageStore = this._agentOptions?.ChatMessageStoreFactory?.Invoke(), + AIContextProvider = this._agentOptions?.AIContextProviderFactory?.Invoke() + }; return thread; } #region Private + /// + /// Notify the when an agent run succeeded, if there is an . + /// + private static async Task NotifyAIContextProviderOfSuccessAsync(AgentThread thread, IEnumerable inputMessages, IEnumerable responseMessages, CancellationToken cancellationToken) + { + if (thread.AIContextProvider is not null) + { + await thread.AIContextProvider.InvokedAsync(new(inputMessages) { ResponseMessages = responseMessages }, + cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Notify the of any failure during an agent run, if there is an . + /// + private static async Task NotifyAIContextProviderOfFailureAsync(AgentThread thread, Exception ex, IEnumerable inputMessages, CancellationToken cancellationToken) + { + if (thread.AIContextProvider is not null) + { + await thread.AIContextProvider.InvokedAsync(new(inputMessages) { InvokeException = ex }, + cancellationToken).ConfigureAwait(false); + } + } + /// /// Configures and returns chat options by merging the provided run options with the agent's default chat options. /// @@ -350,6 +413,34 @@ public sealed class ChatClientAgent : AIAgent threadMessages.AddRange(await thread.MessageStore.GetMessagesAsync(cancellationToken).ConfigureAwait(false)); } + // If we have an AIContextProvider, we should get context from it, and update our + // messages and options with the additional context. + if (thread.AIContextProvider is not null) + { + var invokingContext = new AIContextProvider.InvokingContext(inputMessages); + var aiContext = await thread.AIContextProvider.InvokingAsync(invokingContext, cancellationToken).ConfigureAwait(false); + if (aiContext.Messages is { Count: > 0 }) + { + threadMessages.AddRange(aiContext.Messages); + } + + if (aiContext.Tools is { Count: > 0 }) + { + chatOptions ??= new(); + chatOptions.Tools ??= []; + foreach (AITool tool in aiContext.Tools) + { + chatOptions.Tools.Add(tool); + } + } + + if (aiContext.Instructions is not null) + { + chatOptions ??= new(); + chatOptions.Instructions = string.IsNullOrWhiteSpace(chatOptions.Instructions) ? aiContext.Instructions : $"{chatOptions.Instructions}\n{aiContext.Instructions}"; + } + } + // Add the input messages to the end of thread messages. threadMessages.AddRange(inputMessages); diff --git a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgentOptions.cs b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgentOptions.cs index 2759523cc2..461ed01aa3 100644 --- a/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgentOptions.cs +++ b/dotnet/src/Microsoft.Extensions.AI.Agents/ChatCompletion/ChatClientAgentOptions.cs @@ -80,6 +80,13 @@ public class ChatClientAgentOptions /// public Func? ChatMessageStoreFactory { get; set; } + /// + /// Gets or sets a factory function to create an instance of + /// which will be used to create a context provider for each new thread, and can then + /// provide additional context for each agent run. + /// + public Func? AIContextProviderFactory { get; set; } + /// /// Gets or sets a value indicating whether to use the provided instance as is, /// without applying any default decorators. @@ -105,6 +112,7 @@ public class ChatClientAgentOptions Instructions = this.Instructions, Description = this.Description, ChatOptions = this.ChatOptions?.Clone(), - ChatMessageStoreFactory = this.ChatMessageStoreFactory + ChatMessageStoreFactory = this.ChatMessageStoreFactory, + AIContextProviderFactory = this.AIContextProviderFactory, }; } diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIAgentTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIAgentTests.cs index 04cd8584c8..9906b62a21 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIAgentTests.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIAgentTests.cs @@ -235,7 +235,7 @@ public class AIAgentTests await MockAgent.NotifyThreadOfNewMessagesAsync(threadMock.Object, messages, cancellationToken); - threadMock.Protected().Verify("OnNewMessagesAsync", Times.Once(), messages, cancellationToken); + threadMock.Protected().Verify("MessagesReceivedAsync", Times.Once(), messages, cancellationToken); } #region GetService Method Tests diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextProviderTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextProviderTests.cs new file mode 100644 index 0000000000..f5eea0d5ed --- /dev/null +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextProviderTests.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Extensions.AI.Agents.Abstractions.UnitTests; + +public class AIContextProviderTests +{ + [Fact] + public async Task InvokedAsync_ReturnsCompletedTaskAsync() + { + var provider = new TestAIContextProvider(); + var messages = new ReadOnlyCollection(new List()); + var task = provider.InvokedAsync(new(messages)); + Assert.Equal(default, task); + } + + [Fact] + public async Task SerializeAsync_ReturnsEmptyElementAsync() + { + var provider = new TestAIContextProvider(); + var actual = await provider.SerializeAsync(); + Assert.Equal(default, actual); + } + + [Fact] + public async Task DeserializeAsync_ReturnsCompletedTaskAsync() + { + var provider = new TestAIContextProvider(); + var element = default(JsonElement); + var actual = provider.DeserializeAsync(element); + Assert.Equal(default, actual); + } + + private sealed class TestAIContextProvider : AIContextProvider + { + public override ValueTask InvokingAsync(InvokingContext context, CancellationToken cancellationToken = default) + { + return default; + } + + public override async ValueTask SerializeAsync(JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + return await base.SerializeAsync(jsonSerializerOptions, cancellationToken); + } + + public override async ValueTask DeserializeAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) + { + await base.DeserializeAsync(serializedState, jsonSerializerOptions, cancellationToken); + } + } +} diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextTests.cs new file mode 100644 index 0000000000..2a85a525e5 --- /dev/null +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AIContextTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Collections.Generic; + +namespace Microsoft.Extensions.AI.Agents.Abstractions.UnitTests; + +/// +/// Unit tests for . +/// +public class AIContextTests +{ + [Fact] + public void SetInstructionsRoundtrips() + { + var context = new AIContext + { + Instructions = "Test Instructions" + }; + + Assert.Equal("Test Instructions", context.Instructions); + } + + [Fact] + public void SetMessagesRoundtrips() + { + var context = new AIContext + { + Messages = new List + { + new(ChatRole.User, "Hello"), + new(ChatRole.Assistant, "Hi there!") + } + }; + + Assert.NotNull(context.Messages); + Assert.Equal(2, context.Messages.Count); + Assert.Equal("Hello", context.Messages[0].Text); + Assert.Equal("Hi there!", context.Messages[1].Text); + } + + [Fact] + public void SetAIFunctionsRoundtrips() + { + var context = new AIContext + { + Tools = new List + { + AIFunctionFactory.Create(() => "Function1", "Function1", "Description1"), + AIFunctionFactory.Create(() => "Function2", "Function2", "Description2"), + } + }; + + Assert.NotNull(context.Tools); + Assert.Equal(2, context.Tools.Count); + Assert.Equal("Function1", context.Tools[0].Name); + Assert.Equal("Function2", context.Tools[1].Name); + } +} diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs index 305fc1cd45..843ea3fb0f 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/AgentThreadTests.cs @@ -8,6 +8,8 @@ using System.Threading; using System.Threading.Tasks; using Moq; +#pragma warning disable CA1861 // Avoid constant arrays as arguments + namespace Microsoft.Extensions.AI.Agents.Abstractions.UnitTests; public class AgentThreadTests @@ -102,7 +104,7 @@ public class AgentThreadTests }; // Act - await thread.OnNewMessagesAsync(messages, CancellationToken.None); + await thread.MessagesReceivedAsync(messages, CancellationToken.None); Assert.Equal("thread-123", thread.ConversationId); Assert.Null(thread.MessageStore); } @@ -120,7 +122,7 @@ public class AgentThreadTests }; // Act - await thread.OnNewMessagesAsync(messages, CancellationToken.None); + await thread.MessagesReceivedAsync(messages, CancellationToken.None); // Assert Assert.Equal(2, store.Count); @@ -173,6 +175,26 @@ public class AgentThreadTests Assert.Null(thread.MessageStore); } + [Fact] + public async Task VerifyDeserializeWithAIContextProviderAsync() + { + // Arrange + var json = JsonSerializer.Deserialize(""" + { + "aiContextProviderState": ["CP1"] + } + """, TestJsonSerializerContext.Default.JsonElement); + Mock mockProvider = new(); + var thread = new AgentThread() { AIContextProvider = mockProvider.Object }; + + // Act + await thread.DeserializeAsync(json); + + // Assert + Assert.Null(thread.MessageStore); + mockProvider.Verify(m => m.DeserializeAsync(It.Is(e => e.ValueKind == JsonValueKind.Array && e.GetArrayLength() == 1), It.IsAny(), It.IsAny()), Times.Once); + } + [Fact] public async Task DeserializeWithInvalidJsonThrowsAsync() { @@ -245,6 +267,31 @@ public class AgentThreadTests Assert.Equal("TestContent", textContent.GetProperty("text").GetString()); } + [Fact] + public async Task VerifyThreadSerializationWithWithAIContextProviderAsync() + { + // Arrange + Mock mockProvider = new(); + var providerStateElement = JsonSerializer.SerializeToElement(new[] { "CP1" }, TestJsonSerializerContext.Default.StringArray); + mockProvider + .Setup(m => m.SerializeAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(providerStateElement); + + var thread = new AgentThread(); + thread.AIContextProvider = mockProvider.Object; + + // Act + var json = await thread.SerializeAsync(); + + // Assert + Assert.Equal(JsonValueKind.Object, json.ValueKind); + Assert.True(json.TryGetProperty("aiContextProviderState", out var providerStateProperty)); + Assert.Equal(JsonValueKind.Array, providerStateProperty.ValueKind); + Assert.Single(providerStateProperty.EnumerateArray()); + Assert.Equal("CP1", providerStateProperty.EnumerateArray().First().GetString()); + mockProvider.Verify(m => m.SerializeAsync(It.IsAny(), It.IsAny()), Times.Once); + } + /// /// Verify thread serialization to JSON with custom options. /// diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/TestJsonSerializerContext.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/TestJsonSerializerContext.cs index bd39c6638a..f256ad311c 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/TestJsonSerializerContext.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.Abstractions.UnitTests/TestJsonSerializerContext.cs @@ -17,4 +17,5 @@ namespace Microsoft.Extensions.AI.Agents.Abstractions.UnitTests; [JsonSerializable(typeof(Animal))] [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(Dictionary))] +[JsonSerializable(typeof(string[]))] internal sealed partial class TestJsonSerializerContext : JsonSerializerContext; diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentOptionsTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentOptionsTests.cs index ead3946fc2..d8dd5d52fc 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentOptionsTests.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentOptionsTests.cs @@ -22,6 +22,7 @@ public class ChatClientAgentOptionsTests Assert.Null(options.Description); Assert.Null(options.ChatOptions); Assert.Null(options.ChatMessageStoreFactory); + Assert.Null(options.AIContextProviderFactory); } [Fact] @@ -39,6 +40,7 @@ public class ChatClientAgentOptionsTests Assert.Null(options.Instructions); Assert.Null(options.Description); Assert.Null(options.ChatOptions); + Assert.Null(options.AIContextProviderFactory); } [Fact] @@ -163,11 +165,13 @@ public class ChatClientAgentOptionsTests const string Description = "Test description"; var tools = new List { AIFunctionFactory.Create(() => "test") }; static IChatMessageStore ChatMessageStoreFactory() => new Mock().Object; + static AIContextProvider AIContextProviderFactory() => new Mock().Object; var original = new ChatClientAgentOptions(Instructions, Name, Description, tools) { Id = "test-id", - ChatMessageStoreFactory = ChatMessageStoreFactory + ChatMessageStoreFactory = ChatMessageStoreFactory, + AIContextProviderFactory = AIContextProviderFactory }; // Act @@ -180,6 +184,7 @@ public class ChatClientAgentOptionsTests Assert.Equal(original.Instructions, clone.Instructions); Assert.Equal(original.Description, clone.Description); Assert.Same(original.ChatMessageStoreFactory, clone.ChatMessageStoreFactory); + Assert.Same(original.AIContextProviderFactory, clone.AIContextProviderFactory); // ChatOptions should be cloned, not the same reference Assert.NotSame(original.ChatOptions, clone.ChatOptions); @@ -209,5 +214,7 @@ public class ChatClientAgentOptionsTests Assert.Equal(original.Instructions, clone.Instructions); Assert.Equal(original.Description, clone.Description); Assert.Null(clone.ChatOptions); + Assert.Null(clone.ChatMessageStoreFactory); + Assert.Null(clone.AIContextProviderFactory); } } diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentTests.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentTests.cs index 46afaace36..4ec63e04cd 100644 --- a/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentTests.cs +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/ChatCompletion/ChatClientAgentTests.cs @@ -10,6 +10,8 @@ namespace Microsoft.Extensions.AI.Agents.UnitTests.ChatCompletion; public class ChatClientAgentTests { + #region Constructor Tests + /// /// Verify the invocation and response of . /// @@ -38,6 +40,10 @@ public class ChatClientAgentTests Assert.Equal("AgentInvokedChatClient", agent.ChatClient.GetType().Name); } + #endregion + + #region RunAsync Tests + /// /// Verify the invocation and response of using . /// @@ -390,6 +396,176 @@ public class ChatClientAgentTests await Assert.ThrowsAsync(() => agent.RunAsync([new(ChatRole.User, "test")], thread)); } + /// + /// Verify that RunAsync sets the ConversationId on the thread when the service returns one. + /// + [Fact] + public async Task RunAsyncSetsConversationIdOnThreadWhenReturnedByChatClientAsync() + { + // Arrange + Mock mockService = new(); + mockService.Setup( + s => s.GetResponseAsync( + It.IsAny>(), + It.IsAny(), + It.IsAny())).ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")]) { ConversationId = "ConvId" }); + ChatClientAgent agent = new(mockService.Object, options: new() { Instructions = "test instructions" }); + AgentThread thread = new(); + + // Act + await agent.RunAsync([new(ChatRole.User, "test")], thread); + + // Assert + Assert.Equal("ConvId", thread.ConversationId); + } + + /// + /// Verify that RunAsync invokes any provided AIContextProvider and uses the result. + /// + [Fact] + public async Task RunAsyncInvokesAIContextProviderAndUsesResultAsync() + { + // Arrange + ChatMessage[] requestMessages = [new(ChatRole.User, "user message")]; + ChatMessage[] responseMessages = [new(ChatRole.Assistant, "response")]; + Mock mockService = new(); + List capturedMessages = []; + string capturedInstructions = string.Empty; + List capturedTools = []; + mockService + .Setup(s => s.GetResponseAsync( + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .Callback, ChatOptions, CancellationToken>((msgs, opts, ct) => + { + capturedMessages.AddRange(msgs); + capturedInstructions = opts.Instructions ?? string.Empty; + if (opts.Tools != null) + { + capturedTools.AddRange(opts.Tools); + } + }) + .ReturnsAsync(new ChatResponse(responseMessages)); + + var mockProvider = new Mock(); + mockProvider + .Setup(p => p.InvokingAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new AIContext + { + Messages = [new(ChatRole.System, "context provider message")], + Instructions = "context provider instructions", + Tools = [AIFunctionFactory.Create(() => { }, "context provider function")] + }); + mockProvider + .Setup(p => p.InvokedAsync(It.IsAny(), It.IsAny())) + .Returns(new ValueTask()); + + ChatClientAgent agent = new(mockService.Object, options: new() { Instructions = "base instructions", AIContextProviderFactory = () => mockProvider.Object, ChatOptions = new() { Tools = [AIFunctionFactory.Create(() => { }, "base function")] } }); + + // Act + await agent.RunAsync(requestMessages); + + // Assert + // Should contain: base instructions, context message, user message, base function, context function + Assert.Equal(2, capturedMessages.Count); + Assert.Equal("base instructions\ncontext provider instructions", capturedInstructions); + Assert.Equal("context provider message", capturedMessages[0].Text); + Assert.Equal(ChatRole.System, capturedMessages[0].Role); + Assert.Equal("user message", capturedMessages[1].Text); + Assert.Equal(ChatRole.User, capturedMessages[1].Role); + Assert.Equal(2, capturedTools.Count); + Assert.Contains(capturedTools, t => t.Name == "base function"); + Assert.Contains(capturedTools, t => t.Name == "context provider function"); + mockProvider.Verify(p => p.InvokingAsync(It.IsAny(), It.IsAny()), Times.Once); + mockProvider.Verify(p => p.InvokedAsync(It.Is(x => x.RequestMessages == requestMessages && x.ResponseMessages == responseMessages && x.InvokeException == null), It.IsAny()), Times.Once); + } + + /// + /// Verify that RunAsync invokes any provided AIContextProvider when the downstream GetResponse call fails. + /// + [Fact] + public async Task RunAsyncInvokesAIContextProviderWhenGetResponseFailsAsync() + { + // Arrange + ChatMessage[] requestMessages = [new(ChatRole.User, "user message")]; + ChatMessage[] responseMessages = [new(ChatRole.Assistant, "response")]; + Mock mockService = new(); + mockService + .Setup(s => s.GetResponseAsync( + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .Throws(new InvalidOperationException("downstream failure")); + + var mockProvider = new Mock(); + mockProvider + .Setup(p => p.InvokingAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new AIContext()); + mockProvider + .Setup(p => p.InvokedAsync(It.IsAny(), It.IsAny())) + .Returns(new ValueTask()); + + ChatClientAgent agent = new(mockService.Object, options: new() { Instructions = "base instructions", AIContextProviderFactory = () => mockProvider.Object, ChatOptions = new() { Tools = [AIFunctionFactory.Create(() => { }, "base function")] } }); + + // Act + await Assert.ThrowsAsync(() => agent.RunAsync(requestMessages)); + + // Assert + mockProvider.Verify(p => p.InvokingAsync(It.IsAny(), It.IsAny()), Times.Once); + mockProvider.Verify(p => p.InvokedAsync(It.Is(x => x.RequestMessages == requestMessages && x.ResponseMessages == null && x.InvokeException is InvalidOperationException), It.IsAny()), Times.Once); + } + + /// + /// Verify that RunAsync invokes any provided AIContextProvider and succeeds even when the AIContext is empty. + /// + [Fact] + public async Task RunAsyncInvokesAIContextProviderAndSucceedsWithEmptyAIContextAsync() + { + // Arrange + Mock mockService = new(); + List capturedMessages = []; + string capturedInstructions = string.Empty; + List capturedTools = []; + mockService + .Setup(s => s.GetResponseAsync( + It.IsAny>(), + It.IsAny(), + It.IsAny())) + .Callback, ChatOptions, CancellationToken>((msgs, opts, ct) => + { + capturedMessages.AddRange(msgs); + capturedInstructions = opts.Instructions ?? string.Empty; + if (opts.Tools != null) + { + capturedTools.AddRange(opts.Tools); + } + }) + .ReturnsAsync(new ChatResponse([new(ChatRole.Assistant, "response")])); + + var mockProvider = new Mock(); + mockProvider + .Setup(p => p.InvokingAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new AIContext()); + + ChatClientAgent agent = new(mockService.Object, options: new() { Instructions = "base instructions", AIContextProviderFactory = () => mockProvider.Object, ChatOptions = new() { Tools = [AIFunctionFactory.Create(() => { }, "base function")] } }); + + // Act + await agent.RunAsync([new(ChatRole.User, "user message")]); + + // Assert + // Should contain: base instructions, user message, base function + Assert.Single(capturedMessages); + Assert.Equal("base instructions", capturedInstructions); + Assert.Equal("user message", capturedMessages[0].Text); + Assert.Equal(ChatRole.User, capturedMessages[0].Role); + Assert.Single(capturedTools); + Assert.Contains(capturedTools, t => t.Name == "base function"); + mockProvider.Verify(p => p.InvokingAsync(It.IsAny(), It.IsAny()), Times.Once); + } + + #endregion + #region Property Override Tests /// @@ -1524,6 +1700,61 @@ public class ChatClientAgentTests #endregion + #region GetNewThread Tests + + [Fact] + public void GetNewThreadUsesChatMessageStoreFactoryIfProvided() + { + // Arrange + var mockChatClient = new Mock(); + var mockStore = new Mock(); + var factoryCalled = false; + + var agent = new ChatClientAgent(mockChatClient.Object, new ChatClientAgentOptions + { + Instructions = "Test instructions", + ChatMessageStoreFactory = () => + { + factoryCalled = true; + return mockStore.Object; + } + }); + + // Act + var thread = agent.GetNewThread(); + + // Assert + Assert.True(factoryCalled, "ChatMessageStoreFactory was not called."); + Assert.Same(mockStore.Object, thread.MessageStore); + } + + [Fact] + public void GetNewThreadUsesAIContextProviderFactoryIfProvided() + { + // Arrange + var mockChatClient = new Mock(); + var mockContextProvider = new Mock(); + var factoryCalled = false; + var agent = new ChatClientAgent(mockChatClient.Object, new ChatClientAgentOptions + { + Instructions = "Test instructions", + AIContextProviderFactory = () => + { + factoryCalled = true; + return mockContextProvider.Object; + } + }); + + // Act + var thread = agent.GetNewThread(); + + // Assert + Assert.True(factoryCalled, "AIContextProviderFactory was not called."); + Assert.Same(mockContextProvider.Object, thread.AIContextProvider); + } + + #endregion + private static async IAsyncEnumerable ToAsyncEnumerableAsync(IEnumerable values) { await Task.Yield(); diff --git a/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/TestJsonSerializerContext.cs b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/TestJsonSerializerContext.cs new file mode 100644 index 0000000000..d3d1f00118 --- /dev/null +++ b/dotnet/tests/Microsoft.Extensions.AI.Agents.UnitTests/TestJsonSerializerContext.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft. All rights reserved. + +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.Extensions.AI.Agents.UnitTests; + +[JsonSourceGenerationOptions( + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + UseStringEnumConverter = true)] +[JsonSerializable(typeof(JsonElement))] +[JsonSerializable(typeof(string))] +internal sealed partial class TestJsonSerializerContext : JsonSerializerContext; diff --git a/python/.vscode/launch.json b/python/.vscode/launch.json index b9788cad64..b0ab97127e 100644 --- a/python/.vscode/launch.json +++ b/python/.vscode/launch.json @@ -11,6 +11,15 @@ "program": "${file}", "console": "integratedTerminal", "justMyCode": false + }, + { + "name": "Python Attach", + "type": "debugpy", + "request": "attach", + "connect": { + "host": "localhost", + "port": 5678 + } } ] } diff --git a/python/DEV_SETUP.md b/python/DEV_SETUP.md index 08764f8063..a041712443 100644 --- a/python/DEV_SETUP.md +++ b/python/DEV_SETUP.md @@ -550,6 +550,12 @@ uv run poe test ### Documentation +#### `docs-install` +Install including the documentation tools: +```bash +uv run poe docs-install +``` + #### `docs-clean` Remove the docs build directory: ```bash @@ -562,22 +568,34 @@ Build the documentation: uv run poe docs-build ``` -#### `docs-serve` -Serve documentation locally with auto-reload: +#### `docs-full` +Build the packages, clean and build the documentation: ```bash -uv run poe docs-serve +uv run poe docs-full ``` -#### `docs-check` -Build documentation and fail on warnings: +#### `docs-rebuild` +Clean and build the documentation: ```bash -uv run poe docs-check +uv run poe docs-rebuild ``` -#### `docs-check-examples` -Check documentation examples for code correctness: +#### `docs-full-install` +Install the docs dependencies, build the packages, clean and build the documentation: ```bash -uv run poe docs-check-examples +uv run poe docs-full-install +``` + +#### `docs-debug` +Build the documentation with debug information: +```bash +uv run poe docs-debug +``` + +#### `docs-rebuild-debug` +Clean and build the documentation with debug information: +```bash +uv run poe docs-rebuild-debug ``` ### Code Validation diff --git a/python/README.md b/python/README.md index 2098eda85d..c5f3b61a97 100644 --- a/python/README.md +++ b/python/README.md @@ -3,6 +3,7 @@ ## Quick Install ```bash +# Base package including workflow support pip install agent-framework # Optional: Add Azure integration pip install agent-framework[azure] diff --git a/python/check_md_code_blocks.py b/python/check_md_code_blocks.py index ac88061f4c..b61bfd2743 100644 --- a/python/check_md_code_blocks.py +++ b/python/check_md_code_blocks.py @@ -3,19 +3,35 @@ """Check code blocks in Markdown files for syntax errors.""" import argparse +from enum import Enum import logging import tempfile +import subprocess # nosec from pygments import highlight # type: ignore from pygments.formatters import TerminalFormatter from pygments.lexers import PythonLexer -from sphinx.util.console import darkgreen, darkred, faint, red, teal # type: ignore[attr-defined] logger = logging.getLogger(__name__) logger.addHandler(logging.StreamHandler()) logger.setLevel(logging.INFO) +class Colors(str, Enum): + CEND = "\33[0m" + CRED = "\33[31m" + CREDBG = "\33[41m" + CGREEN = "\33[32m" + CGREENBG = "\33[42m" + CVIOLET = "\33[35m" + CGREY = "\33[90m" + + +def with_color(text: str, color: Colors) -> str: + """Prints a string with the specified color.""" + return f"{color.value}{text}{Colors.CEND.value}" + + def extract_python_code_blocks(markdown_file_path: str) -> list[tuple[str, int]]: """Extract Python code blocks from a Markdown file.""" with open(markdown_file_path, encoding="utf-8") as file: @@ -40,7 +56,7 @@ def extract_python_code_blocks(markdown_file_path: str) -> list[tuple[str, int]] def check_code_blocks(markdown_file_paths: list[str]) -> None: """Check Python code blocks in a Markdown file for syntax errors.""" - files_with_errors = [] + files_with_errors: list[str] = [] for markdown_file_path in markdown_file_paths: code_blocks = extract_python_code_blocks(markdown_file_path) @@ -54,7 +70,7 @@ def check_code_blocks(markdown_file_paths: list[str]) -> None: all(import_code not in code_block for import_code in [f"import {module}", f"from {module}"]) for module in ["agent_framework"] ): - logger.info(" " + darkgreen("OK[ignored]")) + logger.info(f' {with_color("OK[ignored]", Colors.CGREENBG)}') continue with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp_file: @@ -62,17 +78,25 @@ def check_code_blocks(markdown_file_paths: list[str]) -> None: temp_file.flush() # Run pyright on the temporary file using subprocess.run - import subprocess # nosec result = subprocess.run(["pyright", temp_file.name], capture_output=True, text=True) # nosec if result.returncode != 0: - logger.info(" " + darkred("FAIL")) highlighted_code = highlight(code_block, PythonLexer(), TerminalFormatter()) # type: ignore - output = f"{faint('========================================================')}\n{red('Error')}: Pyright found issues in {teal(markdown_file_path_with_line_no)}:\n{faint('--------------------------------------------------------')}\n{highlighted_code}\n{faint('--------------------------------------------------------')}\n\n{teal('pyright output:')}\n{red(result.stdout)}{faint('========================================================')}\n" - logger.info(output) + logger.info( + f" {with_color('FAIL', Colors.CREDBG)}\n" + f"{with_color('========================================================', Colors.CGREY)}\n" + f"{with_color('Error', Colors.CRED)}: Pyright found issues in {with_color(markdown_file_path_with_line_no, Colors.CVIOLET)}:\n" + f"{with_color('--------------------------------------------------------', Colors.CGREY)}\n" + f"{highlighted_code}\n" + f"{with_color('--------------------------------------------------------', Colors.CGREY)}\n" + "\n" + f"{with_color('pyright output:', Colors.CVIOLET)}\n" + f"{with_color(result.stdout, Colors.CRED)}" + f"{with_color('========================================================', Colors.CGREY)}\n" + ) had_errors = True else: - logger.info(" " + darkgreen("OK")) + logger.info(f" {with_color('OK', Colors.CGREENBG)}") if had_errors: files_with_errors.append(markdown_file_path) diff --git a/python/docs/README.md b/python/docs/README.md deleted file mode 100644 index 8d25d91529..0000000000 --- a/python/docs/README.md +++ /dev/null @@ -1,37 +0,0 @@ -## Building the Agent Framework Documentation - -Agent Framework documentation is based on the sphinx documentation system and uses the myst-parser to render markdown files. It uses the [pydata-sphinx-theme](https://pydata-sphinx-theme.readthedocs.io/en/latest/) to style the documentation. - -### Prerequisites - -Ensure you have all of the dev dependencies for the `agent-framework` package installed. You can install them by running the following command from the root of the `python` directory: - -```bash -uv sync -source .venv/bin/activate -``` - -## Building Docs - -To build the documentation, run the following command from the root of the python repository: - -```bash -poe docs-build -``` - -To serve the documentation locally, run the following command from the root of the python repository: - -```bash -poe --directory ./packages/autogen-core/ docs-serve -``` - -[!NOTE] -Sphinx will only rebuild files that have changed since the last build. If you want to force a full rebuild, you can run `poe docs-clean` before running the `docs-build` command. - -## Versioning the Documentation - -The current theme - [pydata-sphinx-theme](https://pydata-sphinx-theme.readthedocs.io/en/latest/) - supports [switching between versions](https://pydata-sphinx-theme.readthedocs.io/en/stable/user_guide/version-dropdown.html) of the documentation. - -To version the documentation, you need to create a new version of the documentation by copying the existing documentation to a new directory with the version number. For example, to create a new version of the documentation for version `0.1.0`, you would run the following command: - -How are various versions built? - TBD. \ No newline at end of file diff --git a/python/docs/agent-framework/_apidoc_templates/module.rst.jinja b/python/docs/agent-framework/_apidoc_templates/module.rst.jinja deleted file mode 100644 index 3878eba033..0000000000 --- a/python/docs/agent-framework/_apidoc_templates/module.rst.jinja +++ /dev/null @@ -1,8 +0,0 @@ -{%- if show_headings %} -{{- basename | e | heading }} - -{% endif -%} -.. automodule:: {{ qualname }} -{%- for option in automodule_options %} - :{{ option }}: -{%- endfor %} diff --git a/python/docs/agent-framework/_apidoc_templates/package.rst.jinja b/python/docs/agent-framework/_apidoc_templates/package.rst.jinja deleted file mode 100644 index 3a8e91f358..0000000000 --- a/python/docs/agent-framework/_apidoc_templates/package.rst.jinja +++ /dev/null @@ -1,53 +0,0 @@ -{%- macro automodule(modname, options) -%} -.. automodule:: {{ modname }} -{%- for option in options %} - :{{ option }}: -{%- endfor %} -{%- endmacro %} - -{%- macro toctree(docnames) -%} -.. toctree:: - :maxdepth: {{ maxdepth }} - :hidden: -{% for docname in docnames %} - {{ docname }} -{%- endfor %} -{%- endmacro %} - -{%- if is_namespace %} -{{- [pkgname, "namespace"] | join(" ") | e | heading }} -{% else %} -{{- pkgname | e | heading }} -{% endif %} - -{%- if is_namespace %} -.. py:module:: {{ pkgname }} -{% endif %} - -{%- if modulefirst and not is_namespace %} -{{ automodule(pkgname, automodule_options) }} -{% endif %} - -{%- if subpackages %} - -{{ toctree(subpackages) }} -{% endif %} - -{%- if submodules %} - -{% if separatemodules %} -{{ toctree(submodules) }} -{% else %} -{%- for submodule in submodules %} -{% if show_headings %} -{{- [submodule, "module"] | join(" ") | e | heading(2) }} -{% endif %} -{{ automodule(submodule, automodule_options) }} -{% endfor %} -{%- endif %} -{%- endif %} - -{%- if not modulefirst and not is_namespace %} - -{{ automodule(pkgname, automodule_options) }} -{% endif %} \ No newline at end of file diff --git a/python/docs/agent-framework/_extension/code_lint.py b/python/docs/agent-framework/_extension/code_lint.py deleted file mode 100644 index d46164519b..0000000000 --- a/python/docs/agent-framework/_extension/code_lint.py +++ /dev/null @@ -1,98 +0,0 @@ -# Modified from: https://github.com/kai687/sphinxawesome-codelinter - -import tempfile -from collections.abc import Iterable -from typing import AbstractSet, Any - -from docutils import nodes -from pygments import highlight # type: ignore -from pygments.formatters import TerminalFormatter -from pygments.lexers import PythonLexer -from sphinx.application import Sphinx -from sphinx.builders import Builder -from sphinx.util import logging -from sphinx.util.console import darkgreen, darkred, faint, red, teal # type: ignore[attr-defined] - -logger = logging.getLogger(__name__) - -__version__ = "0.1.0" - - -class CodeLinter(Builder): - """Iterate over all ``literal_block`` nodes. - - pipe them into any command line tool that - can read from standard input. - """ - - name = "code_lint" - allow_parallel = True - - def init(self) -> None: - """Initialize.""" - self._had_errors = False - pass - - def get_outdated_docs(self) -> str | Iterable[str]: - """Check for outdated files. - - Return an iterable of outdated output files, or a string describing what an - update will build. - """ - return self.env.found_docs - - def get_target_uri(self, docname: str, typ: str | None = None) -> str: - """Return Target URI for a document name.""" - return "" - - def prepare_writing(self, docnames: AbstractSet[str]) -> None: - """Run these steps before documents are written.""" - return - - def write_doc(self, docname: str, doctree: nodes.Node) -> None: - path_prefix: str = self.app.config.code_lint_path_prefix - supported_languages = {"python", "default"} - - if not docname.startswith(path_prefix): - return - - for code in doctree.findall(nodes.literal_block): - if code["language"] in supported_languages: - logger.info("Checking a code block in %s...", docname, nonl=True) - if "ignore" in code["classes"]: - logger.info(" " + darkgreen("OK[ignored]")) - continue - - # Create a temporary file to store the code block - with tempfile.NamedTemporaryFile(mode="wb", suffix=".py") as temp_file: - temp_file.write(code.astext().encode()) - temp_file.flush() - - # Run pyright on the temporary file using subprocess.run - import subprocess - - result = subprocess.run(["pyright", temp_file.name], capture_output=True, text=True) - if result.returncode != 0: - logger.info(" " + darkred("FAIL")) - highlighted_code = highlight(code.astext(), PythonLexer(), TerminalFormatter()) # type: ignore - output = f"{faint('========================================================')}\n{red('Error')}: Pyright found issues in {teal(docname)}:\n{faint('--------------------------------------------------------')}\n{highlighted_code}\n{faint('--------------------------------------------------------')}\n\n{teal('pyright output:')}\n{red(result.stdout)}{faint('========================================================')}\n" - logger.info(output) - self._had_errors = True - else: - logger.info(" " + darkgreen("OK")) - - def finish(self) -> None: - """Finish the build process.""" - if self._had_errors: - raise RuntimeError("Code linting failed - see earlier output") - - -def setup(app: Sphinx) -> dict[str, Any]: - app.add_builder(CodeLinter) - app.add_config_value("code_lint_path_prefix", "", "env") - - return { - "version": __version__, - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/python/docs/agent-framework/_extension/gallery_directive.py b/python/docs/agent-framework/_extension/gallery_directive.py deleted file mode 100644 index 1cebee6445..0000000000 --- a/python/docs/agent-framework/_extension/gallery_directive.py +++ /dev/null @@ -1,144 +0,0 @@ -"""A directive to generate a gallery of images from structured data. - -Generating a gallery of images that are all the same size is a common -pattern in documentation, and this can be cumbersome if the gallery is -generated programmatically. This directive wraps this particular use-case -in a helper-directive to generate it with a single YAML configuration file. - -It currently exists for maintainers of the pydata-sphinx-theme, -but might be abstracted into a standalone package if it proves useful. -""" - -from pathlib import Path -from typing import Any, ClassVar - -from docutils import nodes -from docutils.parsers.rst import directives -from sphinx.application import Sphinx -from sphinx.util import logging -from sphinx.util.docutils import SphinxDirective -from yaml import safe_load - -logger = logging.getLogger(__name__) - - -TEMPLATE_GRID = """ -`````{{grid}} {columns} -{options} - -{content} - -````` -""" - -GRID_CARD = """ -````{{grid-item-card}} {title} -{options} - -{content} -```` -""" - - -class GalleryGridDirective(SphinxDirective): - """A directive to show a gallery of images and links in a Bootstrap grid. - - The grid can be generated from a YAML file that contains a list of items, or - from the content of the directive (also formatted in YAML). Use the parameter - "class-card" to add an additional CSS class to all cards. When specifying the grid - items, you can use all parameters from "grid-item-card" directive to customize - individual cards + ["image", "header", "content", "title"]. - - Danger: - This directive can only be used in the context of a Myst documentation page as - the templates use Markdown flavored formatting. - """ - - name = "gallery-grid" - has_content = True - required_arguments = 0 - optional_arguments = 1 - final_argument_whitespace = True - option_spec: ClassVar[dict[str, Any]] = { - # A class to be added to the resulting container - "grid-columns": directives.unchanged, - "class-container": directives.unchanged, - "class-card": directives.unchanged, - } - - def run(self) -> list[nodes.Node]: - """Create the gallery grid.""" - if self.arguments: - # If an argument is given, assume it's a path to a YAML file - # Parse it and load it into the directive content - path_data_rel = Path(self.arguments[0]) - path_doc, _ = self.get_source_info() - path_doc = Path(path_doc).parent - path_data = (path_doc / path_data_rel).resolve() - if not path_data.exists(): - logger.info(f"Could not find grid data at {path_data}.") - nodes.text("No grid data found at {path_data}.") - return None - yaml_string = path_data.read_text() - else: - yaml_string = "\n".join(self.content) - - # Use all the element with an img-bottom key as sites to show - # and generate a card item for each of them - grid_items = [] - for item in safe_load(yaml_string): - # remove parameters that are not needed for the card options - title = item.pop("title", "") - - # build the content of the card using some extra parameters - header = f"{item.pop('header')} \n^^^ \n" if "header" in item else "" - image = f"![image]({item.pop('image')}) \n" if "image" in item else "" - content = f"{item.pop('content')} \n" if "content" in item else "" - - # optional parameter that influence all cards - if "class-card" in self.options: - item["class-card"] = self.options["class-card"] - - loc_options_str = "\n".join(f":{k}: {v}" for k, v in item.items()) + " \n" - - card = GRID_CARD.format( - options=loc_options_str, content=header + image + content, title=title - ) - grid_items.append(card) - - # Parse the template with Sphinx Design to create an output container - # Prep the options for the template grid - class_ = "gallery-directive" + f' {self.options.get("class-container", "")}' - options = {"gutter": 2, "class-container": class_} - options_str = "\n".join(f":{k}: {v}" for k, v in options.items()) - - # Create the directive string for the grid - grid_directive = TEMPLATE_GRID.format( - columns=self.options.get("grid-columns", "1 2 3 4"), - options=options_str, - content="\n".join(grid_items), - ) - - # Parse content as a directive so Sphinx Design processes it - container = nodes.container() - self.state.nested_parse([grid_directive], 0, container) - - # Sphinx Design outputs a container too, so just use that - return [container.children[0]] - - -def setup(app: Sphinx) -> dict[str, Any]: - """Add custom configuration to sphinx app. - - Args: - app: the Sphinx application - - Returns: - the 2 parallel parameters set to ``True``. - """ - app.add_directive("gallery-grid", GalleryGridDirective) - - return { - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/python/docs/agent-framework/_static/banner-override.js b/python/docs/agent-framework/_static/banner-override.js deleted file mode 100644 index e67243f039..0000000000 --- a/python/docs/agent-framework/_static/banner-override.js +++ /dev/null @@ -1,11 +0,0 @@ -var version = DOCUMENTATION_OPTIONS.VERSION; -if (version === "stable") { - var styles = ` -#bd-header-version-warning { - display: none; -} - ` - var styleSheet = document.createElement("style") - styleSheet.textContent = styles - document.head.appendChild(styleSheet) -} \ No newline at end of file diff --git a/python/docs/agent-framework/_static/custom-icon.js b/python/docs/agent-framework/_static/custom-icon.js deleted file mode 100644 index d717c49b0a..0000000000 --- a/python/docs/agent-framework/_static/custom-icon.js +++ /dev/null @@ -1,18 +0,0 @@ -// File from: https://github.com/pydata/pydata-sphinx-theme/blob/main/docs/_static/custom-icon.js - -/******************************************************************************* - * Set a custom icon for pypi as it's not available in the fa built-in brands - */ -FontAwesome.library.add( - (faListOldStyle = { - prefix: "fa-custom", - iconName: "pypi", - icon: [ - 17.313, // viewBox width - 19.807, // viewBox height - [], // ligature - "e001", // unicode codepoint - private use area - "m10.383 0.2-3.239 1.1769 3.1883 1.1614 3.239-1.1798zm-3.4152 1.2411-3.2362 1.1769 3.1855 1.1614 3.2369-1.1769zm6.7177 0.00281-3.2947 1.2009v3.8254l3.2947-1.1988zm-3.4145 1.2439-3.2926 1.1981v3.8254l0.17548-0.064132 3.1171-1.1347zm-6.6564 0.018325v3.8247l3.244 1.1805v-3.8254zm10.191 0.20931v2.3137l3.1777-1.1558zm3.2947 1.2425-3.2947 1.1988v3.8254l3.2947-1.1988zm-8.7058 0.45739c0.00929-1.931e-4 0.018327-2.977e-4 0.027485 0 0.25633 0.00851 0.4263 0.20713 0.42638 0.49826 1.953e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36226 0.13215-0.65608-0.073306-0.65613-0.4588-6.28e-5 -0.38556 0.2938-0.80504 0.65613-0.93662 0.068422-0.024919 0.13655-0.038114 0.20156-0.039466zm5.2913 0.78369-3.2947 1.1988v3.8247l3.2947-1.1981zm-10.132 1.239-3.2362 1.1769 3.1883 1.1614 3.2362-1.1769zm6.7177 0.00213-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2439-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.016195v3.8275l3.244 1.1805v-3.8254zm16.9 0.21143-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2432-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.019027v3.8247l3.244 1.1805v-3.8254zm13.485 1.4497-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm2.4018 0.38127c0.0093-1.83e-4 0.01833-3.16e-4 0.02749 0 0.25633 0.0085 0.4263 0.20713 0.42638 0.49826 1.97e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36188 0.1316-0.65525-0.07375-0.65542-0.4588-1.95e-4 -0.38532 0.29328-0.80469 0.65542-0.93662 0.06842-0.02494 0.13655-0.03819 0.20156-0.03947zm-5.8142 0.86403-3.244 1.1805v1.4201l3.244 1.1805z", // svg path (https://simpleicons.org/icons/pypi.svg) - ], - }), - ); \ No newline at end of file diff --git a/python/docs/agent-framework/_static/custom.css b/python/docs/agent-framework/_static/custom.css deleted file mode 100644 index ae67f8c882..0000000000 --- a/python/docs/agent-framework/_static/custom.css +++ /dev/null @@ -1,147 +0,0 @@ -.bd-footer { - font-size: 0.8rem; -} - -html[data-theme="light"] { - --pst-color-primary: hsl(222.2 47.4% 11.2%); - --pst-color-secondary: #1774E5; - --pst-color-secondary-bg: #1774E5; - --pst-color-accent: #1774E5; - --sd-color-secondary-highlight: #0062cc; - --pst-color-shadow: rgba(0, 0, 0, 0.0); -} - -html[data-theme="dark"] { - --pst-color-primary: hsl(213 31% 91%); - --pst-color-secondary: #017FFF; - --pst-color-secondary-bg: #017FFF; - --pst-color-accent: #017FFF; - --sd-color-secondary-highlight: #0062cc; - --pst-color-shadow: rgba(0, 0, 0, 0.0); -} - -.bd-header-announcement { - color: white; -} - -.bd-header-announcement a { - color: white; -} - -.bd-header-announcement a:hover { - color: white; - text-shadow: 0.5px 0 0 currentColor; -} - -/* Adding header icon hover and focus effects */ -.bd-header a:focus-visible { - color: var(--pst-color-secondary) !important; - text-decoration: underline !important; - text-shadow: 0.5px 0 0 currentColor; - transform: scale(1.05); - transition: all 0.2s ease-in-out; - outline: none; -} - -nav.bd-links .current>a { - box-shadow: inset 1px 0 0 var(--pst-color-primary); -} -@media (forced-colors: active) { - /* Top breadcrumbs navigation (ie: Home > Core > ...) */ - .bd-breadcrumbs .breadcrumb-item > a:focus-visible{ - border: 2px solid var(--pst-color-primary); - } - - /* Left sidebar */ - nav.bd-links .navbar-nav .toctree-l1>a:focus-visible { - border: 2px solid var(--pst-color-primary); - } - nav.bd-links .current>a { - box-shadow: none; - border-left: 4px solid var(--pst-color-primary) !important; - } - - /* Right sidebar */ - .bd-sidebar-secondary .sidebar-secondary-items .nav-item .active { - box-shadow: none; - border-left: 5px solid var(--pst-color-primary) !important; - } - .bd-sidebar-secondary .sidebar-secondary-items .nav-item>a:focus-visible { - border: 2px solid var(--pst-color-primary); - } -} -html[data-theme="light"] .bd-header { - border-bottom: 1px solid var(--pst-color-border); -} - -.admonition, div.admonition { - border: 1px solid var(--pst-color-border); -} - -.api-card { - text-align: center; - font-size: 1.2rem; -} - -.api-card svg { - font-size: 2rem; -} - -.search-button-field { - border-radius: var(--bs-btn-border-radius); -} - -.bd-content .sd-tab-set .sd-tab-content { - border: none; - border-top: 3px solid var(--pst-color-border); - -} -.bd-content .sd-tab-set>input:checked+label { - border: none; - transform: translateY(0); - font-weight: 700; - border-bottom: 4px solid var(--pst-color-secondary); -} -.bd-content .sd-tab-set>input:focus-visible+label { - border: 2px outset var(--pst-color-secondary); - transform: translateY(0); -} -.bd-content .sd-tab-set>label { - border: none; - background-color: transparent; - font-weight: 500; -} - -.card-title { - font-size: 1.2rem; - font-weight: bold; -} - -.card-title svg { - font-size: 2rem; - vertical-align: bottom; - margin-right: 5px; -} - -/* This is gross, but necessary to meet accessibility requirements */ -.headerlink { - visibility: visible !important; -} -/* jupyter notebook output cells */ -.bd-article .docutils .cell_output .output .highlight > pre:focus-visible{ - border: 2px outset var(--pst-color-secondary); -} - -/* Copy button */ -.bd-article .docutils .docutils .copybtn:focus-visible:after { - /* border: 10px outset var(--pst-color-primary); */ - display: block; - opacity: 1; - visibility: visible; -} - -/* Long autodoc module names wrap on prev/next links */ -/* TODO: Should we extend this to the entire site? */ -.prev-next-title { - word-break: break-word; -} \ No newline at end of file diff --git a/python/docs/agent-framework/_static/custom.js b/python/docs/agent-framework/_static/custom.js deleted file mode 100644 index 3cfd649c7d..0000000000 --- a/python/docs/agent-framework/_static/custom.js +++ /dev/null @@ -1,208 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - let liveRegion = createLiveRegion(); - - document.querySelectorAll('.copybtn').forEach(button => { - // Return focus to copy button after activation - button.addEventListener('click', async function (event) { - // Save the current focus - const focusedElement = document.activeElement; - - // Perform the copy action - await copyToClipboard(this); - announceMessage(liveRegion, 'Copied to clipboard'); - - // Restore the focus - focusedElement.focus(); - }); - }); - - document.querySelectorAll('.search-button-field').forEach(button => { - button.addEventListener('click', () => { - // Save the element that had focus before opening the search - const previousFocus = document.activeElement; - - // Add an event listener to handle closing the search - document.addEventListener('keydown', (event) => { - if (event.key === 'Escape') { - // Restore focus to the previous element - previousFocus.focus(); - } - }); - }); - }); - - // Set active TOCtree elements with aria-current=page - document.querySelectorAll('.bd-sidenav .active').forEach(function (element) { - element.setAttribute('aria-current', 'page'); - }); - - // Set secondary navbar (in-page nagivation) active element with aria-current=page - document.addEventListener("activate.bs.scrollspy", function () { - const navLinks = document.querySelectorAll(".bd-toc-nav a"); - - navLinks.forEach((navLink) => { - navLink.parentElement.removeAttribute('aria-current'); - }); - - const activeNavLinks = document.querySelectorAll(".bd-toc-nav a.active"); - activeNavLinks.forEach((navLink) => { - navLink.parentElement.setAttribute('aria-current', 'page'); - }); - }); - - const themeButton = document.querySelector('.theme-switch-button'); - if (themeButton) { - themeButton.addEventListener('click', function () { - const mode = document.documentElement.getAttribute('data-mode'); - announceMessage(liveRegion, `Theme changed to ${mode}`); - }); - } - - // Enhance TOC sections for accessibility - document.querySelectorAll('.caption-text').forEach(caption => { - const sectionTitle = caption.textContent.trim(); - const captionContainer = caption.closest('p.caption'); - if (!captionContainer) return; - - // Find and process navigation lists that belong to this section - findSectionNav(captionContainer, sectionTitle); - }); - - // Version dropdown menu is dynamically generated after page load. Listen for changes to set aria-selected - var observer = new MutationObserver(function () { - document.querySelectorAll('.dropdown-item').forEach(function (element) { - if (element.classList.contains('active')) { - element.setAttribute('aria-selected', 'true'); - } - }); - }); - - // Observe changes in the version-switcher__menu element - var targetNode = document.querySelector('.version-switcher__menu'); - var config = { childList: true, subtree: true }; - - if (targetNode) { - observer.observe(targetNode, config); - } -}); - -async function copyToClipboard(button) { - const targetSelector = button.getAttribute('data-clipboard-target'); - const codeBlock = document.querySelector(targetSelector); - try { - await navigator.clipboard.writeText(codeBlock.textContent); - } catch (err) { - console.error('Failed to copy text: ', err); - } -} - -function createLiveRegion() { - const liveRegion = document.createElement('div'); - liveRegion.setAttribute('role', 'status'); - liveRegion.setAttribute('aria-live', 'assertive'); - liveRegion.style.position = 'absolute'; - liveRegion.style.width = '1px'; - liveRegion.style.height = '1px'; - liveRegion.style.padding = '0'; - liveRegion.style.margin = '-1px'; - liveRegion.style.overflow = 'hidden'; - liveRegion.style.clipPath = 'inset(50%)'; - liveRegion.style.whiteSpace = 'nowrap'; ` ` - liveRegion.style.border = '0'; - document.body.appendChild(liveRegion); - - return liveRegion; -} - -function announceMessage(liveRegion, message) { - liveRegion.textContent = ''; - setTimeout(() => { - liveRegion.textContent = message; - }, 50); -} - -/** - * Find navigation lists belonging to a section and process them - */ -function findSectionNav(captionContainer, sectionTitle) { - let nextElement = captionContainer.nextElementSibling; - - while (nextElement) { - if (nextElement.classList && nextElement.classList.contains('caption')) { - break; - } - - if (nextElement.matches('ul.bd-sidenav')) { - enhanceNavList(nextElement, sectionTitle); - } - - nextElement = nextElement.nextElementSibling; - } -} - -/** - * Process a navigation list by enhancing its links for accessibility - */ -function enhanceNavList(navList, sectionTitle) { - const topLevelItems = navList.querySelectorAll(':scope > li'); - - topLevelItems.forEach(item => { - const link = item.querySelector(':scope > a.reference.internal'); - if (!link) return; - - const linkText = link.textContent.trim(); - link.setAttribute('aria-label', `${sectionTitle}: ${linkText}`); - - enhanceExpandableSections(item, link, linkText, sectionTitle); - }); -} - -/** - * Process expandable sections (details elements) within a navigation item - */ -function enhanceExpandableSections(item, parentLink, parentText, sectionTitle) { - const detailsElements = item.querySelectorAll('details'); - - detailsElements.forEach(details => { - enhanceToggleButton(details, parentText); - enhanceNestedLinks(details, parentLink, parentText, sectionTitle); - }); -} - -/** - * Make toggle buttons more accessible by adding appropriate aria labels - */ -function enhanceToggleButton(details, parentText) { - const summary = details.querySelector('summary'); - if (!summary) return; - - function updateToggleLabel() { - const isExpanded = details.hasAttribute('open'); - const action = isExpanded ? 'Collapse' : 'Expand'; - summary.setAttribute('aria-label', `${action} ${parentText} section`); - } - - updateToggleLabel(); - - summary.addEventListener('click', () => { - setTimeout(updateToggleLabel, 10); - }); -} - -/** - * Enhance nested links with hierarchical aria-labels - */ -function enhanceNestedLinks(details, parentLink, parentText, sectionTitle) { - const nestedLinks = details.querySelectorAll('a.reference.internal'); - - nestedLinks.forEach(link => { - const linkText = link.textContent.trim(); - const parentLabel = parentLink.getAttribute('aria-label'); - - if (parentLabel) { - link.setAttribute('aria-label', `${parentLabel}: ${linkText}`); - } else { - link.setAttribute('aria-label', `${sectionTitle}: ${parentText}: ${linkText}`); - } - }); -} diff --git a/python/docs/agent-framework/_static/images/logo/favicon-16x16.png b/python/docs/agent-framework/_static/images/logo/favicon-16x16.png deleted file mode 100644 index ef6b18ab21..0000000000 --- a/python/docs/agent-framework/_static/images/logo/favicon-16x16.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4a649cf9cca62edf0f4f6e4acf76981fb9b27399b4d598b22b189c92424f4ea -size 434 diff --git a/python/docs/agent-framework/_static/images/logo/favicon-32x32.png b/python/docs/agent-framework/_static/images/logo/favicon-32x32.png deleted file mode 100644 index 7b017c34f7..0000000000 --- a/python/docs/agent-framework/_static/images/logo/favicon-32x32.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a272fc4c4a508fd936c130a727728da6c773de710a5ae600d06fac06329e0f6d -size 998 diff --git a/python/docs/agent-framework/_static/images/logo/favicon-512x512.png b/python/docs/agent-framework/_static/images/logo/favicon-512x512.png deleted file mode 100644 index 2700ece240..0000000000 --- a/python/docs/agent-framework/_static/images/logo/favicon-512x512.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c1f90048923bdaa4e2eeb6ab70f3cc059dc706d43e7208f336102702fc231b81 -size 45618 diff --git a/python/docs/agent-framework/_static/images/logo/favicon.ico b/python/docs/agent-framework/_static/images/logo/favicon.ico deleted file mode 100644 index 16f7a78a7b..0000000000 Binary files a/python/docs/agent-framework/_static/images/logo/favicon.ico and /dev/null differ diff --git a/python/docs/agent-framework/_static/images/logo/logo.svg b/python/docs/agent-framework/_static/images/logo/logo.svg deleted file mode 100644 index 1ae7d1e693..0000000000 --- a/python/docs/agent-framework/_static/images/logo/logo.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/python/docs/agent-framework/_static/switcher.json b/python/docs/agent-framework/_static/switcher.json deleted file mode 100644 index 809a9c26e5..0000000000 --- a/python/docs/agent-framework/_static/switcher.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "name": "v0.2 (stable)", - "version": "0.2", - "url": "https://microsoft.github.io/autogen/0.2/" - }, - { - "version": "dev", - "url": "https://microsoft.github.io/autogen/dev/" - } -] diff --git a/python/docs/agent-framework/_templates/edit-this-page.html b/python/docs/agent-framework/_templates/edit-this-page.html deleted file mode 100644 index 0254d1a2a2..0000000000 --- a/python/docs/agent-framework/_templates/edit-this-page.html +++ /dev/null @@ -1,16 +0,0 @@ -{% if sourcename is defined and theme_use_edit_page_button and page_source_suffix %} - {% set src = sourcename.split('.') %} - -{% endif %} diff --git a/python/docs/agent-framework/_templates/footer-middle-links.html b/python/docs/agent-framework/_templates/footer-middle-links.html deleted file mode 100644 index 62a911b430..0000000000 --- a/python/docs/agent-framework/_templates/footer-middle-links.html +++ /dev/null @@ -1 +0,0 @@ -

Privacy Policy | Consumer Health Privacy

\ No newline at end of file diff --git a/python/docs/agent-framework/_templates/sidebar-nav-bs-agentchat.html b/python/docs/agent-framework/_templates/sidebar-nav-bs-agentchat.html deleted file mode 100644 index afbaff852b..0000000000 --- a/python/docs/agent-framework/_templates/sidebar-nav-bs-agentchat.html +++ /dev/null @@ -1,39 +0,0 @@ -{# Displays the TOC-subtree for pages nested under the currently active top-level TOCtree element. #} - - diff --git a/python/docs/agent-framework/_templates/sidebar-nav-bs-core.html b/python/docs/agent-framework/_templates/sidebar-nav-bs-core.html deleted file mode 100644 index d6288526d3..0000000000 --- a/python/docs/agent-framework/_templates/sidebar-nav-bs-core.html +++ /dev/null @@ -1,38 +0,0 @@ -{# Displays the TOC-subtree for pages nested under the currently active top-level TOCtree element. #} - - diff --git a/python/docs/agent-framework/_templates/sidebar-nav-bs-extensions.html b/python/docs/agent-framework/_templates/sidebar-nav-bs-extensions.html deleted file mode 100644 index b2c27fdfc8..0000000000 --- a/python/docs/agent-framework/_templates/sidebar-nav-bs-extensions.html +++ /dev/null @@ -1,39 +0,0 @@ -{# Displays the TOC-subtree for pages nested under the currently active top-level TOCtree element. #} - - diff --git a/python/docs/agent-framework/_templates/sidebar-nav-bs-studio.html b/python/docs/agent-framework/_templates/sidebar-nav-bs-studio.html deleted file mode 100644 index 7408ca37e0..0000000000 --- a/python/docs/agent-framework/_templates/sidebar-nav-bs-studio.html +++ /dev/null @@ -1,32 +0,0 @@ -{# Displays the TOC-subtree for pages nested under the currently active top-level TOCtree element. #} - - \ No newline at end of file diff --git a/python/docs/agent-framework/_templates/sidebar-nav-bs.html b/python/docs/agent-framework/_templates/sidebar-nav-bs.html deleted file mode 100644 index bb443c687a..0000000000 --- a/python/docs/agent-framework/_templates/sidebar-nav-bs.html +++ /dev/null @@ -1,15 +0,0 @@ -{# Displays the TOC-subtree for pages nested under the currently active top-level TOCtree element. #} - \ No newline at end of file diff --git a/python/docs/agent-framework/_templates/theme-switcher.html b/python/docs/agent-framework/_templates/theme-switcher.html deleted file mode 100644 index d89a012b32..0000000000 --- a/python/docs/agent-framework/_templates/theme-switcher.html +++ /dev/null @@ -1,7 +0,0 @@ -{# Displays an icon to switch between light mode, dark mode, and auto (use browser's setting). #} -{# As the theme switcher will only work when JavaScript is enabled, we hide it with `pst-js-only`. #} - \ No newline at end of file diff --git a/python/docs/agent-framework/_templates/version-banner-override.html b/python/docs/agent-framework/_templates/version-banner-override.html deleted file mode 100644 index 1fa4844f96..0000000000 --- a/python/docs/agent-framework/_templates/version-banner-override.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/python/docs/agent-framework/conf.py b/python/docs/agent-framework/conf.py deleted file mode 100644 index 569499140b..0000000000 --- a/python/docs/agent-framework/conf.py +++ /dev/null @@ -1,210 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -# Configuration file for the Sphinx documentation builder. -# -# For the full list of built-in configuration values, see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -import os -import sys -from pathlib import Path -from typing import Any - -from sphinx.application import Sphinx - -# -- Project information ----------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -import agent_framework -import agent_framework_foundry -import agent_framework_azure - -project = "agent_framework" -copyright = "2025, Microsoft" -author = "Microsoft" -version = "0.1.0b1" - -release_override = os.getenv("SPHINX_RELEASE_OVERRIDE") -if release_override is None or release_override == "": - release = agent_framework.__version__ -else: - release = release_override - -sys.path.append(str(Path(".").resolve())) - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [ - "sphinx.ext.napoleon", - "sphinx.ext.autodoc", - "sphinx.ext.coverage", - "sphinx.ext.autosummary", - "sphinx.ext.todo", - "sphinx.ext.viewcode", - "sphinx.ext.intersphinx", - "sphinx.ext.graphviz", - "sphinxext.rediraffe", - "sphinx_design", - "sphinx_copybutton", - "_extension.gallery_directive", - "myst_nb", - "sphinxcontrib.autodoc_pydantic", - "_extension.code_lint", -] -suppress_warnings = ["myst.header"] - -# Napoleon settings -napoleon_google_docstring = True -napoleon_use_admonition_for_examples = False -napoleon_include_init_with_doc = True -napoleon_custom_sections = [("returns_style", "params_style")] - -templates_path = ["_templates"] - - -# TODO: include all notebooks excluding those requiring remote API access. -nb_execution_mode = "off" - -# Guides and tutorials must succeed. -nb_execution_raise_on_error = True -nb_execution_timeout = 60 - -myst_heading_anchors = 5 - -myst_enable_extensions = [ - "colon_fence", - "linkify", - "strikethrough", -] - -if (path := os.getenv("PY_DOCS_DIR")) is None: - path = "dev" - - -if (switcher_version := os.getenv("PY_SWITCHER_VERSION")) is None: - switcher_version = "dev" - -html_baseurl = f"/agent-framework/{path}/" - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_title = "Agent Framework" - -html_theme = "pydata_sphinx_theme" -html_static_path = ["_static"] -html_css_files = ["custom.css"] - -add_module_names = False - -html_logo = "_static/images/logo/logo.svg" -html_favicon = "_static/images/logo/favicon-512x512.png" - -html_theme_options = { - "header_links_before_dropdown": 6, - "navbar_align": "left", - "check_switcher": False, - # "navbar_start": ["navbar-logo", "version-switcher"], - # "switcher": { - # "json_url": "/_static/switcher.json", - # }, - "show_prev_next": True, - "icon_links": [ - { - "name": "GitHub", - "url": "https://github.com/microsoft/agent-framework", - "icon": "fa-brands fa-github", - }, - ], - "footer_start": ["copyright"], - "footer_center": ["footer-middle-links"], - "footer_end": ["theme-version", "version-banner-override"], - "pygments_light_style": "xcode", - "pygments_dark_style": "monokai", - "navbar_start": ["navbar-logo", "version-switcher"], - "switcher": { - "json_url": "https://raw.githubusercontent.com/microsoft/agent-framework/refs/heads/main/docs/switcher.json", - "version_match": switcher_version, - }, - "show_version_warning_banner": True, -} - -html_js_files = ["custom-icon.js", "banner-override.js", "custom.js"] -html_sidebars = {"packages/index": []} - -html_context = { - "display_github": True, - "github_user": "microsoft", - "github_repo": "agent-framework", - "github_version": "main", - "doc_path": "python/docs/agent-framework/", -} - -autoclass_content = "both" -autodoc_default_options = { - "members": True, - "member-order": "alphabetical", - "undoc-members": True, - "show-inheritance": True, - "imported-members": True, -} -autodoc_pydantic_model_show_json = False -autodoc_pydantic_model_show_config_summary = False -autodoc_pydantic_model_show_json_error_strategy = "coerce" -python_use_unqualified_type_names = True -autodoc_preserve_defaults = True - -intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} - -code_lint_path_prefix = "reference/python" - -nb_mime_priority_overrides = [ - ("code_lint", "image/jpeg", 100), - ("code_lint", "image/png", 100), - ("code_lint", "text/plain", 100), -] - -rediraffe_redirects = {} - - -def setup_to_main(app: Sphinx, pagename: str, templatename: str, context, doctree) -> None: - """Add a function that jinja can access for returning an "edit this page" link pointing to `main`.""" - - def to_main(link: str) -> str: - """Transform "edit on github" links and make sure they always point to the main branch. - - Args: - link: the link to the github edit interface - - Returns: - the link to the tip of the main branch for the same file - """ - links = link.split("/") - idx = links.index("edit") - return "/".join(links[: idx + 1]) + "/main/" + "/".join(links[idx + 2 :]) - - context["to_main"] = to_main - - -def setup(app: Sphinx) -> dict[str, Any]: - """Add custom configuration to sphinx app. - - Args: - app: the Sphinx application - Returns: - the 2 parallel parameters set to ``True``. - """ - app.connect("html-page-context", setup_to_main) - - # Adding here so it is inline and not in a separate file. - clarity_analytics = """(function(c,l,a,r,i,t,y){ - c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)}; - t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i; - y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y); -})(window, document, "clarity", "script", "lnxpe6skj1");""" - app.add_js_file(None, body=clarity_analytics) - - return { - "parallel_read_safe": True, - "parallel_write_safe": True, - } diff --git a/python/docs/agent-framework/index.md b/python/docs/agent-framework/index.md deleted file mode 100644 index ffa078acb5..0000000000 --- a/python/docs/agent-framework/index.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -myst: - html_meta: - "description lang=en": | - Top-level documentation for Agent Framework, a framework for developing applications using AI agents -html_theme.sidebar_secondary.remove: false -sd_hide_title: true ---- - - - -# Agent Framework - -
-
-
-

-Agent Framework -

-

-A framework for building AI agents and applications -

-
-
-
- -
- -::::{grid} -:gutter: 2 - -:::{grid-item-card} {fas}`cube;pst-color-primary` Agent Framework [![PyPi agent-framework](https://img.shields.io/badge/PyPi-agent--framework-blue?logo=pypi)](https://pypi.org/project/agent-framework/) -:shadow: none -:margin: 2 0 0 0 -:columns: 12 12 12 12 - -Create and manage AI agents, workflows, and applications using the Agent Framework. It provides: - -* Deterministic and dynamic agentic workflows for business processes. -* Research on multi-agent collaboration. -* Distributed agents for multi-language applications. - -_Start here if you are getting serious about building multi-agent systems._ - -+++ - -```{button-ref} reference/index -:color: secondary - -Get Started -``` - -::: - -:::{grid-item-card} {fas}`puzzle-piece;pst-color-primary` Extensions [![PyPi agent-framework](https://img.shields.io/badge/PyPi-autogen--ext-blue?logo=pypi)](https://pypi.org/search/?q=agent-framework-) -:shadow: none -:margin: 2 0 0 0 -:columns: 12 12 12 12 - -Implementations of connectors and other external components for the Agent Framework. These extensions allow you to connect to various AI models, services, and tools, enhancing the capabilities of your agents. - -* {py:mod}`~agent-framework.azure` for using Azure services. -* {py:mod}`~agent-framework.foundry` for using Foundry models. -* {py:mod}`~agent-framework.openai` for using OpenAI models. -+++ - -::: - -:::: - -
- -```{toctree} -:maxdepth: 3 -:hidden: - -reference/index -``` diff --git a/python/docs/agent-framework/reference/index.md b/python/docs/agent-framework/reference/index.md deleted file mode 100644 index f9642c8dcf..0000000000 --- a/python/docs/agent-framework/reference/index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -myst: - html_meta: - "description lang=en": | - Agent Framework is a community-driven project. Learn how to get involved, contribute, and connect with the community. ---- - -# API Reference - -```{toctree} -:caption: Agent Framework -:maxdepth: 2 - -python/agent_framework -python/agent_framework.exceptions -python/agent_framework.openai -python/agent_framework.azure -python/agent_framework.foundry -``` diff --git a/python/docs/agent-framework/reference/python/agent_framework.azure.rst b/python/docs/agent-framework/reference/python/agent_framework.azure.rst deleted file mode 100644 index 9ca4738986..0000000000 --- a/python/docs/agent-framework/reference/python/agent_framework.azure.rst +++ /dev/null @@ -1,4 +0,0 @@ -agent_framework.azure -========================== - -.. automodule:: agent_framework.azure diff --git a/python/docs/agent-framework/reference/python/agent_framework.exceptions.rst b/python/docs/agent-framework/reference/python/agent_framework.exceptions.rst deleted file mode 100644 index 7ee054fa05..0000000000 --- a/python/docs/agent-framework/reference/python/agent_framework.exceptions.rst +++ /dev/null @@ -1,5 +0,0 @@ -agent_framework.exceptions -========================== - -.. automodule:: agent_framework.exceptions - :member-order: bysource diff --git a/python/docs/agent-framework/reference/python/agent_framework.foundry.rst b/python/docs/agent-framework/reference/python/agent_framework.foundry.rst deleted file mode 100644 index 5e92de23f5..0000000000 --- a/python/docs/agent-framework/reference/python/agent_framework.foundry.rst +++ /dev/null @@ -1,4 +0,0 @@ -agent_framework.foundry -========================== - -.. automodule:: agent_framework.foundry diff --git a/python/docs/agent-framework/reference/python/agent_framework.openai.rst b/python/docs/agent-framework/reference/python/agent_framework.openai.rst deleted file mode 100644 index 7f8a73ad6d..0000000000 --- a/python/docs/agent-framework/reference/python/agent_framework.openai.rst +++ /dev/null @@ -1,4 +0,0 @@ -agent_framework.openai -========================== - -.. automodule:: agent_framework.openai diff --git a/python/docs/agent-framework/reference/python/agent_framework.rst b/python/docs/agent-framework/reference/python/agent_framework.rst deleted file mode 100644 index e24c689456..0000000000 --- a/python/docs/agent-framework/reference/python/agent_framework.rst +++ /dev/null @@ -1,4 +0,0 @@ -agent_framework -=============== - -.. automodule:: agent_framework diff --git a/python/docs/generate_docs.py b/python/docs/generate_docs.py new file mode 100644 index 0000000000..15325ee7c9 --- /dev/null +++ b/python/docs/generate_docs.py @@ -0,0 +1,107 @@ +# Copyright (c) Microsoft. All rights reserved. + +import debugpy +import asyncio +import json +import os +from pathlib import Path +from dotenv import load_dotenv + +from agent_framework import __version__ as agent_framework_version +from py2docfx.__main__ import main as py2docfx_main + +load_dotenv() + +async def generate_af_docs(root_path: Path): + """Generate documentation for the Agent Framework using py2docfx. + + This function runs the py2docfx command with the specified parameters. + """ + package = { + "packages": [ + { + "package_info": { + "name": "agent-framework", + "version": agent_framework_version, + "install_type": "pypi", + "extras": ["all"], + }, + "sphinx_extensions": [ + "sphinxcontrib.autodoc_pydantic", + "sphinx-pydantic", + "sphinx.ext.autosummary" + ], + "extension_config": { + "napoleon_google_docstring": True, + "napoleon_preprocess_types": True, + "napoleon_use_param": True, + "autodoc_pydantic_field_doc_policy": "both", + "autodoc_pydantic_model_show_json": False, + "autodoc_pydantic_model_show_config_summary": True, + "autodoc_pydantic_model_show_field_summary": True, + "autodoc_pydantic_model_hide_paramlist": False, + "autodoc_pydantic_model_show_json_error_strategy": "coerce", + "autodoc_pydantic_settings_show_config_summary": True, + "autodoc_pydantic_settings_show_field_summary": True, + "python_use_unqualified_type_names": True, + "autodoc_preserve_defaults": True, + "autodoc_class_signature": "separated", + "autodoc_typehints": "both", + "autodoc_typehints_format": "fully-qualified", + "autodoc_default_options": { + "members": True, + "member-order": "alphabetical", + "undoc-members": True, + "show-inheritance": True, + "imported-members": True, + "inherited-members": 'AFBaseModel', + }, + }, + } + ], + "required_packages": [ + { + "install_type": "pypi", + "name": "autodoc_pydantic", + "version": ">=2.0.0", + }, + { + "install_type": "pypi", + "name": "sphinx-pydantic", + } + ], + } + + args = [ + "-o", + str((root_path / "docs" / "build").absolute()), + "-j", + json.dumps(package), + ] + try: + await py2docfx_main(args) + except Exception as e: + print(f"Error generating documentation: {e}") + + +if __name__ == "__main__": + # Ensure the script is run from the correct directory + debug = False + if debug: + debugpy.listen(("localhost", 5678)) + debugpy.wait_for_client() + debugpy.breakpoint() + + current_path = Path(__file__).parent.parent.resolve() + print(f"Current path: {current_path}") + # ensure the dist folder exists + dist_path = current_path / "dist" + if not dist_path.exists(): + print(" Please run `poe build` to generate the dist folder.") + exit(1) + if os.getenv("PIP_FIND_LINKS") != str(dist_path.absolute()): + print(f"Setting PIP_FIND_LINKS to {dist_path.absolute()}") + os.environ["PIP_FIND_LINKS"] = str(dist_path.absolute()) + print(f"Generating documentation in: {current_path / 'docs' / 'build'}") + # Generate the documentation + asyncio.run(generate_af_docs(current_path)) diff --git a/python/packages/azure/pyproject.toml b/python/packages/azure/pyproject.toml index 6b2d1968c7..019278b2df 100644 --- a/python/packages/azure/pyproject.toml +++ b/python/packages/azure/pyproject.toml @@ -82,10 +82,6 @@ include = "../../shared_tasks.toml" mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_azure" test = "pytest --cov=agent_framework_azure --cov-report=term-missing:skip-covered tests" -[tool.uv.build-backend] -module-name = "agent_framework_azure" -module-root = "" - [build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" +requires = ["flit-core >= 3.9,<4.0"] +build-backend = "flit_core.buildapi" diff --git a/python/packages/copilotstudio/README.md b/python/packages/copilotstudio/README.md index fcf211a919..76c3a1f22b 100644 --- a/python/packages/copilotstudio/README.md +++ b/python/packages/copilotstudio/README.md @@ -23,7 +23,7 @@ Before using the Copilot Studio agent, you need: The following environment variables are used for configuration: - `COPILOTSTUDIOAGENT__ENVIRONMENTID` - Your Copilot Studio environment ID -- `COPILOTSTUDIOAGENT__SCHEMANAME` - Your copilot's agent identifier/schema name +- `COPILOTSTUDIOAGENT__SCHEMANAME` - Your copilot's agent identifier/schema name - `COPILOTSTUDIOAGENT__AGENTAPPID` - Your App Registration client ID - `COPILOTSTUDIOAGENT__TENANTID` - Your Azure AD tenant ID @@ -36,7 +36,7 @@ from agent_framework.copilotstudio import CopilotStudioAgent async def main(): # Create agent using environment variables agent = CopilotStudioAgent() - + # Run a simple query result = await agent.run("What is the capital of France?") print(result) @@ -58,19 +58,20 @@ async def main(): client_id=os.environ["COPILOTSTUDIOAGENT__AGENTAPPID"], tenant_id=os.environ["COPILOTSTUDIOAGENT__TENANTID"] ) - + # Create connection settings settings = ConnectionSettings( environment_id=os.environ["COPILOTSTUDIOAGENT__ENVIRONMENTID"], agent_identifier=os.environ["COPILOTSTUDIOAGENT__SCHEMANAME"], cloud=PowerPlatformCloud.PROD, - copilot_agent_type=AgentType.PUBLISHED + copilot_agent_type=AgentType.PUBLISHED, + custom_power_platform_cloud=None ) - + # Create client and agent client = CopilotClient(settings=settings, token=token) agent = CopilotStudioAgent(client=client) - + # Run a query result = await agent.run("What is the capital of Italy?") print(result) @@ -94,4 +95,3 @@ For more comprehensive examples, see the [Copilot Studio examples](https://githu - Explicit settings and manual token acquisition - Different authentication patterns - Error handling and troubleshooting - diff --git a/python/packages/foundry/agent_framework_foundry/_chat_client.py b/python/packages/foundry/agent_framework_foundry/_chat_client.py index 0298d46c62..5861e9abdf 100644 --- a/python/packages/foundry/agent_framework_foundry/_chat_client.py +++ b/python/packages/foundry/agent_framework_foundry/_chat_client.py @@ -27,7 +27,7 @@ from agent_framework import ( ) from agent_framework._pydantic import AFBaseSettings from agent_framework.exceptions import ServiceInitializationError, ServiceResponseException -from agent_framework.telemetry import prepend_agent_framework_to_user_agent, use_telemetry +from agent_framework.telemetry import AGENT_FRAMEWORK_USER_AGENT, use_telemetry from azure.ai.agents.models import ( AgentsNamedToolChoice, AgentsNamedToolChoiceType, @@ -95,8 +95,6 @@ class FoundrySettings(AFBaseSettings): TFoundryChatClient = TypeVar("TFoundryChatClient", bound="FoundryChatClient") -HEADERS = prepend_agent_framework_to_user_agent() - @use_function_invocation @use_telemetry @@ -174,7 +172,11 @@ class FoundryChatClient(BaseChatClient): # Use provided credential if not async_credential: raise ServiceInitializationError("Azure credential is required when client is not provided.") - client = AIProjectClient(endpoint=foundry_settings.project_endpoint, credential=async_credential) + client = AIProjectClient( + endpoint=foundry_settings.project_endpoint, + credential=async_credential, + user_agent=AGENT_FRAMEWORK_USER_AGENT, + ) should_close_client = True super().__init__( @@ -286,11 +288,7 @@ class FoundryChatClient(BaseChatClient): raise ServiceInitializationError("Model deployment name is required for agent creation.") agent_name = self.agent_name - args = { - "model": self.ai_model_id, - "name": agent_name, - "headers": HEADERS, - } + args = {"model": self.ai_model_id, "name": agent_name} if run_options: if "tools" in run_options: args["tools"] = run_options["tools"] @@ -326,11 +324,7 @@ class FoundryChatClient(BaseChatClient): if thread_run is not None and tool_run_id is not None and tool_run_id == thread_run.id and tool_outputs: # There's an active run and we have tool results to submit, so submit the results. await self.client.agents.runs.submit_tool_outputs_stream( # type: ignore[reportUnknownMemberType] - thread_run.thread_id, - tool_run_id, - tool_outputs=tool_outputs, - event_handler=handler, - headers=HEADERS, + thread_run.thread_id, tool_run_id, tool_outputs=tool_outputs, event_handler=handler ) # Pass the handler to the stream to continue processing stream = handler # type: ignore @@ -342,10 +336,7 @@ class FoundryChatClient(BaseChatClient): # Now create a new run and stream the results. run_options.pop("conversation_id", None) stream = await self.client.agents.runs.stream( # type: ignore[reportUnknownMemberType] - final_thread_id, - agent_id=agent_id, - headers=HEADERS, - **run_options, + final_thread_id, agent_id=agent_id, **run_options ) return stream, final_thread_id @@ -355,9 +346,7 @@ class FoundryChatClient(BaseChatClient): if thread_id is None: return None - async for run in self.client.agents.runs.list( - thread_id=thread_id, limit=1, order=ListSortOrder.DESCENDING, headers=HEADERS - ): # type: ignore[reportUnknownMemberType] + async for run in self.client.agents.runs.list(thread_id=thread_id, limit=1, order=ListSortOrder.DESCENDING): # type: ignore[reportUnknownMemberType] if run.status not in [ RunStatus.COMPLETED, RunStatus.CANCELLED, @@ -374,15 +363,13 @@ class FoundryChatClient(BaseChatClient): if thread_id is not None: if thread_run is not None: # There was an active run; we need to cancel it before starting a new run. - await self.client.agents.runs.cancel(thread_id, thread_run.id, headers=HEADERS) + await self.client.agents.runs.cancel(thread_id, thread_run.id) return thread_id # No thread ID was provided, so create a new thread. thread = await self.client.agents.threads.create( - tool_resources=run_options.get("tool_resources"), - metadata=run_options.get("metadata"), - headers=HEADERS, + tool_resources=run_options.get("tool_resources"), metadata=run_options.get("metadata") ) thread_id = thread.id # workaround for: https://github.com/Azure/azure-sdk-for-python/issues/42805 @@ -391,11 +378,7 @@ class FoundryChatClient(BaseChatClient): # `messages=run_options.pop("additional_messages")` for msg in run_options.pop("additional_messages", []): await self.client.agents.messages.create( - thread_id=thread_id, - role=msg.role, - content=msg.content, - metadata=msg.metadata, - headers=HEADERS, + thread_id=thread_id, role=msg.role, content=msg.content, metadata=msg.metadata ) # and remove until here. return thread_id @@ -519,7 +502,7 @@ class FoundryChatClient(BaseChatClient): async def _cleanup_agent_if_needed(self) -> None: """Clean up the agent if we created it.""" if self._should_delete_agent and self.agent_id is not None: - await self.client.agents.delete_agent(self.agent_id, headers=HEADERS) + await self.client.agents.delete_agent(self.agent_id) self.agent_id = None self._should_delete_agent = False diff --git a/python/packages/foundry/pyproject.toml b/python/packages/foundry/pyproject.toml index f601069a94..a7aa1cf86a 100644 --- a/python/packages/foundry/pyproject.toml +++ b/python/packages/foundry/pyproject.toml @@ -84,10 +84,6 @@ include = "../../shared_tasks.toml" mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_foundry" test = "pytest --cov=agent_framework_foundry --cov-report=term-missing:skip-covered tests" -[tool.uv.build-backend] -module-name = "agent_framework_foundry" -module-root = "" - [build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" +requires = ["flit-core >= 3.9,<4.0"] +build-backend = "flit_core.buildapi" diff --git a/python/packages/foundry/tests/test_foundry_chat_client.py b/python/packages/foundry/tests/test_foundry_chat_client.py index fa69e21b0b..484069be79 100644 --- a/python/packages/foundry/tests/test_foundry_chat_client.py +++ b/python/packages/foundry/tests/test_foundry_chat_client.py @@ -23,7 +23,6 @@ from agent_framework import ( TextContent, UriContent, ) -from agent_framework import __version__ as AF_VERSION from agent_framework.exceptions import ServiceInitializationError from agent_framework.foundry import FoundryChatClient, FoundrySettings from azure.ai.agents.models import ( @@ -315,9 +314,7 @@ async def test_foundry_chat_client_cleanup_agent_if_needed_should_delete( await chat_client._cleanup_agent_if_needed() # type: ignore # Verify agent deletion was called - mock_ai_project_client.agents.delete_agent.assert_called_once_with( - "agent-to-delete", headers={"User-Agent": f"agent-framework-python/{AF_VERSION}"} - ) + mock_ai_project_client.agents.delete_agent.assert_called_once_with("agent-to-delete") assert not chat_client._should_delete_agent # type: ignore @@ -358,9 +355,7 @@ async def test_foundry_chat_client_aclose(mock_ai_project_client: MagicMock) -> await chat_client.close() # Verify agent deletion was called - mock_ai_project_client.agents.delete_agent.assert_called_once_with( - "agent-to-delete", headers={"User-Agent": f"agent-framework-python/{AF_VERSION}"} - ) + mock_ai_project_client.agents.delete_agent.assert_called_once_with("agent-to-delete") async def test_foundry_chat_client_async_context_manager(mock_ai_project_client: MagicMock) -> None: @@ -374,9 +369,7 @@ async def test_foundry_chat_client_async_context_manager(mock_ai_project_client: pass # Just test that we can enter and exit # Verify cleanup was called on exit - mock_ai_project_client.agents.delete_agent.assert_called_once_with( - "agent-to-delete", headers={"User-Agent": f"agent-framework-python/{AF_VERSION}"} - ) + mock_ai_project_client.agents.delete_agent.assert_called_once_with("agent-to-delete") def test_foundry_chat_client_create_run_options_basic(mock_ai_project_client: MagicMock) -> None: @@ -562,9 +555,7 @@ async def test_foundry_chat_client_prepare_thread_cancels_active_run(mock_ai_pro result = await chat_client._prepare_thread("test-thread", mock_thread_run, run_options) # type: ignore assert result == "test-thread" - mock_ai_project_client.agents.runs.cancel.assert_called_once_with( - "test-thread", "run_123", headers={"User-Agent": f"agent-framework-python/{AF_VERSION}"} - ) + mock_ai_project_client.agents.runs.cancel.assert_called_once_with("test-thread", "run_123") def test_foundry_chat_client_create_function_call_contents_basic(mock_ai_project_client: MagicMock) -> None: diff --git a/python/packages/main/README.md b/python/packages/main/README.md index 363b6533a4..61e5b5ca0a 100644 --- a/python/packages/main/README.md +++ b/python/packages/main/README.md @@ -50,10 +50,10 @@ You can also override environment variables by explicitly passing configuration from agent_framework.azure import AzureChatClient chat_client = AzureChatClient( - api_key=..., - endpoint=..., - deployment_name=..., - api_version=..., + api_key="", + endpoint="", + deployment_name="", + api_version="", ) ``` diff --git a/python/packages/main/agent_framework/__init__.py b/python/packages/main/agent_framework/__init__.py index b7963138cc..a0b1088ffb 100644 --- a/python/packages/main/agent_framework/__init__.py +++ b/python/packages/main/agent_framework/__init__.py @@ -17,3 +17,4 @@ from ._middleware import * # noqa: F403 from ._threads import * # noqa: F403 from ._tools import * # noqa: F403 from ._types import * # noqa: F403 +from ._workflow import * # noqa: F403 diff --git a/python/packages/main/agent_framework/_memory.py b/python/packages/main/agent_framework/_memory.py index cdb3f2ff61..fbdfa44216 100644 --- a/python/packages/main/agent_framework/_memory.py +++ b/python/packages/main/agent_framework/_memory.py @@ -17,6 +17,8 @@ else: # region Context +__all__ = ["AggregateContextProvider", "Context", "ContextProvider"] + class Context(AFBaseModel): """A class containing any context that should be provided to the AI model as supplied by an ContextProvider. diff --git a/python/packages/main/agent_framework/_tools.py b/python/packages/main/agent_framework/_tools.py index 6bff5f8cb5..6a3d1eb615 100644 --- a/python/packages/main/agent_framework/_tools.py +++ b/python/packages/main/agent_framework/_tools.py @@ -73,6 +73,9 @@ DEFAULT_MAX_ITERATIONS: Final[int] = 10 TChatClient = TypeVar("TChatClient", bound="ChatClientProtocol") # region Helpers +ArgsT = TypeVar("ArgsT", bound=BaseModel) +ReturnT = TypeVar("ReturnT") + def _parse_inputs( inputs: "Contents | dict[str, Any] | str | list[Contents | dict[str, Any] | str] | None", @@ -121,13 +124,10 @@ def _parse_inputs( class ToolProtocol(Protocol): """Represents a generic tool that can be specified to an AI service. - Attributes: + Parameters: name: The name of the tool. description: A description of the tool. additional_properties: Additional properties associated with the tool. - - Methods: - parameters: The parameters accepted by the tool, in a json schema format. """ name: str @@ -142,10 +142,6 @@ class ToolProtocol(Protocol): ... -ArgsT = TypeVar("ArgsT", bound=BaseModel) -ReturnT = TypeVar("ReturnT") - - class BaseTool(AFBaseModel): """Base class for AI tools, providing common attributes and methods. @@ -516,11 +512,20 @@ def ai_function( In order to add descriptions to parameters, in your function signature, use the `Annotated` type from `typing` and the `Field` class from `pydantic`: - from typing import Annotated + Example: + .. code-block:: python + + from typing import Annotated from pydantic import Field - : Annotated[, Field(description="")] + + def ai_function_example( + arg1: Annotated[str, Field(description="The first argument")], + arg2: Annotated[int, Field(description="The second argument")], + ) -> str: + # An example function that takes two arguments and returns a string. + return f"arg1: {arg1}, arg2: {arg2}" Args: func: The function to wrap. If None, returns a decorator. diff --git a/python/packages/main/agent_framework/_types.py b/python/packages/main/agent_framework/_types.py index 1a7e54efef..d3b3eab044 100644 --- a/python/packages/main/agent_framework/_types.py +++ b/python/packages/main/agent_framework/_types.py @@ -1297,7 +1297,7 @@ FinishReason.TOOL_CALLS = FinishReason(value="tool_calls") # type: ignore[assig class ChatMessage(AFBaseModel): - """Represents a chat message used by a `ModelClient`. + """Represents a chat message. Attributes: role: The role of the author of the message. diff --git a/python/packages/main/agent_framework/_workflow/README.md b/python/packages/main/agent_framework/_workflow/README.md new file mode 100644 index 0000000000..90e9eb8991 --- /dev/null +++ b/python/packages/main/agent_framework/_workflow/README.md @@ -0,0 +1,15 @@ +# Get Started with Microsoft Agent Framework Workflow + +Workflow capabilities now ship with the core `agent-framework` package. + +```bash +pip install agent-framework +``` + +Optional visualization support is still available via the `viz` extra: + +```bash +pip install agent-framework[viz] +``` + +See the [project README](https://github.com/microsoft/agent-framework/tree/main/python/README.md) for more information. diff --git a/python/packages/workflow/agent_framework_workflow/__init__.py b/python/packages/main/agent_framework/_workflow/__init__.py similarity index 84% rename from python/packages/workflow/agent_framework_workflow/__init__.py rename to python/packages/main/agent_framework/_workflow/__init__.py index 61094b9eb6..f8c3955c9d 100644 --- a/python/packages/workflow/agent_framework_workflow/__init__.py +++ b/python/packages/main/agent_framework/_workflow/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) Microsoft. All rights reserved. -import importlib.metadata +import contextlib from ._agent import WorkflowAgent from ._checkpoint import ( @@ -13,7 +13,18 @@ from ._concurrent import ConcurrentBuilder from ._const import ( DEFAULT_MAX_ITERATIONS, ) -from ._edge import Case, Default +from ._edge import ( + Case, + Default, + Edge, + FanInEdgeGroup, + FanOutEdgeGroup, + SingleEdgeGroup, + SwitchCaseEdgeGroup, + SwitchCaseEdgeGroupCase, + SwitchCaseEdgeGroupDefault, +) +from ._edge_runner import create_edge_runner from ._events import ( AgentRunEvent, AgentRunUpdateEvent, @@ -67,15 +78,19 @@ from ._magentic import ( MagenticStartMessage, StandardMagenticManager, ) +from ._runner import Runner from ._runner_context import ( InProcRunnerContext, Message, RunnerContext, ) from ._sequential import SequentialBuilder +from ._shared_state import SharedState +from ._telemetry import EdgeGroupDeliveryStatus, WorkflowTracer, workflow_tracer from ._validation import ( EdgeDuplicationError, GraphConnectivityError, + HandlerOutputAnnotationError, TypeCompatibilityError, ValidationTypeEnum, WorkflowValidationError, @@ -85,12 +100,6 @@ from ._viz import WorkflowViz from ._workflow import Workflow, WorkflowBuilder, WorkflowRunResult from ._workflow_context import WorkflowContext -try: - __version__ = importlib.metadata.version(__name__) -except importlib.metadata.PackageNotFoundError: - __version__ = "0.0.0" # Fallback for development mode - - __all__ = [ "DEFAULT_MAX_ITERATIONS", "AgentExecutor", @@ -102,15 +111,20 @@ __all__ = [ "CheckpointStorage", "ConcurrentBuilder", "Default", + "Edge", "EdgeDuplicationError", + "EdgeGroupDeliveryStatus", "Executor", "ExecutorCompletedEvent", "ExecutorEvent", "ExecutorFailedEvent", "ExecutorInvokeEvent", + "FanInEdgeGroup", + "FanOutEdgeGroup", "FileCheckpointStorage", "FunctionExecutor", "GraphConnectivityError", + "HandlerOutputAnnotationError", "InMemoryCheckpointStorage", "InProcRunnerContext", "MagenticAgentDeltaEvent", @@ -137,11 +151,17 @@ __all__ = [ "RequestInfoExecutor", "RequestInfoMessage", "RequestResponse", + "Runner", "RunnerContext", "SequentialBuilder", + "SharedState", + "SingleEdgeGroup", "StandardMagenticManager", "SubWorkflowRequestInfo", "SubWorkflowResponse", + "SwitchCaseEdgeGroup", + "SwitchCaseEdgeGroupCase", + "SwitchCaseEdgeGroupDefault", "TypeCompatibilityError", "ValidationTypeEnum", "Workflow", @@ -158,19 +178,18 @@ __all__ = [ "WorkflowRunState", "WorkflowStartedEvent", "WorkflowStatusEvent", + "WorkflowTracer", "WorkflowValidationError", "WorkflowViz", - "__version__", + "create_edge_runner", "executor", "handler", "intercepts_request", "validate_workflow_graph", + "workflow_tracer", ] - # Rebuild models to resolve forward references after all imports are complete -import contextlib - with contextlib.suppress(AttributeError, TypeError, ValueError): # Rebuild WorkflowExecutor to resolve Workflow forward reference WorkflowExecutor.model_rebuild() diff --git a/python/packages/main/agent_framework/_workflow/__init__.pyi b/python/packages/main/agent_framework/_workflow/__init__.pyi new file mode 100644 index 0000000000..506cac18e3 --- /dev/null +++ b/python/packages/main/agent_framework/_workflow/__init__.pyi @@ -0,0 +1,186 @@ +# Copyright (c) Microsoft. All rights reserved. + +from ._agent import WorkflowAgent +from ._checkpoint import ( + CheckpointStorage, + FileCheckpointStorage, + InMemoryCheckpointStorage, + WorkflowCheckpoint, +) +from ._concurrent import ConcurrentBuilder +from ._const import DEFAULT_MAX_ITERATIONS +from ._edge import ( + Case, + Default, + Edge, + FanInEdgeGroup, + FanOutEdgeGroup, + SingleEdgeGroup, + SwitchCaseEdgeGroup, + SwitchCaseEdgeGroupCase, + SwitchCaseEdgeGroupDefault, +) +from ._edge_runner import create_edge_runner +from ._events import ( + AgentRunEvent, + AgentRunUpdateEvent, + ExecutorCompletedEvent, + ExecutorEvent, + ExecutorFailedEvent, + ExecutorInvokeEvent, + RequestInfoEvent, + WorkflowCompletedEvent, + WorkflowErrorDetails, + WorkflowEvent, + WorkflowFailedEvent, + WorkflowRunState, + WorkflowStartedEvent, + WorkflowStatusEvent, +) +from ._executor import ( + AgentExecutor, + AgentExecutorRequest, + AgentExecutorResponse, + Executor, + RequestInfoExecutor, + RequestInfoMessage, + RequestResponse, + SubWorkflowRequestInfo, + SubWorkflowResponse, + WorkflowExecutor, + handler, + intercepts_request, +) +from ._function_executor import FunctionExecutor, executor +from ._magentic import ( + MagenticAgentDeltaEvent, + MagenticAgentExecutor, + MagenticAgentMessageEvent, + MagenticBuilder, + MagenticCallbackEvent, + MagenticCallbackMode, + MagenticContext, + MagenticFinalResultEvent, + MagenticManagerBase, + MagenticOrchestratorExecutor, + MagenticOrchestratorMessageEvent, + MagenticPlanReviewDecision, + MagenticPlanReviewReply, + MagenticPlanReviewRequest, + MagenticProgressLedger, + MagenticProgressLedgerItem, + MagenticRequestMessage, + MagenticResponseMessage, + MagenticStartMessage, + StandardMagenticManager, +) +from ._runner import Runner +from ._runner_context import ( + InProcRunnerContext, + Message, + RunnerContext, +) +from ._sequential import SequentialBuilder +from ._shared_state import SharedState +from ._telemetry import EdgeGroupDeliveryStatus, WorkflowTracer, workflow_tracer +from ._validation import ( + EdgeDuplicationError, + GraphConnectivityError, + HandlerOutputAnnotationError, + TypeCompatibilityError, + ValidationTypeEnum, + WorkflowValidationError, + validate_workflow_graph, +) +from ._viz import WorkflowViz +from ._workflow import Workflow, WorkflowBuilder, WorkflowRunResult +from ._workflow_context import WorkflowContext + +__all__ = [ + "DEFAULT_MAX_ITERATIONS", + "AgentExecutor", + "AgentExecutorRequest", + "AgentExecutorResponse", + "AgentRunEvent", + "AgentRunUpdateEvent", + "Case", + "CheckpointStorage", + "ConcurrentBuilder", + "Default", + "Edge", + "EdgeDuplicationError", + "EdgeGroupDeliveryStatus", + "Executor", + "ExecutorCompletedEvent", + "ExecutorEvent", + "ExecutorFailedEvent", + "ExecutorInvokeEvent", + "FanInEdgeGroup", + "FanOutEdgeGroup", + "FileCheckpointStorage", + "FunctionExecutor", + "GraphConnectivityError", + "HandlerOutputAnnotationError", + "InMemoryCheckpointStorage", + "InProcRunnerContext", + "MagenticAgentDeltaEvent", + "MagenticAgentExecutor", + "MagenticAgentMessageEvent", + "MagenticBuilder", + "MagenticCallbackEvent", + "MagenticCallbackMode", + "MagenticContext", + "MagenticFinalResultEvent", + "MagenticManagerBase", + "MagenticOrchestratorExecutor", + "MagenticOrchestratorMessageEvent", + "MagenticPlanReviewDecision", + "MagenticPlanReviewReply", + "MagenticPlanReviewRequest", + "MagenticProgressLedger", + "MagenticProgressLedgerItem", + "MagenticRequestMessage", + "MagenticResponseMessage", + "MagenticStartMessage", + "Message", + "RequestInfoEvent", + "RequestInfoExecutor", + "RequestInfoMessage", + "RequestResponse", + "Runner", + "RunnerContext", + "SequentialBuilder", + "SharedState", + "SingleEdgeGroup", + "StandardMagenticManager", + "SubWorkflowRequestInfo", + "SubWorkflowResponse", + "SwitchCaseEdgeGroup", + "SwitchCaseEdgeGroupCase", + "SwitchCaseEdgeGroupDefault", + "TypeCompatibilityError", + "ValidationTypeEnum", + "Workflow", + "WorkflowAgent", + "WorkflowBuilder", + "WorkflowCheckpoint", + "WorkflowCompletedEvent", + "WorkflowContext", + "WorkflowErrorDetails", + "WorkflowEvent", + "WorkflowExecutor", + "WorkflowFailedEvent", + "WorkflowRunResult", + "WorkflowRunState", + "WorkflowStartedEvent", + "WorkflowStatusEvent", + "WorkflowTracer", + "WorkflowValidationError", + "WorkflowViz", + "create_edge_runner", + "executor", + "handler", + "intercepts_request", + "validate_workflow_graph", + "workflow_tracer", +] diff --git a/python/packages/workflow/agent_framework_workflow/_agent.py b/python/packages/main/agent_framework/_workflow/_agent.py similarity index 93% rename from python/packages/workflow/agent_framework_workflow/_agent.py rename to python/packages/main/agent_framework/_workflow/_agent.py index 94e1d6555e..29d4251bc2 100644 --- a/python/packages/workflow/agent_framework_workflow/_agent.py +++ b/python/packages/main/agent_framework/_workflow/_agent.py @@ -6,6 +6,8 @@ from collections.abc import AsyncIterable, Sequence from datetime import datetime from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast +from pydantic import Field + from agent_framework import ( AgentRunResponse, AgentRunResponseUpdate, @@ -20,7 +22,6 @@ from agent_framework import ( ) from agent_framework._pydantic import AFBaseModel from agent_framework.exceptions import AgentExecutionException -from pydantic import Field from ._events import ( AgentRunUpdateEvent, @@ -73,9 +74,10 @@ class WorkflowAgent(BaseAgent): kwargs["workflow"] = workflow # Validate the workflow's start executor can handle agent-facing message inputs - start_executor = workflow.get_start_executor() - if start_executor is None: - raise ValueError("Workflow's start executor is not defined.") + try: + start_executor = workflow.get_start_executor() + except KeyError as exc: # Defensive: workflow lacks a configured entry point + raise ValueError("Workflow's start executor is not defined.") from exc if not start_executor.can_handle_type(list[ChatMessage]): raise ValueError("Workflow's start executor cannot handle list[ChatMessage]") @@ -256,6 +258,9 @@ class WorkflowAgent(BaseAgent): message_id=str(uuid.uuid4()), created_at=datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ"), ) + case _: + # Ignore non-agent workflow events + pass # We only care about the above two events and discard the rest. return None @@ -349,16 +354,17 @@ class WorkflowAgent(BaseAgent): if current is None: return incoming raw_list: list[object] = [] + + def _add_raw(value: object) -> None: + if isinstance(value, list): + raw_list.extend(cast(list[object], value)) + else: + raw_list.append(value) + if current.raw_representation is not None: - if isinstance(current.raw_representation, list): - raw_list.extend(current.raw_representation) - else: - raw_list.append(current.raw_representation) + _add_raw(current.raw_representation) if incoming.raw_representation is not None: - if isinstance(incoming.raw_representation, list): - raw_list.extend(incoming.raw_representation) - else: - raw_list.append(incoming.raw_representation) + _add_raw(incoming.raw_representation) return AgentRunResponse( messages=(current.messages or []) + (incoming.messages or []), response_id=current.response_id or incoming.response_id, @@ -407,11 +413,13 @@ class WorkflowAgent(BaseAgent): if merged_additional_properties is None: merged_additional_properties = {} merged_additional_properties.update(aggregated.additional_properties) - if aggregated.raw_representation: - if isinstance(aggregated.raw_representation, list): - raw_representations.extend(aggregated.raw_representation) + raw_value = aggregated.raw_representation + if raw_value: + cast_value = cast(object | list[object], raw_value) + if isinstance(cast_value, list): + raw_representations.extend(cast(list[object], cast_value)) else: - raw_representations.append(aggregated.raw_representation) + raw_representations.append(cast_value) # PHASE 3: HANDLE GLOBAL DANGLING UPDATES (NO RESPONSE_ID) if global_dangling: @@ -427,11 +435,13 @@ class WorkflowAgent(BaseAgent): if merged_additional_properties is None: merged_additional_properties = {} merged_additional_properties.update(flattened.additional_properties) - if flattened.raw_representation: - if isinstance(flattened.raw_representation, list): - raw_representations.extend(flattened.raw_representation) + flat_raw = flattened.raw_representation + if flat_raw: + cast_flat = cast(object | list[object], flat_raw) + if isinstance(cast_flat, list): + raw_representations.extend(cast(list[object], cast_flat)) else: - raw_representations.append(flattened.raw_representation) + raw_representations.append(cast_flat) # PHASE 4: CONSTRUCT FINAL RESPONSE WITH INPUT RESPONSE_ID return AgentRunResponse( diff --git a/python/packages/workflow/agent_framework_workflow/_checkpoint.py b/python/packages/main/agent_framework/_workflow/_checkpoint.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_checkpoint.py rename to python/packages/main/agent_framework/_workflow/_checkpoint.py diff --git a/python/packages/workflow/agent_framework_workflow/_concurrent.py b/python/packages/main/agent_framework/_workflow/_concurrent.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_concurrent.py rename to python/packages/main/agent_framework/_workflow/_concurrent.py index 14feb6bc8e..670a555f50 100644 --- a/python/packages/workflow/agent_framework_workflow/_concurrent.py +++ b/python/packages/main/agent_framework/_workflow/_concurrent.py @@ -177,7 +177,7 @@ class ConcurrentBuilder: Usage: ```python - from agent_framework.workflow import ConcurrentBuilder + from agent_framework import ConcurrentBuilder # Minimal: use default aggregator (returns list[ChatMessage]) workflow = ConcurrentBuilder().participants([agent1, agent2, agent3]).build() diff --git a/python/packages/workflow/agent_framework_workflow/_const.py b/python/packages/main/agent_framework/_workflow/_const.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_const.py rename to python/packages/main/agent_framework/_workflow/_const.py diff --git a/python/packages/workflow/agent_framework_workflow/_edge.py b/python/packages/main/agent_framework/_workflow/_edge.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_edge.py rename to python/packages/main/agent_framework/_workflow/_edge.py index 76a0cb9a3a..7e175a5054 100644 --- a/python/packages/workflow/agent_framework_workflow/_edge.py +++ b/python/packages/main/agent_framework/_workflow/_edge.py @@ -6,10 +6,11 @@ from collections.abc import Callable, Sequence from dataclasses import dataclass from typing import Any, ClassVar -from agent_framework._pydantic import AFBaseModel from pydantic import Field -from agent_framework_workflow._executor import Executor +from agent_framework._pydantic import AFBaseModel + +from ._executor import Executor logger = logging.getLogger(__name__) diff --git a/python/packages/workflow/agent_framework_workflow/_edge_runner.py b/python/packages/main/agent_framework/_workflow/_edge_runner.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_edge_runner.py rename to python/packages/main/agent_framework/_workflow/_edge_runner.py diff --git a/python/packages/workflow/agent_framework_workflow/_events.py b/python/packages/main/agent_framework/_workflow/_events.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_events.py rename to python/packages/main/agent_framework/_workflow/_events.py diff --git a/python/packages/workflow/agent_framework_workflow/_executor.py b/python/packages/main/agent_framework/_workflow/_executor.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_executor.py rename to python/packages/main/agent_framework/_workflow/_executor.py index b4005cd152..83763bc02a 100644 --- a/python/packages/workflow/agent_framework_workflow/_executor.py +++ b/python/packages/main/agent_framework/_workflow/_executor.py @@ -12,9 +12,10 @@ from typing import TYPE_CHECKING, Any, Generic, TypeVar, Union, get_args, get_or if TYPE_CHECKING: from ._workflow import Workflow +from pydantic import Field + from agent_framework import AgentProtocol, AgentRunResponse, AgentRunResponseUpdate, AgentThread, ChatMessage from agent_framework._pydantic import AFBaseModel -from pydantic import Field from ._events import ( AgentRunEvent, diff --git a/python/packages/workflow/agent_framework_workflow/_function_executor.py b/python/packages/main/agent_framework/_workflow/_function_executor.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_function_executor.py rename to python/packages/main/agent_framework/_workflow/_function_executor.py diff --git a/python/packages/workflow/agent_framework_workflow/_magentic.py b/python/packages/main/agent_framework/_workflow/_magentic.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_magentic.py rename to python/packages/main/agent_framework/_workflow/_magentic.py index 7e3e75949f..204565c320 100644 --- a/python/packages/workflow/agent_framework_workflow/_magentic.py +++ b/python/packages/main/agent_framework/_workflow/_magentic.py @@ -13,6 +13,8 @@ from enum import Enum from typing import Annotated, Any, Literal, Protocol, TypeVar, Union, cast from uuid import uuid4 +from pydantic import BaseModel, ConfigDict, Field + from agent_framework import ( AgentProtocol, AgentRunResponse, @@ -25,7 +27,6 @@ from agent_framework import ( ) from agent_framework._agents import BaseAgent from agent_framework._pydantic import AFBaseModel -from pydantic import BaseModel, ConfigDict, Field from ._events import WorkflowCompletedEvent, WorkflowEvent from ._executor import Executor, RequestInfoMessage, RequestResponse, handler diff --git a/python/packages/workflow/agent_framework_workflow/_runner.py b/python/packages/main/agent_framework/_workflow/_runner.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_runner.py rename to python/packages/main/agent_framework/_workflow/_runner.py diff --git a/python/packages/workflow/agent_framework_workflow/_runner_context.py b/python/packages/main/agent_framework/_workflow/_runner_context.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_runner_context.py rename to python/packages/main/agent_framework/_workflow/_runner_context.py diff --git a/python/packages/workflow/agent_framework_workflow/_sequential.py b/python/packages/main/agent_framework/_workflow/_sequential.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_sequential.py rename to python/packages/main/agent_framework/_workflow/_sequential.py index 4271d3f7d7..cc091601c4 100644 --- a/python/packages/workflow/agent_framework_workflow/_sequential.py +++ b/python/packages/main/agent_framework/_workflow/_sequential.py @@ -103,7 +103,7 @@ class SequentialBuilder: Usage: ```python - from agent_framework.workflow import SequentialBuilder + from agent_framework import SequentialBuilder workflow = SequentialBuilder().participants([agent1, agent2, summarizer_exec]).build() ``` diff --git a/python/packages/workflow/agent_framework_workflow/_shared_state.py b/python/packages/main/agent_framework/_workflow/_shared_state.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_shared_state.py rename to python/packages/main/agent_framework/_workflow/_shared_state.py diff --git a/python/packages/workflow/agent_framework_workflow/_telemetry.py b/python/packages/main/agent_framework/_workflow/_telemetry.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_telemetry.py rename to python/packages/main/agent_framework/_workflow/_telemetry.py index 682a90b040..dc1a483e93 100644 --- a/python/packages/workflow/agent_framework_workflow/_telemetry.py +++ b/python/packages/main/agent_framework/_workflow/_telemetry.py @@ -3,11 +3,12 @@ from enum import Enum from typing import TYPE_CHECKING, Any, ClassVar -from agent_framework._pydantic import AFBaseSettings from opentelemetry.trace import Link, NoOpTracer, SpanKind, StatusCode, get_current_span, get_tracer from opentelemetry.trace.span import SpanContext from opentelemetry.util.types import Attributes +from agent_framework._pydantic import AFBaseSettings + if TYPE_CHECKING: from ._workflow import Workflow diff --git a/python/packages/workflow/agent_framework_workflow/_typing_utils.py b/python/packages/main/agent_framework/_workflow/_typing_utils.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_typing_utils.py rename to python/packages/main/agent_framework/_workflow/_typing_utils.py diff --git a/python/packages/workflow/agent_framework_workflow/_validation.py b/python/packages/main/agent_framework/_workflow/_validation.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_validation.py rename to python/packages/main/agent_framework/_workflow/_validation.py diff --git a/python/packages/workflow/agent_framework_workflow/_viz.py b/python/packages/main/agent_framework/_workflow/_viz.py similarity index 99% rename from python/packages/workflow/agent_framework_workflow/_viz.py rename to python/packages/main/agent_framework/_workflow/_viz.py index 916d980993..34ecd7e2be 100644 --- a/python/packages/workflow/agent_framework_workflow/_viz.py +++ b/python/packages/main/agent_framework/_workflow/_viz.py @@ -80,7 +80,7 @@ class WorkflowViz: import graphviz # type: ignore except ImportError as e: raise ImportError( - "viz extra is required for export. Install it with: pip install agent-framework-workflow[viz]. " + "viz extra is required for export. Install it with: pip install agent-framework[viz]. " "You also need to install graphviz separately. E.g., sudo apt-get install graphviz on Debian/Ubuntu " "or brew install graphviz on macOS. See https://graphviz.org/download/ for details." ) from e diff --git a/python/packages/workflow/agent_framework_workflow/_workflow.py b/python/packages/main/agent_framework/_workflow/_workflow.py similarity index 97% rename from python/packages/workflow/agent_framework_workflow/_workflow.py rename to python/packages/main/agent_framework/_workflow/_workflow.py index 25aad51e14..d4915fb8bd 100644 --- a/python/packages/workflow/agent_framework_workflow/_workflow.py +++ b/python/packages/main/agent_framework/_workflow/_workflow.py @@ -5,11 +5,12 @@ import logging import sys import uuid from collections.abc import AsyncIterable, Awaitable, Callable, Sequence -from typing import Any +from typing import Any, cast + +from pydantic import Field from agent_framework import AgentProtocol from agent_framework._pydantic import AFBaseModel -from pydantic import Field from ._agent import WorkflowAgent from ._checkpoint import CheckpointStorage @@ -51,6 +52,14 @@ else: logger = logging.getLogger(__name__) +def _default_edge_groups() -> list[EdgeGroup]: + return [] + + +def _default_executors() -> dict[str, Executor]: + return {} + + class WorkflowRunResult(list[WorkflowEvent]): """A list of events generated during the workflow execution in non-streaming mode. @@ -116,10 +125,10 @@ class Workflow(AFBaseModel): """ edge_groups: list[EdgeGroup] = Field( - default_factory=list, description="List of edge groups that define the workflow edges" + default_factory=_default_edge_groups, description="List of edge groups that define the workflow edges" ) executors: dict[str, Executor] = Field( - default_factory=dict, description="Dictionary mapping executor IDs to Executor instances" + default_factory=_default_executors, description="Dictionary mapping executor IDs to Executor instances" ) start_executor_id: str = Field(min_length=1, description="The ID of the starting executor for the workflow") max_iterations: int = Field( @@ -181,21 +190,20 @@ class Workflow(AFBaseModel): # Ensure WorkflowExecutor instances have their workflow field serialized if "executors" in data: - executors_data = data["executors"] + executors_data = cast(dict[str, Any], data["executors"]) + executor_map: dict[str, Executor] = self.executors for executor_id, executor_data in executors_data.items(): # Check if this is a WorkflowExecutor that might be missing its workflow field - if ( - isinstance(executor_data, dict) - and executor_data.get("type") == "WorkflowExecutor" - and "workflow" not in executor_data - ): - # Get the original executor object and serialize its workflow - original_executor = self.executors.get(executor_id) - if original_executor and hasattr(original_executor, "workflow"): - from ._executor import WorkflowExecutor + if isinstance(executor_data, dict): + executor_dict = cast(dict[str, Any], executor_data) + if executor_dict.get("type") == "WorkflowExecutor" and "workflow" not in executor_dict: + # Get the original executor object and serialize its workflow + original_executor = executor_map.get(executor_id) + if original_executor is not None and hasattr(original_executor, "workflow"): + from ._executor import WorkflowExecutor - if isinstance(original_executor, WorkflowExecutor): - executor_data["workflow"] = original_executor.workflow.model_dump(**kwargs) + if isinstance(original_executor, WorkflowExecutor): + executor_dict["workflow"] = original_executor.workflow.model_dump(**kwargs) return data diff --git a/python/packages/workflow/agent_framework_workflow/_workflow_context.py b/python/packages/main/agent_framework/_workflow/_workflow_context.py similarity index 100% rename from python/packages/workflow/agent_framework_workflow/_workflow_context.py rename to python/packages/main/agent_framework/_workflow/_workflow_context.py diff --git a/python/packages/main/agent_framework/telemetry.py b/python/packages/main/agent_framework/telemetry.py index 0c276ed2c7..5382d413db 100644 --- a/python/packages/main/agent_framework/telemetry.py +++ b/python/packages/main/agent_framework/telemetry.py @@ -22,6 +22,7 @@ from ._pydantic import AFBaseSettings from .exceptions import AgentInitializationError, ChatClientInitializationError if TYPE_CHECKING: # pragma: no cover + from azure.core.credentials import TokenCredential from opentelemetry.metrics import Histogram from opentelemetry.sdk.resources import Resource from opentelemetry.util._decorator import _AgnosticContextManager # type: ignore[reportPrivateUsage] @@ -413,10 +414,13 @@ class OtelSettings(AFBaseSettings): """Check if the setup has been executed.""" return self._executed_setup - def setup_telemetry(self) -> None: + def setup_telemetry(self, credential: "TokenCredential | None" = None) -> None: """Setup telemetry based on the settings. If both connection_string and otlp_endpoint both will be used. + + Args: + credential: The credential to use for Azure Monitor Entra ID authentication. Default is None. """ if not self.ENABLED or self._executed_setup: return @@ -438,6 +442,7 @@ class OtelSettings(AFBaseSettings): configure_azure_monitor( connection_string=self.application_insights_connection_string, + credential=credential, logger_name="agent_framework", resource=resource, enable_live_metrics=self.application_insights_live_metrics, @@ -458,6 +463,7 @@ def setup_telemetry( enable_sensitive_data: bool | None = None, otlp_endpoint: str | None = None, application_insights_connection_string: str | None = None, + credential: "TokenCredential | None" = None, enable_live_metrics: bool | None = None, ) -> None: """Setup telemetry with optionally provided settings. @@ -472,6 +478,8 @@ def setup_telemetry( enable_sensitive_data: Enable OpenTelemetry sensitive events. Default is False. otlp_endpoint: The OpenTelemetry Protocol (OTLP) endpoint. Default is None. application_insights_connection_string: The Azure Monitor connection string. Default is None. + credential: The credential to use for Azure Monitor Entra ID authentication. + Default is None. enable_live_metrics: Enable Azure Monitor live metrics. Default is False. """ @@ -486,7 +494,7 @@ def setup_telemetry( OTEL_SETTINGS.application_insights_connection_string = application_insights_connection_string if enable_live_metrics is not None: OTEL_SETTINGS.application_insights_live_metrics = enable_live_metrics - OTEL_SETTINGS.setup_telemetry() + OTEL_SETTINGS.setup_telemetry(credential=credential) # region Chat Client Telemetry diff --git a/python/packages/main/agent_framework/workflow/__init__.py b/python/packages/main/agent_framework/workflow/__init__.py deleted file mode 100644 index 70f9bf49ea..0000000000 --- a/python/packages/main/agent_framework/workflow/__init__.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -import importlib -from typing import Any - -PACKAGE_NAME = "agent_framework_workflow" -PACKAGE_EXTRA = "workflow" -_IMPORTS = [ - "Executor", - "FunctionExecutor", - "executor", - "WorkflowContext", - "__version__", - "events", - "WorkflowBuilder", - "ExecutorCompletedEvent", - "ExecutorEvent", - "ExecutorInvokeEvent", - "RequestInfoEvent", - "WorkflowCompletedEvent", - "WorkflowEvent", - "WorkflowStartedEvent", - "AgentRunEvent", - "AgentRunUpdateEvent", - "handler", - "AgentExecutor", - "MagenticAgentDeltaEvent", - "MagenticCallbackEvent", - "MagenticCallbackMode", - "MagenticAgentMessageEvent", - "MagenticFinalResultEvent", - "MagenticManagerBase", - "MagenticOrchestratorMessageEvent", - "AgentExecutorRequest", - "AgentExecutorResponse", - "RequestInfoExecutor", - "RequestInfoMessage", - "WorkflowRunResult", - "Workflow", - "WorkflowAgent", - "WorkflowViz", - "FileCheckpointStorage", - "ExecutorFailedEvent", - "InMemoryCheckpointStorage", - "CheckpointStorage", - "WorkflowCheckpoint", - "Case", - "Default", - "RequestResponse", - "SubWorkflowRequestInfo", - "SubWorkflowResponse", - "WorkflowExecutor", - "intercepts_request", - "MagenticBuilder", - "PlanReviewDecision", - "PlanReviewReply", - "PlanReviewRequest", - "RequestInfoEvent", - "StandardMagenticManager", - "WorkflowStatusEvent", - "WorkflowRunState", - "WorkflowErrorDetails", - "WorkflowFailedEvent", - "ConcurrentBuilder", - "SequentialBuilder", -] - - -def __getattr__(name: str) -> Any: - if name in _IMPORTS: - try: - return getattr(importlib.import_module(PACKAGE_NAME), name) - except ModuleNotFoundError as exc: - raise ModuleNotFoundError( - f"The '{PACKAGE_EXTRA}' extra is not installed, " - f"please do `pip install agent-framework[{PACKAGE_EXTRA}]`" - ) from exc - raise AttributeError(f"Module {PACKAGE_NAME} has no attribute {name}.") - - -def __dir__() -> list[str]: - return _IMPORTS diff --git a/python/packages/main/agent_framework/workflow/__init__.pyi b/python/packages/main/agent_framework/workflow/__init__.pyi deleted file mode 100644 index b50c2007a2..0000000000 --- a/python/packages/main/agent_framework/workflow/__init__.pyi +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. - -from agent_framework_workflow import ( - AgentExecutor, - AgentExecutorRequest, - AgentExecutorResponse, - AgentRunEvent, - AgentRunUpdateEvent, - Case, - CheckpointStorage, - ConcurrentBuilder, - Default, - Executor, - ExecutorCompletedEvent, - ExecutorEvent, - ExecutorFailedEvent, - ExecutorInvokeEvent, - FileCheckpointStorage, - FunctionExecutor, - InMemoryCheckpointStorage, - MagenticBuilder, - MagenticCallbackEvent, - MagenticCallbackMode, - MagenticPlanReviewDecision, - MagenticPlanReviewReply, - MagenticPlanReviewRequest, - MagenticProgressLedger, - MagenticProgressLedgerItem, - RequestInfoEvent, - RequestInfoExecutor, - RequestInfoMessage, - RequestResponse, - SequentialBuilder, - StandardMagenticManager, - SubWorkflowRequestInfo, - SubWorkflowResponse, - Workflow, - WorkflowAgent, - WorkflowBuilder, - WorkflowCheckpoint, - WorkflowCompletedEvent, - WorkflowContext, - WorkflowErrorDetails, - WorkflowEvent, - WorkflowExecutor, - WorkflowFailedEvent, - WorkflowRunResult, - WorkflowRunState, - WorkflowStartedEvent, - WorkflowStatusEvent, - WorkflowViz, - __version__, - executor, - handler, - intercepts_request, -) - -__all__ = [ - "AgentExecutor", - "AgentExecutorRequest", - "AgentExecutorResponse", - "AgentRunEvent", - "AgentRunUpdateEvent", - "Case", - "CheckpointStorage", - "ConcurrentBuilder", - "Default", - "Executor", - "ExecutorCompletedEvent", - "ExecutorEvent", - "ExecutorFailedEvent", - "ExecutorInvokeEvent", - "FileCheckpointStorage", - "FunctionExecutor", - "InMemoryCheckpointStorage", - "MagenticBuilder", - "MagenticCallbackEvent", - "MagenticCallbackMode", - "MagenticPlanReviewDecision", - "MagenticPlanReviewReply", - "MagenticPlanReviewRequest", - "MagenticProgressLedger", - "MagenticProgressLedgerItem", - "RequestInfoEvent", - "RequestInfoExecutor", - "RequestInfoMessage", - "RequestResponse", - "SequentialBuilder", - "StandardMagenticManager", - "SubWorkflowRequestInfo", - "SubWorkflowResponse", - "Workflow", - "WorkflowAgent", - "WorkflowBuilder", - "WorkflowCheckpoint", - "WorkflowCompletedEvent", - "WorkflowContext", - "WorkflowErrorDetails", - "WorkflowEvent", - "WorkflowExecutor", - "WorkflowFailedEvent", - "WorkflowRunResult", - "WorkflowRunState", - "WorkflowStartedEvent", - "WorkflowStatusEvent", - "WorkflowViz", - "__version__", - "executor", - "handler", - "intercepts_request", -] diff --git a/python/packages/main/pyproject.toml b/python/packages/main/pyproject.toml index b5e1bfd6c8..24eec9eee5 100644 --- a/python/packages/main/pyproject.toml +++ b/python/packages/main/pyproject.toml @@ -33,7 +33,8 @@ dependencies = [ "azure-monitor-opentelemetry>=1.7.0", "azure-monitor-opentelemetry-exporter>=1.0.0b41", "opentelemetry-exporter-otlp-proto-grpc>=1.36.0", - "opentelemetry-semantic-conventions-ai>=0.4.13" + "opentelemetry-semantic-conventions-ai>=0.4.13", + "aiofiles>=24.1.0" ] [project.optional-dependencies] @@ -43,12 +44,21 @@ azure = [ foundry = [ "agent-framework-foundry" ] -workflow = [ - "agent-framework-workflow" +viz = [ + "graphviz>=0.20.0", ] runtime = [ "agent-framework-runtime" ] +mem0 = [ + "agent-framework-mem0" +] +all = [ + "agent-framework-azure", + "agent-framework-foundry", + "agent-framework-runtime", + "agent-framework-mem0" +] [tool.uv] prerelease = "if-necessary-or-explicit" @@ -106,10 +116,6 @@ include = "../../shared_tasks.toml" mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework" test = "pytest --cov=agent_framework --cov-report=term-missing:skip-covered tests" -[tool.uv.build-backend] -module-name = "agent_framework" -module-root = "" - [build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" +requires = ["flit-core >= 3.9,<4.0"] +build-backend = "flit_core.buildapi" diff --git a/python/packages/workflow/tests/test_checkpoint.py b/python/packages/main/tests/workflow/test_checkpoint.py similarity index 99% rename from python/packages/workflow/tests/test_checkpoint.py rename to python/packages/main/tests/workflow/test_checkpoint.py index 4ae5304672..0515a7ca35 100644 --- a/python/packages/workflow/tests/test_checkpoint.py +++ b/python/packages/main/tests/workflow/test_checkpoint.py @@ -5,7 +5,7 @@ import tempfile from datetime import datetime, timezone from pathlib import Path -from agent_framework_workflow._checkpoint import ( +from agent_framework import ( FileCheckpointStorage, InMemoryCheckpointStorage, WorkflowCheckpoint, diff --git a/python/packages/workflow/tests/test_concurrent.py b/python/packages/main/tests/workflow/test_concurrent.py similarity index 97% rename from python/packages/workflow/tests/test_concurrent.py rename to python/packages/main/tests/workflow/test_concurrent.py index 25becca7cd..1974b0b2e9 100644 --- a/python/packages/workflow/tests/test_concurrent.py +++ b/python/packages/main/tests/workflow/test_concurrent.py @@ -3,13 +3,15 @@ from typing import Any, cast import pytest -from agent_framework import AgentRunResponse, ChatMessage, Role -from agent_framework_workflow import ( +from agent_framework import ( AgentExecutorRequest, AgentExecutorResponse, + AgentRunResponse, + ChatMessage, ConcurrentBuilder, Executor, + Role, WorkflowCompletedEvent, WorkflowContext, handler, diff --git a/python/packages/workflow/tests/test_edge.py b/python/packages/main/tests/workflow/test_edge.py similarity index 98% rename from python/packages/workflow/tests/test_edge.py rename to python/packages/main/tests/workflow/test_edge.py index 98ecee5138..8c6692a56f 100644 --- a/python/packages/workflow/tests/test_edge.py +++ b/python/packages/main/tests/workflow/test_edge.py @@ -5,12 +5,19 @@ from typing import Any from unittest.mock import patch import pytest -from agent_framework.workflow import Executor, WorkflowContext, handler from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter -from agent_framework_workflow._edge import ( +from agent_framework import ( + Executor, + InProcRunnerContext, + Message, + SharedState, + WorkflowContext, + handler, +) +from agent_framework._workflow._edge import ( Edge, FanInEdgeGroup, FanOutEdgeGroup, @@ -19,10 +26,8 @@ from agent_framework_workflow._edge import ( SwitchCaseEdgeGroupCase, SwitchCaseEdgeGroupDefault, ) -from agent_framework_workflow._edge_runner import create_edge_runner -from agent_framework_workflow._runner_context import InProcRunnerContext, Message -from agent_framework_workflow._shared_state import SharedState -from agent_framework_workflow._telemetry import EdgeGroupDeliveryStatus, workflow_tracer +from agent_framework._workflow._edge_runner import create_edge_runner +from agent_framework._workflow._telemetry import EdgeGroupDeliveryStatus, workflow_tracer @pytest.fixture @@ -34,7 +39,7 @@ def tracing_enabled(): os.environ["AGENT_FRAMEWORK_WORKFLOW_ENABLE_OTEL_DIAGNOSTICS"] = "true" # Force reload the settings to pick up the environment variable - from agent_framework_workflow._telemetry import WorkflowDiagnosticSettings + from agent_framework._workflow._telemetry import WorkflowDiagnosticSettings workflow_tracer.settings = WorkflowDiagnosticSettings() @@ -635,7 +640,7 @@ async def test_source_edge_group_with_selection_func_send_message() -> None: data = MockMessage(data="test") message = Message(data=data, source_id=source.id) - with patch("agent_framework_workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: + with patch("agent_framework._workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: success = await edge_runner.send_message(message, shared_state, ctx) assert success is True @@ -688,7 +693,7 @@ async def test_source_edge_group_with_selection_func_send_message_with_target() data = MockMessage(data="test") message = Message(data=data, source_id=source.id, target_id=target1.id) - with patch("agent_framework_workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: + with patch("agent_framework._workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: success = await edge_runner.send_message(message, shared_state, ctx) assert success is True @@ -921,7 +926,7 @@ async def test_target_edge_group_send_message_buffer() -> None: data = MockMessage(data="test") - with patch("agent_framework_workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: + with patch("agent_framework._workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: success = await edge_runner.send_message( Message(data=data, source_id=source1.id), shared_state, @@ -1203,7 +1208,7 @@ async def test_switch_case_edge_group_send_message() -> None: data = MockMessage(data=-1) message = Message(data=data, source_id=source.id) - with patch("agent_framework_workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: + with patch("agent_framework._workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: success = await edge_runner.send_message(message, shared_state, ctx) assert success is True @@ -1212,7 +1217,7 @@ async def test_switch_case_edge_group_send_message() -> None: # Default condition should data = MockMessage(data=1) message = Message(data=data, source_id=source.id) - with patch("agent_framework_workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: + with patch("agent_framework._workflow._edge_runner.EdgeRunner._execute_on_target") as mock_send: success = await edge_runner.send_message(message, shared_state, ctx) assert success is True diff --git a/python/packages/workflow/tests/test_executor.py b/python/packages/main/tests/workflow/test_executor.py similarity index 98% rename from python/packages/workflow/tests/test_executor.py rename to python/packages/main/tests/workflow/test_executor.py index 21da2d9db7..c448212357 100644 --- a/python/packages/workflow/tests/test_executor.py +++ b/python/packages/main/tests/workflow/test_executor.py @@ -1,7 +1,8 @@ # Copyright (c) Microsoft. All rights reserved. import pytest -from agent_framework.workflow import Executor, WorkflowContext, handler + +from agent_framework import Executor, WorkflowContext, handler def test_executor_without_handlers(): diff --git a/python/packages/workflow/tests/test_full_conversation.py b/python/packages/main/tests/workflow/test_full_conversation.py similarity index 98% rename from python/packages/workflow/tests/test_full_conversation.py rename to python/packages/main/tests/workflow/test_full_conversation.py index f1bad2a477..a56d05a7b1 100644 --- a/python/packages/workflow/tests/test_full_conversation.py +++ b/python/packages/main/tests/workflow/test_full_conversation.py @@ -3,26 +3,24 @@ from collections.abc import AsyncIterable from typing import Any +from pydantic import PrivateAttr + from agent_framework import ( + AgentExecutor, AgentRunResponse, AgentRunResponseUpdate, AgentThread, BaseAgent, ChatMessage, Role, - TextContent, -) -from pydantic import PrivateAttr - -from agent_framework_workflow import ( - AgentExecutor, SequentialBuilder, + TextContent, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, handler, ) -from agent_framework_workflow._executor import AgentExecutorResponse, Executor +from agent_framework._workflow._executor import AgentExecutorResponse, Executor class _SimpleAgent(BaseAgent): diff --git a/python/packages/workflow/tests/test_function_executor.py b/python/packages/main/tests/workflow/test_function_executor.py similarity index 99% rename from python/packages/workflow/tests/test_function_executor.py rename to python/packages/main/tests/workflow/test_function_executor.py index ebe6ebd7b5..1ca16e9c66 100644 --- a/python/packages/workflow/tests/test_function_executor.py +++ b/python/packages/main/tests/workflow/test_function_executor.py @@ -3,7 +3,8 @@ from typing import Any import pytest -from agent_framework.workflow import ( + +from agent_framework import ( FunctionExecutor, WorkflowBuilder, WorkflowCompletedEvent, diff --git a/python/packages/workflow/tests/test_magentic.py b/python/packages/main/tests/workflow/test_magentic.py similarity index 98% rename from python/packages/workflow/tests/test_magentic.py rename to python/packages/main/tests/workflow/test_magentic.py index 5b4a96edf0..13e170cdc3 100644 --- a/python/packages/workflow/tests/test_magentic.py +++ b/python/packages/main/tests/workflow/test_magentic.py @@ -5,19 +5,13 @@ from dataclasses import dataclass from typing import Any import pytest + from agent_framework import ( AgentRunResponse, AgentRunResponseUpdate, ChatMessage, ChatResponse, ChatResponseUpdate, - Role, - TextContent, -) -from agent_framework._agents import BaseAgent -from agent_framework._clients import ChatClientProtocol as AFChatClient - -from agent_framework_workflow import ( Executor, MagenticBuilder, MagenticManagerBase, @@ -27,12 +21,16 @@ from agent_framework_workflow import ( MagenticProgressLedger, MagenticProgressLedgerItem, RequestInfoEvent, + Role, + TextContent, WorkflowCompletedEvent, WorkflowContext, WorkflowEvent, # type: ignore # noqa: E402 handler, ) -from agent_framework_workflow._magentic import ( +from agent_framework._agents import BaseAgent +from agent_framework._clients import ChatClientProtocol as AFChatClient +from agent_framework._workflow._magentic import ( MagenticContext, MagenticStartMessage, ) @@ -239,7 +237,7 @@ async def test_magentic_orchestrator_round_limit_produces_partial_result(): manager.satisfied_after_signoff = False wf = MagenticBuilder().participants(agentA=_DummyExec("agentA")).with_standard_manager(manager).build() - from agent_framework_workflow import WorkflowEvent # type: ignore + from agent_framework import WorkflowEvent # type: ignore events: list[WorkflowEvent] = [] async for ev in wf.run_stream("round limit test"): @@ -263,7 +261,7 @@ class _DummyExec(Executor): pass -from agent_framework_workflow import StandardMagenticManager # noqa: E402 +from agent_framework import StandardMagenticManager # noqa: E402 class _StubChatClient(AFChatClient): @@ -415,7 +413,7 @@ async def _collect_agent_responses_setup(participant_obj: object): captured: list[ChatMessage] = [] async def sink(event) -> None: # type: ignore[no-untyped-def] - from agent_framework_workflow._magentic import MagenticAgentMessageEvent + from agent_framework._workflow._magentic import MagenticAgentMessageEvent if isinstance(event, MagenticAgentMessageEvent) and event.message is not None: captured.append(event.message) diff --git a/python/packages/workflow/tests/test_runner.py b/python/packages/main/tests/workflow/test_runner.py similarity index 92% rename from python/packages/workflow/tests/test_runner.py rename to python/packages/main/tests/workflow/test_runner.py index 0666f1b66c..cfd01f1f08 100644 --- a/python/packages/workflow/tests/test_runner.py +++ b/python/packages/main/tests/workflow/test_runner.py @@ -4,12 +4,12 @@ import asyncio from dataclasses import dataclass import pytest -from agent_framework.workflow import Executor, WorkflowCompletedEvent, WorkflowContext, WorkflowEvent, handler -from agent_framework_workflow._edge import SingleEdgeGroup -from agent_framework_workflow._runner import Runner -from agent_framework_workflow._runner_context import InProcRunnerContext, RunnerContext -from agent_framework_workflow._shared_state import SharedState +from agent_framework import Executor, WorkflowCompletedEvent, WorkflowContext, WorkflowEvent, handler +from agent_framework._workflow._edge import SingleEdgeGroup +from agent_framework._workflow._runner import Runner +from agent_framework._workflow._runner_context import InProcRunnerContext, RunnerContext +from agent_framework._workflow._shared_state import SharedState @dataclass diff --git a/python/packages/workflow/tests/test_sequential.py b/python/packages/main/tests/workflow/test_sequential.py similarity index 98% rename from python/packages/workflow/tests/test_sequential.py rename to python/packages/main/tests/workflow/test_sequential.py index 25ccabab75..930ec4db76 100644 --- a/python/packages/workflow/tests/test_sequential.py +++ b/python/packages/main/tests/workflow/test_sequential.py @@ -4,19 +4,17 @@ from collections.abc import AsyncIterable from typing import Any import pytest + from agent_framework import ( AgentRunResponse, AgentRunResponseUpdate, AgentThread, BaseAgent, ChatMessage, - Role, - TextContent, -) - -from agent_framework_workflow import ( Executor, + Role, SequentialBuilder, + TextContent, WorkflowCompletedEvent, WorkflowContext, handler, diff --git a/python/packages/workflow/tests/test_serialization.py b/python/packages/main/tests/workflow/test_serialization.py similarity index 99% rename from python/packages/workflow/tests/test_serialization.py rename to python/packages/main/tests/workflow/test_serialization.py index e3b0177c57..2a515b2c57 100644 --- a/python/packages/workflow/tests/test_serialization.py +++ b/python/packages/main/tests/workflow/test_serialization.py @@ -4,9 +4,11 @@ import json from typing import Any import pytest -from agent_framework.workflow import Executor, WorkflowBuilder, WorkflowContext, handler -from agent_framework_workflow._edge import ( +from agent_framework import Executor, WorkflowBuilder, WorkflowContext, handler +from agent_framework._workflow._edge import ( + Case, + Default, Edge, FanInEdgeGroup, FanOutEdgeGroup, @@ -15,7 +17,7 @@ from agent_framework_workflow._edge import ( SwitchCaseEdgeGroupCase, SwitchCaseEdgeGroupDefault, ) -from agent_framework_workflow._executor import ( +from agent_framework._workflow._executor import ( WorkflowExecutor, ) @@ -629,8 +631,6 @@ class TestSerializationWorkflowClasses: def test_comprehensive_edge_groups_workflow_serialization() -> None: """Test serialization of a workflow that uses all edge group types: SwitchCase, FanOut, and FanIn.""" - from agent_framework_workflow._edge import Case, Default - # Create executors for a comprehensive workflow router = SampleExecutor(id="router") processor_a = SampleExecutor(id="proc_a") diff --git a/python/packages/workflow/tests/test_simple_sub_workflow.py b/python/packages/main/tests/workflow/test_simple_sub_workflow.py similarity index 96% rename from python/packages/workflow/tests/test_simple_sub_workflow.py rename to python/packages/main/tests/workflow/test_simple_sub_workflow.py index 07bbcd6afc..41309db05d 100644 --- a/python/packages/workflow/tests/test_simple_sub_workflow.py +++ b/python/packages/main/tests/workflow/test_simple_sub_workflow.py @@ -5,7 +5,7 @@ from dataclasses import dataclass import pytest -from agent_framework_workflow import ( +from agent_framework import ( Executor, WorkflowBuilder, WorkflowContext, @@ -37,7 +37,7 @@ class SimpleSubExecutor(Executor): @handler async def process(self, request: SimpleRequest, ctx: WorkflowContext[None]) -> None: """Process a simple request.""" - from agent_framework_workflow import WorkflowCompletedEvent + from agent_framework import WorkflowCompletedEvent # Just echo back with prefix and complete response = SimpleResponse(result=f"processed: {request.text}") diff --git a/python/packages/workflow/tests/test_sub_workflow.py b/python/packages/main/tests/workflow/test_sub_workflow.py similarity index 99% rename from python/packages/workflow/tests/test_sub_workflow.py rename to python/packages/main/tests/workflow/test_sub_workflow.py index 8687f3f47e..7bcb72e54b 100644 --- a/python/packages/workflow/tests/test_sub_workflow.py +++ b/python/packages/main/tests/workflow/test_sub_workflow.py @@ -7,7 +7,7 @@ from typing import Any import pytest from pydantic import Field -from agent_framework_workflow import ( +from agent_framework import ( Executor, RequestInfoExecutor, RequestInfoMessage, diff --git a/python/packages/workflow/tests/test_tracing.py b/python/packages/main/tests/workflow/test_tracing.py similarity index 97% rename from python/packages/workflow/tests/test_tracing.py rename to python/packages/main/tests/workflow/test_tracing.py index d42132402a..5b280727c4 100644 --- a/python/packages/workflow/tests/test_tracing.py +++ b/python/packages/main/tests/workflow/test_tracing.py @@ -10,13 +10,13 @@ from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter -from agent_framework_workflow import WorkflowBuilder -from agent_framework_workflow._executor import Executor, handler -from agent_framework_workflow._runner_context import InProcRunnerContext, Message -from agent_framework_workflow._shared_state import SharedState -from agent_framework_workflow._telemetry import WorkflowTracer, workflow_tracer -from agent_framework_workflow._workflow import Workflow -from agent_framework_workflow._workflow_context import WorkflowContext +from agent_framework import WorkflowBuilder +from agent_framework._workflow._executor import Executor, handler +from agent_framework._workflow._runner_context import InProcRunnerContext, Message +from agent_framework._workflow._shared_state import SharedState +from agent_framework._workflow._telemetry import WorkflowTracer, workflow_tracer +from agent_framework._workflow._workflow import Workflow +from agent_framework._workflow._workflow_context import WorkflowContext @pytest.fixture @@ -26,7 +26,7 @@ def tracing_enabled() -> Generator[None, None, None]: os.environ["AGENT_FRAMEWORK_WORKFLOW_ENABLE_OTEL"] = "true" # Force reload the settings to pick up the environment variable - from agent_framework_workflow._telemetry import WorkflowDiagnosticSettings + from agent_framework._workflow._telemetry import WorkflowDiagnosticSettings workflow_tracer.settings = WorkflowDiagnosticSettings() @@ -153,7 +153,7 @@ async def test_workflow_tracer_configuration() -> None: os.environ["AGENT_FRAMEWORK_WORKFLOW_ENABLE_OTEL"] = "true" # Force reload the settings to pick up the environment variable - from agent_framework_workflow._telemetry import WorkflowDiagnosticSettings + from agent_framework._workflow._telemetry import WorkflowDiagnosticSettings tracer.settings = WorkflowDiagnosticSettings() diff --git a/python/packages/workflow/tests/test_validation.py b/python/packages/main/tests/workflow/test_validation.py similarity index 99% rename from python/packages/workflow/tests/test_validation.py rename to python/packages/main/tests/workflow/test_validation.py index 213a9f0e53..6057f4486a 100644 --- a/python/packages/workflow/tests/test_validation.py +++ b/python/packages/main/tests/workflow/test_validation.py @@ -5,7 +5,7 @@ from typing import Any import pytest -from agent_framework_workflow import ( +from agent_framework import ( EdgeDuplicationError, Executor, GraphConnectivityError, @@ -17,8 +17,8 @@ from agent_framework_workflow import ( handler, validate_workflow_graph, ) -from agent_framework_workflow._edge import SingleEdgeGroup -from agent_framework_workflow._validation import HandlerOutputAnnotationError +from agent_framework._workflow._edge import SingleEdgeGroup +from agent_framework._workflow._validation import HandlerOutputAnnotationError class StringExecutor(Executor): diff --git a/python/packages/workflow/tests/test_viz.py b/python/packages/main/tests/workflow/test_viz.py similarity index 98% rename from python/packages/workflow/tests/test_viz.py rename to python/packages/main/tests/workflow/test_viz.py index 474cd1ade2..d445343590 100644 --- a/python/packages/workflow/tests/test_viz.py +++ b/python/packages/main/tests/workflow/test_viz.py @@ -3,9 +3,8 @@ """Tests for the workflow visualization module.""" import pytest -from agent_framework.workflow import Executor, WorkflowBuilder, WorkflowContext, WorkflowViz, handler -from agent_framework_workflow import WorkflowExecutor +from agent_framework import Executor, WorkflowBuilder, WorkflowContext, WorkflowExecutor, WorkflowViz, handler class MockExecutor(Executor): diff --git a/python/packages/workflow/tests/test_workflow.py b/python/packages/main/tests/workflow/test_workflow.py similarity index 98% rename from python/packages/workflow/tests/test_workflow.py rename to python/packages/main/tests/workflow/test_workflow.py index bdca48afbc..e1b5956c3c 100644 --- a/python/packages/workflow/tests/test_workflow.py +++ b/python/packages/main/tests/workflow/test_workflow.py @@ -5,9 +5,11 @@ from dataclasses import dataclass from typing import Any import pytest -from agent_framework.workflow import ( + +from agent_framework import ( Executor, FileCheckpointStorage, + Message, RequestInfoEvent, RequestInfoExecutor, RequestInfoMessage, @@ -19,8 +21,6 @@ from agent_framework.workflow import ( handler, ) -from agent_framework_workflow import Message - @dataclass class NumberMessage: @@ -381,7 +381,7 @@ async def test_workflow_run_stream_from_checkpoint_with_external_storage(simple_ storage = FileCheckpointStorage(temp_dir) # Create a test checkpoint manually in storage - from agent_framework_workflow._checkpoint import WorkflowCheckpoint + from agent_framework import WorkflowCheckpoint test_checkpoint = WorkflowCheckpoint( workflow_id="test-workflow", @@ -418,7 +418,7 @@ async def test_workflow_run_from_checkpoint_non_streaming(simple_executor: Execu storage = FileCheckpointStorage(temp_dir) # Create a test checkpoint manually in storage - from agent_framework_workflow._checkpoint import WorkflowCheckpoint + from agent_framework import WorkflowCheckpoint test_checkpoint = WorkflowCheckpoint( workflow_id="test-workflow", @@ -451,7 +451,7 @@ async def test_workflow_run_stream_from_checkpoint_with_responses(simple_executo storage = FileCheckpointStorage(temp_dir) # Create a test checkpoint manually in storage - from agent_framework_workflow._checkpoint import WorkflowCheckpoint + from agent_framework import WorkflowCheckpoint test_checkpoint = WorkflowCheckpoint( workflow_id="test-workflow", @@ -561,7 +561,7 @@ async def test_workflow_multiple_runs_no_state_collision(): async def test_comprehensive_edge_groups_workflow(): """Test a workflow that uses SwitchCaseEdgeGroup, FanOutEdgeGroup, and FanInEdgeGroup.""" - from agent_framework_workflow._edge import Case, Default + from agent_framework import Case, Default # Create 6 executors for different roles with different increment values router = IncrementExecutor(id="router", limit=1000, increment=1) # Increment by 1 @@ -668,7 +668,7 @@ async def test_workflow_with_simple_cycle_and_exit_condition(): # Verify cycling occurred (should have events from both executors) # Check for ExecutorInvokeEvent and ExecutorCompletedEvent types that have executor_id - from agent_framework_workflow._events import ExecutorCompletedEvent, ExecutorInvokeEvent + from agent_framework import ExecutorCompletedEvent, ExecutorInvokeEvent executor_events = [e for e in events if isinstance(e, (ExecutorInvokeEvent, ExecutorCompletedEvent))] executor_ids = {e.executor_id for e in executor_events} diff --git a/python/packages/workflow/tests/test_workflow_agent.py b/python/packages/main/tests/workflow/test_workflow_agent.py similarity index 99% rename from python/packages/workflow/tests/test_workflow_agent.py rename to python/packages/main/tests/workflow/test_workflow_agent.py index 8a8377843e..a194940d27 100644 --- a/python/packages/workflow/tests/test_workflow_agent.py +++ b/python/packages/main/tests/workflow/test_workflow_agent.py @@ -4,21 +4,20 @@ import uuid from typing import Any import pytest + from agent_framework import ( AgentRunResponse, AgentRunResponseUpdate, + AgentRunUpdateEvent, ChatMessage, + Executor, FunctionResultContent, + RequestInfoExecutor, + RequestInfoMessage, Role, TextContent, UsageContent, UsageDetails, -) -from agent_framework.workflow import ( - AgentRunUpdateEvent, - Executor, - RequestInfoExecutor, - RequestInfoMessage, WorkflowAgent, WorkflowBuilder, WorkflowContext, diff --git a/python/packages/workflow/tests/test_workflow_builder.py b/python/packages/main/tests/workflow/test_workflow_builder.py similarity index 93% rename from python/packages/workflow/tests/test_workflow_builder.py rename to python/packages/main/tests/workflow/test_workflow_builder.py index ebd3d2c9d0..bcac9c7669 100644 --- a/python/packages/workflow/tests/test_workflow_builder.py +++ b/python/packages/main/tests/workflow/test_workflow_builder.py @@ -4,8 +4,20 @@ from dataclasses import dataclass from typing import Any import pytest -from agent_framework import AgentRunResponse, AgentRunResponseUpdate, AgentThread, BaseAgent, ChatMessage, Role -from agent_framework.workflow import AgentExecutor, Executor, WorkflowBuilder, WorkflowContext, handler + +from agent_framework import ( + AgentExecutor, + AgentRunResponse, + AgentRunResponseUpdate, + AgentThread, + BaseAgent, + ChatMessage, + Executor, + Role, + WorkflowBuilder, + WorkflowContext, + handler, +) class DummyAgent(BaseAgent): diff --git a/python/packages/workflow/tests/test_workflow_states.py b/python/packages/main/tests/workflow/test_workflow_states.py similarity index 95% rename from python/packages/workflow/tests/test_workflow_states.py rename to python/packages/main/tests/workflow/test_workflow_states.py index 0070afda46..51e16d5afb 100644 --- a/python/packages/workflow/tests/test_workflow_states.py +++ b/python/packages/main/tests/workflow/test_workflow_states.py @@ -1,12 +1,15 @@ # Copyright (c) Microsoft. All rights reserved. import pytest -from agent_framework.workflow import ( + +from agent_framework import ( Executor, ExecutorFailedEvent, + InProcRunnerContext, RequestInfoEvent, RequestInfoExecutor, RequestInfoMessage, + SharedState, Workflow, WorkflowBuilder, WorkflowCompletedEvent, @@ -17,10 +20,7 @@ from agent_framework.workflow import ( WorkflowStatusEvent, handler, ) - -from agent_framework_workflow import InProcRunnerContext -from agent_framework_workflow._shared_state import SharedState -from agent_framework_workflow._workflow_context import WorkflowContext as WFContext +from agent_framework import WorkflowContext as WFContext class FailingExecutor(Executor): diff --git a/python/packages/mem0/pyproject.toml b/python/packages/mem0/pyproject.toml index dc3324db79..5e95378c60 100644 --- a/python/packages/mem0/pyproject.toml +++ b/python/packages/mem0/pyproject.toml @@ -84,10 +84,6 @@ include = "../../shared_tasks.toml" mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_mem0" test = "pytest --cov=agent_framework_mem0 --cov-report=term-missing:skip-covered tests" -[tool.uv.build-backend] -module-name = "agent_framework_mem0" -module-root = "" - [build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" +requires = ["flit-core >= 3.9,<4.0"] +build-backend = "flit_core.buildapi" diff --git a/python/packages/runtime/pyproject.toml b/python/packages/runtime/pyproject.toml index 34c2980028..a22c1ba683 100644 --- a/python/packages/runtime/pyproject.toml +++ b/python/packages/runtime/pyproject.toml @@ -81,10 +81,6 @@ include = "../../shared_tasks.toml" mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_runtime" test = "pytest --cov=agent_framework_runtime --cov-report=term-missing:skip-covered tests" -[tool.uv.build-backend] -module-name = "agent_framework_runtime" -module-root = "" - [build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" \ No newline at end of file +requires = ["flit-core >= 3.9,<4.0"] +build-backend = "flit_core.buildapi" diff --git a/python/packages/runtime/tests/test_sample.py b/python/packages/runtime/tests/test_sample.py new file mode 100644 index 0000000000..73e3423a41 --- /dev/null +++ b/python/packages/runtime/tests/test_sample.py @@ -0,0 +1,6 @@ +# Copyright (c) Microsoft. All rights reserved. + + +def test_sample(): + """Sample test so test task doesn't stop due to no tests.""" + assert True diff --git a/python/packages/workflow/LICENSE b/python/packages/workflow/LICENSE deleted file mode 100644 index 9e841e7a26..0000000000 --- a/python/packages/workflow/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/python/packages/workflow/README.md b/python/packages/workflow/README.md deleted file mode 100644 index 1133074818..0000000000 --- a/python/packages/workflow/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Get Started with Microsoft Agent Framework Workflow - -Please install this package as the extra for `agent-framework`: - -```bash -pip install agent-framework[workflow] -``` - -and see the [README](https://github.com/microsoft/agent-framework/tree/main/python/README.md) for more information. diff --git a/python/packages/workflow/pyproject.toml b/python/packages/workflow/pyproject.toml deleted file mode 100644 index 4dfece1cb7..0000000000 --- a/python/packages/workflow/pyproject.toml +++ /dev/null @@ -1,95 +0,0 @@ -[project] -name = "agent-framework-workflow" -description = "Workflow integration for Microsoft Agent Framework." -authors = [{ name = "Microsoft", email = "SK-Support@microsoft.com"}] -readme = "README.md" -requires-python = ">=3.10" -version = "0.1.0b1" -license-files = ["LICENSE"] -urls.homepage = "https://learn.microsoft.com/en-us/semantic-kernel/overview/" -urls.source = "https://github.com/microsoft/agent-framework/tree/main/python" -urls.release_notes = "https://github.com/microsoft/agent-framework/releases?q=tag%3Apython-1&expanded=true" -urls.issues = "https://github.com/microsoft/agent-framework/issues" -classifiers = [ - "License :: OSI Approved :: MIT License", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Framework :: Pydantic :: 2", - "Typing :: Typed", -] -dependencies = [ - "agent-framework", -] - -[project.optional-dependencies] -viz = [ - "graphviz>=0.20.0", -] - -[tool.uv] -prerelease = "if-necessary-or-explicit" -environments = [ - "sys_platform == 'darwin'", - "sys_platform == 'linux'", - "sys_platform == 'win32'" -] - -[tool.uv-dynamic-versioning] -fallback-version = "0.0.0" -[tool.pytest.ini_options] -testpaths = 'tests' -addopts = "-ra -q -r fEX" -asyncio_mode = "auto" -asyncio_default_fixture_loop_scope = "function" -filterwarnings = [] -timeout = 120 - -[tool.ruff] -extend = "../../pyproject.toml" - -[tool.coverage.run] -omit = [ - "**/__init__.py" -] - -[tool.pyright] -extend = "../../pyproject.toml" -exclude = ['tests'] - -[tool.mypy] -plugins = ['pydantic.mypy'] -strict = true -python_version = "3.10" -ignore_missing_imports = true -disallow_untyped_defs = true -no_implicit_optional = true -check_untyped_defs = true -warn_return_any = true -show_error_codes = true -warn_unused_ignores = false -disallow_incomplete_defs = true -disallow_untyped_decorators = true - -[tool.bandit] -targets = ["agent_framework_workflow"] -exclude_dirs = ["tests"] - -[tool.poe] -executor.type = "uv" -include = "../../shared_tasks.toml" -[tool.poe.tasks] -mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_workflow" -test = "pytest --cov=agent_framework_workflow --cov-report=term-missing:skip-covered tests" - -[tool.uv.build-backend] -module-name = "agent_framework_workflow" -module-root = "" - -[build-system] -requires = ["uv_build>=0.8.2,<0.9.0"] -build-backend = "uv_build" diff --git a/python/pyproject.toml b/python/pyproject.toml index 1b2e1a456f..d35badb111 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -9,7 +9,6 @@ dependencies = [ "agent-framework-copilotstudio", "agent-framework-foundry", "agent-framework-mem0", - "agent-framework-workflow", ] [dependency-groups] @@ -29,23 +28,12 @@ dev = [ "rich", "tomli", "tomli-w", - "markdownify", +] +docs = [ # Documentation - "myst-nb==1.1.2", - "pydata-sphinx-theme==0.16.1", - "sphinx-copybutton", - "sphinx-design", - "sphinx", - "autodoc_pydantic>=2", - "pygments", - "sphinxext-rediraffe", - "opentelemetry-instrumentation-openai", - "markdown-it-py[linkify]", - # Documentation tooling - "diskcache", - "redis", - "sphinx-autobuild", - "aiofiles>=24.1.0", + "debugpy>=1.8.16", + "py2docfx>=0.1.20", + "pip", ] [tool.uv] @@ -68,7 +56,6 @@ agent-framework-copilotstudio = { workspace = true } agent-framework-foundry = { workspace = true } agent-framework-mem0 = { workspace = true } agent-framework-runtime = { workspace = true } -agent-framework-workflow = { workspace = true } [tool.ruff] line-length = 120 @@ -175,15 +162,14 @@ exclude_dirs = ["tests", "./run_tasks_in_packages_if_exists.py", "./check_md_cod executor.type = "uv" [tool.poe.tasks] -markdown-code-lint = """python check_md_code_blocks.py ./docs/agent-framework/**/*.md README.md""" +markdown-code-lint = """python check_md_code_blocks.py README.md ./packages/**/README.md ./samples/**/*.md""" samples-code-check = """pyright ./samples""" +docs-install = "uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit --group=docs" docs-clean = "rm -rf docs/build" -docs-build = "sphinx-build docs/agent-framework docs/build" -docs-serve = "sphinx-autobuild --watch docs/agent-framework docs/build --port 8000 --jobs auto" -docs-check = "sphinx-build --fail-on-warning docs/agent-framework docs/build" -docs-check-examples = "sphinx-build -b code_lint docs/agent-framework docs/build" +docs-build = "uv run python ./docs/generate_docs.py" +docs-debug = "uv run python -m debugpy --listen 5678 ./docs/generate_docs.py" pre-commit-install = "uv run pre-commit install --install-hooks --overwrite" -install = "uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit" +install = "uv sync --all-packages --all-extras --dev -U --prerelease=if-necessary-or-explicit --no-group=docs" test = "python run_tasks_in_packages_if_exists.py test" fmt = "python run_tasks_in_packages_if_exists.py fmt" format.ref = "fmt" @@ -194,7 +180,7 @@ build = "python run_tasks_in_packages_if_exists.py build" # combined checks check = ["fmt", "lint", "pyright", "mypy", "test", "markdown-code-lint", "samples-code-check"] pre-commit-check = ["fmt", "lint", "pyright", "markdown-code-lint", "samples-code-check"] -all-tests = "pytest --import-mode=importlib --cov=agent_framework --cov=agent_framework_azure --cov=agent_framework_copilotstudio --cov=agent_framework_foundry --cov=agent_framework_mem0 --cov=agent_framework_workflow --cov-report=term-missing:skip-covered packages/azure/tests packages/copilotstudio/tests packages/foundry/tests packages/main/tests packages/mem0/tests packages/workflow/tests" +all-tests = "pytest --import-mode=importlib --cov=agent_framework --cov=agent_framework_azure --cov=agent_framework_copilotstudio --cov=agent_framework_foundry --cov=agent_framework_mem0 --cov-report=term-missing:skip-covered packages/azure/tests packages/copilotstudio/tests packages/foundry/tests packages/main/tests packages/mem0/tests" [tool.poe.tasks.venv] cmd = "uv venv --clear --python $python" @@ -206,6 +192,29 @@ sequence = [ { ref = "pre-commit-install" } ] args = [{ name = "python", default = "3.13", options = ['-p', '--python'] }] +[tool.poe.tasks.docs-full] +sequence = [ + { ref = 'build' }, + { ref = "docs-clean" }, + { ref = "docs-build" } +] +[tool.poe.tasks.docs-full-install] +sequence = [ + { ref = "docs-install" }, + { ref = 'build' }, + { ref = "docs-clean" }, + { ref = "docs-build" } +] +[tool.poe.tasks.docs-rebuild] +sequence = [ + { ref = "docs-clean" }, + { ref = "docs-build" } +] +[tool.poe.tasks.docs-rebuild-debug] +sequence = [ + { ref = "docs-clean" }, + { ref = "docs-debug" } +] [tool.setuptools.packages.find] where = ["packages"] diff --git a/python/samples/getting_started/agents/copilotstudio/README.md b/python/samples/getting_started/agents/copilotstudio/README.md index e2503db51a..10c308e690 100644 --- a/python/samples/getting_started/agents/copilotstudio/README.md +++ b/python/samples/getting_started/agents/copilotstudio/README.md @@ -29,15 +29,15 @@ The examples use MSAL (Microsoft Authentication Library) for authentication. The Your Azure AD App Registration should have: -1. **API Permissions**: +1. **API Permissions**: - Power Platform API permissions (https://api.powerplatform.com/.default) - Appropriate delegated permissions for your organization -2. **Redirect URIs**: - - For public client flows: `http://localhost` +2. **Redirect URIs**: + - For public client flows: `http://localhost` - Configure as appropriate for your authentication method -3. **Authentication**: +3. **Authentication**: - Enable "Allow public client flows" if using interactive authentication ## Usage Patterns @@ -45,11 +45,19 @@ Your Azure AD App Registration should have: ### Basic Usage with Environment Variables ```python +import asyncio from agent_framework.copilotstudio import CopilotStudioAgent # Uses environment variables for configuration -agent = CopilotStudioAgent() -result = await agent.run("What is the capital of France?") +async def main(): + # Create agent using environment variables + agent = CopilotStudioAgent() + + # Run a simple query + result = await agent.run("What is the capital of France?") + print(result) + +asyncio.run(main()) ``` ### Explicit Configuration @@ -69,7 +77,8 @@ settings = ConnectionSettings( environment_id="your-environment-id", agent_identifier="your-agent-schema-name", cloud=PowerPlatformCloud.PROD, - copilot_agent_type=AgentType.PUBLISHED + copilot_agent_type=AgentType.PUBLISHED, + custom_power_platform_cloud=None ) client = CopilotClient(settings=settings, token=token) @@ -80,7 +89,7 @@ agent = CopilotStudioAgent(client=client) ### Common Issues -1. **Authentication Errors**: +1. **Authentication Errors**: - Verify your App Registration has correct permissions - Ensure environment variables are set correctly - Check that your tenant ID and client ID are valid diff --git a/python/samples/getting_started/telemetry/04-workflow.py b/python/samples/getting_started/telemetry/04-workflow.py index e07df885e2..88bd8b7187 100644 --- a/python/samples/getting_started/telemetry/04-workflow.py +++ b/python/samples/getting_started/telemetry/04-workflow.py @@ -3,14 +3,14 @@ import asyncio from typing import Any -from agent_framework.telemetry import setup_telemetry -from agent_framework.workflow import ( +from agent_framework import ( Executor, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, handler, ) +from agent_framework.telemetry import setup_telemetry from opentelemetry import trace from opentelemetry.trace import SpanKind from opentelemetry.trace.span import format_trace_id diff --git a/python/samples/getting_started/telemetry/README.md b/python/samples/getting_started/telemetry/README.md index b574aa4251..53d309aad1 100644 --- a/python/samples/getting_started/telemetry/README.md +++ b/python/samples/getting_started/telemetry/README.md @@ -79,6 +79,18 @@ This sample shows how to setup telemetry when using the Agent Framework's workfl ## Application Insights/Azure Monitor +### Authentication + +You can connect to your Application Insights instance using a connection string. You can also authenticate using Entra ID by passing a [TokenCredential](https://learn.microsoft.com/en-us/python/api/azure-core/azure.core.credentials.tokencredential?view=azure-python) to the `setup_telemetry()` function used in the samples above. + +```python +from azure.identity import DefaultAzureCredential + +setup_telemetry(credential=DefaultAzureCredential()) +``` + +It is recommended to use [DefaultAzureCredential](https://learn.microsoft.com/en-us/python/api/azure-identity/azure.identity.defaultazurecredential?view=azure-python) for local development and [ManagedIdentityCredential](https://learn.microsoft.com/en-us/python/api/azure-identity/azure.identity.managedidentitycredential?view=azure-python) for production environments. + ### Logs and traces Go to your Application Insights instance, click on _Transaction search_ on the left menu. Use the operation id output by the program to search for the logs and traces associated with the operation. Click on any of the search result to view the end-to-end transaction details. Read more [here](https://learn.microsoft.com/en-us/azure/azure-monitor/app/transaction-search-and-diagnostics?tabs=transaction-search). diff --git a/python/samples/getting_started/workflow/README.md b/python/samples/getting_started/workflow/README.md index 1a52dfe738..4b879e10dd 100644 --- a/python/samples/getting_started/workflow/README.md +++ b/python/samples/getting_started/workflow/README.md @@ -2,16 +2,12 @@ ## Installation -To install the base `agent_framework.workflow` package, run: - -```bash -pip install agent-framework-workflow -``` +Workflow support ships with the core `agent-framework` package, so no extra installation step is required. To install with visualization support: ```bash -pip install agent-framework-workflow[viz] +pip install agent-framework[viz] ``` To export visualization images you also need to [install GraphViz](https://graphviz.org/download/). diff --git a/python/samples/getting_started/workflow/_start-here/step1_executors_and_edges.py b/python/samples/getting_started/workflow/_start-here/step1_executors_and_edges.py index 14c5348575..173c578a51 100644 --- a/python/samples/getting_started/workflow/_start-here/step1_executors_and_edges.py +++ b/python/samples/getting_started/workflow/_start-here/step1_executors_and_edges.py @@ -2,7 +2,7 @@ import asyncio -from agent_framework.workflow import ( +from agent_framework import ( Executor, WorkflowBuilder, WorkflowCompletedEvent, diff --git a/python/samples/getting_started/workflow/_start-here/step2_agents_in_a_workflow.py b/python/samples/getting_started/workflow/_start-here/step2_agents_in_a_workflow.py index 3d42723a38..1c0a113965 100644 --- a/python/samples/getting_started/workflow/_start-here/step2_agents_in_a_workflow.py +++ b/python/samples/getting_started/workflow/_start-here/step2_agents_in_a_workflow.py @@ -2,8 +2,8 @@ import asyncio +from agent_framework import AgentRunEvent, WorkflowBuilder from agent_framework.azure import AzureChatClient -from agent_framework.workflow import AgentRunEvent, WorkflowBuilder from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/_start-here/step3_streaming.py b/python/samples/getting_started/workflow/_start-here/step3_streaming.py index 0619bd4c8e..423fcd53da 100644 --- a/python/samples/getting_started/workflow/_start-here/step3_streaming.py +++ b/python/samples/getting_started/workflow/_start-here/step3_streaming.py @@ -2,9 +2,9 @@ import asyncio -from agent_framework import ChatAgent, ChatMessage -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( + ChatAgent, + ChatMessage, Executor, ExecutorFailedEvent, WorkflowBuilder, @@ -15,6 +15,7 @@ from agent_framework.workflow import ( WorkflowStatusEvent, handler, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/agents/azure_chat_agents_streaming.py b/python/samples/getting_started/workflow/agents/azure_chat_agents_streaming.py index 4f39385a92..175ee30214 100644 --- a/python/samples/getting_started/workflow/agents/azure_chat_agents_streaming.py +++ b/python/samples/getting_started/workflow/agents/azure_chat_agents_streaming.py @@ -2,8 +2,8 @@ import asyncio +from agent_framework import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent from agent_framework.azure import AzureChatClient -from agent_framework.workflow import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/agents/custom_agent_executors.py b/python/samples/getting_started/workflow/agents/custom_agent_executors.py index 6d416eb1b1..eb9497ae77 100644 --- a/python/samples/getting_started/workflow/agents/custom_agent_executors.py +++ b/python/samples/getting_started/workflow/agents/custom_agent_executors.py @@ -2,9 +2,16 @@ import asyncio -from agent_framework import ChatAgent, ChatMessage +from agent_framework import ( + ChatAgent, + ChatMessage, + Executor, + WorkflowBuilder, + WorkflowCompletedEvent, + WorkflowContext, + handler, +) from agent_framework.azure import AzureChatClient -from agent_framework.workflow import Executor, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, handler from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/agents/foundry_chat_agents_streaming.py b/python/samples/getting_started/workflow/agents/foundry_chat_agents_streaming.py index da7cba755a..20f04c2a00 100644 --- a/python/samples/getting_started/workflow/agents/foundry_chat_agents_streaming.py +++ b/python/samples/getting_started/workflow/agents/foundry_chat_agents_streaming.py @@ -3,7 +3,7 @@ # import asyncio # from agent_framework.foundry import FoundryChatClient -# from agent_framework.workflow import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent +# from agent_framework import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent # from azure.identity.aio import AzureCliCredential # """ @@ -100,7 +100,7 @@ from typing import Any from collections.abc import Awaitable, Callable from agent_framework.foundry import FoundryChatClient -from agent_framework.workflow import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent +from agent_framework import AgentRunUpdateEvent, WorkflowBuilder, WorkflowCompletedEvent from azure.identity.aio import AzureCliCredential diff --git a/python/samples/getting_started/workflow/agents/workflow_as_agent_human_in_the_loop.py b/python/samples/getting_started/workflow/agents/workflow_as_agent_human_in_the_loop.py index 54940837c0..c1af5d63cc 100644 --- a/python/samples/getting_started/workflow/agents/workflow_as_agent_human_in_the_loop.py +++ b/python/samples/getting_started/workflow/agents/workflow_as_agent_human_in_the_loop.py @@ -10,7 +10,7 @@ from agent_framework import ( Role, ) from agent_framework.openai import OpenAIChatClient -from agent_framework.workflow import ( +from agent_framework import ( Executor, RequestInfoExecutor, RequestInfoMessage, diff --git a/python/samples/getting_started/workflow/agents/workflow_as_agent_reflection_pattern.py b/python/samples/getting_started/workflow/agents/workflow_as_agent_reflection_pattern.py index 8fa8835176..1dd66da437 100644 --- a/python/samples/getting_started/workflow/agents/workflow_as_agent_reflection_pattern.py +++ b/python/samples/getting_started/workflow/agents/workflow_as_agent_reflection_pattern.py @@ -6,7 +6,7 @@ from uuid import uuid4 from agent_framework import AgentRunResponseUpdate, ChatClientProtocol, ChatMessage, Contents, Role from agent_framework.openai import OpenAIChatClient -from agent_framework.workflow import AgentRunUpdateEvent, Executor, WorkflowBuilder, WorkflowContext, handler +from agent_framework import AgentRunUpdateEvent, Executor, WorkflowBuilder, WorkflowContext, handler from pydantic import BaseModel """ diff --git a/python/samples/getting_started/workflow/checkpoint/checkpoint_with_resume.py b/python/samples/getting_started/workflow/checkpoint/checkpoint_with_resume.py index db70db6ec5..839b3ad12c 100644 --- a/python/samples/getting_started/workflow/checkpoint/checkpoint_with_resume.py +++ b/python/samples/getting_started/workflow/checkpoint/checkpoint_with_resume.py @@ -5,19 +5,20 @@ import os from pathlib import Path from typing import Any -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutor, AgentExecutorRequest, AgentExecutorResponse, + ChatMessage, Executor, FileCheckpointStorage, + Role, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, handler, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/composition/sub_workflow_basics.py b/python/samples/getting_started/workflow/composition/sub_workflow_basics.py index ed023be224..1c8013bacf 100644 --- a/python/samples/getting_started/workflow/composition/sub_workflow_basics.py +++ b/python/samples/getting_started/workflow/composition/sub_workflow_basics.py @@ -4,7 +4,7 @@ import asyncio from dataclasses import dataclass from typing import Any -from agent_framework.workflow import ( +from agent_framework import ( Executor, WorkflowBuilder, WorkflowCompletedEvent, diff --git a/python/samples/getting_started/workflow/composition/sub_workflow_parallel_requests.py b/python/samples/getting_started/workflow/composition/sub_workflow_parallel_requests.py index 7ab7737a8e..a5a5ef45bd 100644 --- a/python/samples/getting_started/workflow/composition/sub_workflow_parallel_requests.py +++ b/python/samples/getting_started/workflow/composition/sub_workflow_parallel_requests.py @@ -4,7 +4,7 @@ import asyncio from dataclasses import dataclass from typing import Any -from agent_framework.workflow import ( +from agent_framework import ( Executor, RequestInfoExecutor, WorkflowBuilder, @@ -15,7 +15,7 @@ from agent_framework.workflow import ( # Import the new sub-workflow types directly from the implementation package try: - from agent_framework_workflow import ( + from agent_framework import ( RequestInfoMessage, RequestResponse, WorkflowExecutor, @@ -26,7 +26,7 @@ except ImportError: import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", "packages", "workflow")) - from agent_framework_workflow import ( + from agent_framework import ( RequestInfoMessage, RequestResponse, WorkflowExecutor, diff --git a/python/samples/getting_started/workflow/composition/sub_workflow_request_interception.py b/python/samples/getting_started/workflow/composition/sub_workflow_request_interception.py index eae530334b..2cc2be9a01 100644 --- a/python/samples/getting_started/workflow/composition/sub_workflow_request_interception.py +++ b/python/samples/getting_started/workflow/composition/sub_workflow_request_interception.py @@ -4,7 +4,7 @@ import asyncio from dataclasses import dataclass from typing import Any -from agent_framework_workflow import ( +from agent_framework import ( Executor, RequestInfoExecutor, RequestInfoMessage, diff --git a/python/samples/getting_started/workflow/control-flow/edge_condition.py b/python/samples/getting_started/workflow/control-flow/edge_condition.py index 63d2977ca4..405b237fe5 100644 --- a/python/samples/getting_started/workflow/control-flow/edge_condition.py +++ b/python/samples/getting_started/workflow/control-flow/edge_condition.py @@ -4,17 +4,18 @@ import asyncio import os from typing import Any -from agent_framework import ChatMessage, Role # Core chat primitives used to build requests -from agent_framework.azure import AzureChatClient # Thin client wrapper for Azure OpenAI chat models -from agent_framework.workflow import ( +from agent_framework import ( # Core chat primitives used to build requests AgentExecutor, # Wraps an LLM agent that can be invoked inside a workflow AgentExecutorRequest, # Input message bundle for an AgentExecutor AgentExecutorResponse, # Output from an AgentExecutor + ChatMessage, + Role, WorkflowBuilder, # Fluent builder for wiring executors and edges WorkflowCompletedEvent, # Event we emit at the end to signal completion WorkflowContext, # Per-run context and event bus executor, # Decorator to declare a Python function as a workflow executor ) +from agent_framework.azure import AzureChatClient # Thin client wrapper for Azure OpenAI chat models from azure.identity import AzureCliCredential # Uses your az CLI login for credentials from pydantic import BaseModel # Structured outputs for safer parsing diff --git a/python/samples/getting_started/workflow/control-flow/multi_selection_edge_group.py b/python/samples/getting_started/workflow/control-flow/multi_selection_edge_group.py index d14a1ab539..547f0ed740 100644 --- a/python/samples/getting_started/workflow/control-flow/multi_selection_edge_group.py +++ b/python/samples/getting_started/workflow/control-flow/multi_selection_edge_group.py @@ -8,18 +8,19 @@ from dataclasses import dataclass from typing import Literal from uuid import uuid4 -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutor, AgentExecutorRequest, AgentExecutorResponse, + ChatMessage, + Role, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, WorkflowEvent, executor, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential from pydantic import BaseModel diff --git a/python/samples/getting_started/workflow/control-flow/sequential_executors.py b/python/samples/getting_started/workflow/control-flow/sequential_executors.py index 9da46054f3..d4921e99fa 100644 --- a/python/samples/getting_started/workflow/control-flow/sequential_executors.py +++ b/python/samples/getting_started/workflow/control-flow/sequential_executors.py @@ -3,7 +3,7 @@ import asyncio from typing import Any -from agent_framework.workflow import ( +from agent_framework import ( Executor, WorkflowBuilder, WorkflowCompletedEvent, diff --git a/python/samples/getting_started/workflow/control-flow/sequential_streaming.py b/python/samples/getting_started/workflow/control-flow/sequential_streaming.py index 9333611824..bf194ba901 100644 --- a/python/samples/getting_started/workflow/control-flow/sequential_streaming.py +++ b/python/samples/getting_started/workflow/control-flow/sequential_streaming.py @@ -2,7 +2,7 @@ import asyncio -from agent_framework.workflow import WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, executor +from agent_framework import WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, executor """ Sample: Foundational sequential workflow with streaming using function-style executors. diff --git a/python/samples/getting_started/workflow/control-flow/simple_loop.py b/python/samples/getting_started/workflow/control-flow/simple_loop.py index b2ed84e42a..d38c314b02 100644 --- a/python/samples/getting_started/workflow/control-flow/simple_loop.py +++ b/python/samples/getting_started/workflow/control-flow/simple_loop.py @@ -3,19 +3,20 @@ import asyncio from enum import Enum -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutor, AgentExecutorRequest, AgentExecutorResponse, + ChatMessage, Executor, ExecutorCompletedEvent, + Role, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, handler, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/control-flow/switch_case_edge_group.py b/python/samples/getting_started/workflow/control-flow/switch_case_edge_group.py index b23ffafb08..0833ff5b12 100644 --- a/python/samples/getting_started/workflow/control-flow/switch_case_edge_group.py +++ b/python/samples/getting_started/workflow/control-flow/switch_case_edge_group.py @@ -6,19 +6,20 @@ from dataclasses import dataclass from typing import Any, Literal from uuid import uuid4 -from agent_framework import ChatMessage, Role # Core chat primitives used to form LLM requests -from agent_framework.azure import AzureChatClient # Thin client for Azure OpenAI chat models -from agent_framework.workflow import ( +from agent_framework import ( # Core chat primitives used to form LLM requests AgentExecutor, # Wraps an agent so it can run inside a workflow AgentExecutorRequest, # Message bundle sent to an AgentExecutor AgentExecutorResponse, # Result returned by an AgentExecutor Case, # Case entry for a switch-case edge group + ChatMessage, Default, # Default branch when no cases match + Role, WorkflowBuilder, # Fluent builder for assembling the graph WorkflowCompletedEvent, # Terminal event for successful completion WorkflowContext, # Per-run context and event bus executor, # Decorator to turn a function into a workflow executor ) +from agent_framework.azure import AzureChatClient # Thin client for Azure OpenAI chat models from azure.identity import AzureCliCredential # Uses your az CLI login for credentials from pydantic import BaseModel # Structured outputs with validation diff --git a/python/samples/getting_started/workflow/human-in-the-loop/guessing_game_with_human_input.py b/python/samples/getting_started/workflow/human-in-the-loop/guessing_game_with_human_input.py index ca5c5ec884..1be8abf83b 100644 --- a/python/samples/getting_started/workflow/human-in-the-loop/guessing_game_with_human_input.py +++ b/python/samples/getting_started/workflow/human-in-the-loop/guessing_game_with_human_input.py @@ -3,17 +3,17 @@ import asyncio from dataclasses import dataclass -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutor, # Executor that runs the agent AgentExecutorRequest, # Message bundle sent to an AgentExecutor AgentExecutorResponse, # Result returned by an AgentExecutor - Executor, + ChatMessage, # Chat message structure + Executor, # Base class for workflow executors RequestInfoEvent, # Event emitted when human input is requested RequestInfoExecutor, # Special executor that collects human input out of band RequestInfoMessage, # Base class for request payloads sent to RequestInfoExecutor RequestResponse, # Correlates a human response with the original request + Role, # Enum of chat roles (user, assistant, system) WorkflowBuilder, # Fluent builder for assembling the graph WorkflowCompletedEvent, # Terminal event used to finish the workflow WorkflowContext, # Per run context and event bus @@ -21,6 +21,7 @@ from agent_framework.workflow import ( WorkflowStatusEvent, # Event emitted on run state changes handler, # Decorator to expose an Executor method as a step ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential from pydantic import BaseModel @@ -230,13 +231,11 @@ async def main() -> None: # Detect run state transitions for a better developer experience. pending_status = any( - isinstance(e, WorkflowStatusEvent) - and e.state == WorkflowRunState.IN_PROGRESS_PENDING_REQUESTS + isinstance(e, WorkflowStatusEvent) and e.state == WorkflowRunState.IN_PROGRESS_PENDING_REQUESTS for e in events ) idle_with_requests = any( - isinstance(e, WorkflowStatusEvent) - and e.state == WorkflowRunState.IDLE_WITH_PENDING_REQUESTS + isinstance(e, WorkflowStatusEvent) and e.state == WorkflowRunState.IDLE_WITH_PENDING_REQUESTS for e in events ) if pending_status: diff --git a/python/samples/getting_started/workflow/observability/tracing_basics.py b/python/samples/getting_started/workflow/observability/tracing_basics.py index 0fbccd9e47..3e34aefbcf 100644 --- a/python/samples/getting_started/workflow/observability/tracing_basics.py +++ b/python/samples/getting_started/workflow/observability/tracing_basics.py @@ -4,7 +4,7 @@ import asyncio import os from typing import Any -from agent_framework_workflow import Executor, WorkflowBuilder, WorkflowContext, handler +from agent_framework import Executor, WorkflowBuilder, WorkflowContext, handler """Basic tracing workflow sample. diff --git a/python/samples/getting_started/workflow/orchestration/concurrent_agents.py b/python/samples/getting_started/workflow/orchestration/concurrent_agents.py index b8e165c5b4..df3d212b4c 100644 --- a/python/samples/getting_started/workflow/orchestration/concurrent_agents.py +++ b/python/samples/getting_started/workflow/orchestration/concurrent_agents.py @@ -3,9 +3,8 @@ import asyncio from typing import Any -from agent_framework import ChatMessage +from agent_framework import ChatMessage, ConcurrentBuilder, WorkflowCompletedEvent from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ConcurrentBuilder, WorkflowCompletedEvent from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/orchestration/concurrent_custom_agent_executors.py b/python/samples/getting_started/workflow/orchestration/concurrent_custom_agent_executors.py index 067489dee2..e4883e6789 100644 --- a/python/samples/getting_started/workflow/orchestration/concurrent_custom_agent_executors.py +++ b/python/samples/getting_started/workflow/orchestration/concurrent_custom_agent_executors.py @@ -3,17 +3,18 @@ import asyncio from typing import Any -from agent_framework import ChatAgent, ChatMessage -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutorRequest, AgentExecutorResponse, + ChatAgent, + ChatMessage, ConcurrentBuilder, Executor, WorkflowCompletedEvent, WorkflowContext, handler, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/orchestration/concurrent_custom_aggregator.py b/python/samples/getting_started/workflow/orchestration/concurrent_custom_aggregator.py index 73f95388c6..02fa8c892a 100644 --- a/python/samples/getting_started/workflow/orchestration/concurrent_custom_aggregator.py +++ b/python/samples/getting_started/workflow/orchestration/concurrent_custom_aggregator.py @@ -3,9 +3,8 @@ import asyncio from typing import Any -from agent_framework import ChatMessage, Role +from agent_framework import ChatMessage, ConcurrentBuilder, Role, WorkflowCompletedEvent from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ConcurrentBuilder, WorkflowCompletedEvent from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/orchestration/magentic.py b/python/samples/getting_started/workflow/orchestration/magentic.py index e5fd8d4ba6..52be43a418 100644 --- a/python/samples/getting_started/workflow/orchestration/magentic.py +++ b/python/samples/getting_started/workflow/orchestration/magentic.py @@ -3,9 +3,9 @@ import asyncio import logging -from agent_framework import ChatAgent, HostedCodeInterpreterTool -from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient -from agent_framework_workflow import ( +from agent_framework import ( + ChatAgent, + HostedCodeInterpreterTool, MagenticAgentDeltaEvent, MagenticAgentMessageEvent, MagenticBuilder, @@ -15,6 +15,7 @@ from agent_framework_workflow import ( MagenticOrchestratorMessageEvent, WorkflowCompletedEvent, ) +from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) diff --git a/python/samples/getting_started/workflow/orchestration/magentic_human_plan_update.py b/python/samples/getting_started/workflow/orchestration/magentic_human_plan_update.py index 9e946c2d23..aec0aaa334 100644 --- a/python/samples/getting_started/workflow/orchestration/magentic_human_plan_update.py +++ b/python/samples/getting_started/workflow/orchestration/magentic_human_plan_update.py @@ -4,9 +4,9 @@ import asyncio import logging from typing import cast -from agent_framework import ChatAgent, HostedCodeInterpreterTool -from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient -from agent_framework_workflow import ( +from agent_framework import ( + ChatAgent, + HostedCodeInterpreterTool, MagenticAgentDeltaEvent, MagenticAgentMessageEvent, MagenticBuilder, @@ -20,6 +20,7 @@ from agent_framework_workflow import ( RequestInfoEvent, WorkflowCompletedEvent, ) +from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) diff --git a/python/samples/getting_started/workflow/orchestration/sequential_agents.py b/python/samples/getting_started/workflow/orchestration/sequential_agents.py index 88aa5ba37a..dfc7f154a5 100644 --- a/python/samples/getting_started/workflow/orchestration/sequential_agents.py +++ b/python/samples/getting_started/workflow/orchestration/sequential_agents.py @@ -3,9 +3,8 @@ import asyncio from typing import Any -from agent_framework import ChatMessage, Role +from agent_framework import ChatMessage, Role, SequentialBuilder, WorkflowCompletedEvent from agent_framework.azure import AzureChatClient -from agent_framework.workflow import SequentialBuilder, WorkflowCompletedEvent from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/orchestration/sequential_custom_executors.py b/python/samples/getting_started/workflow/orchestration/sequential_custom_executors.py index b78ea96626..889833f634 100644 --- a/python/samples/getting_started/workflow/orchestration/sequential_custom_executors.py +++ b/python/samples/getting_started/workflow/orchestration/sequential_custom_executors.py @@ -3,9 +3,16 @@ import asyncio from typing import Any -from agent_framework import ChatMessage, Role +from agent_framework import ( + ChatMessage, + Executor, + Role, + SequentialBuilder, + WorkflowCompletedEvent, + WorkflowContext, + handler, +) from agent_framework.azure import AzureChatClient -from agent_framework.workflow import Executor, SequentialBuilder, WorkflowCompletedEvent, WorkflowContext, handler from azure.identity import AzureCliCredential """ diff --git a/python/samples/getting_started/workflow/parallelism/fan_out_fan_in_edges.py b/python/samples/getting_started/workflow/parallelism/fan_out_fan_in_edges.py index ca96bb78d6..d28a2ca6a0 100644 --- a/python/samples/getting_started/workflow/parallelism/fan_out_fan_in_edges.py +++ b/python/samples/getting_started/workflow/parallelism/fan_out_fan_in_edges.py @@ -4,19 +4,20 @@ import asyncio from dataclasses import dataclass from typing import Any -from agent_framework import ChatMessage, Role # Core chat primitives to build LLM requests -from agent_framework.azure import AzureChatClient # Client wrapper for Azure OpenAI chat models -from agent_framework.workflow import ( +from agent_framework import ( # Core chat primitives to build LLM requests AgentExecutor, # Wraps an LLM agent for use inside a workflow AgentExecutorRequest, # The message bundle sent to an AgentExecutor AgentExecutorResponse, # The structured result returned by an AgentExecutor AgentRunEvent, # Tracing event for agent execution steps + ChatMessage, # Chat message structure Executor, # Base class for custom Python executors + Role, # Enum of chat roles (user, assistant, system) WorkflowBuilder, # Fluent builder for wiring the workflow graph WorkflowCompletedEvent, # Terminal event carrying the final result WorkflowContext, # Per run context and event bus handler, # Decorator to mark an Executor method as invokable ) +from agent_framework.azure import AzureChatClient # Client wrapper for Azure OpenAI chat models from azure.identity import AzureCliCredential # Uses your az CLI login for credentials """ diff --git a/python/samples/getting_started/workflow/parallelism/map_reduce_and_visualization.py b/python/samples/getting_started/workflow/parallelism/map_reduce_and_visualization.py index e551c44136..160b62ec6b 100644 --- a/python/samples/getting_started/workflow/parallelism/map_reduce_and_visualization.py +++ b/python/samples/getting_started/workflow/parallelism/map_reduce_and_visualization.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from typing import Any import aiofiles -from agent_framework.workflow import ( +from agent_framework import ( Executor, # Base class for custom workflow steps WorkflowBuilder, # Fluent graph builder for executors and edges WorkflowCompletedEvent, # Terminal event that carries final output @@ -296,7 +296,7 @@ async def main(): svg_file = viz.export(format="svg") print(f"SVG file saved to: {svg_file}") except ImportError: - print("Tip: Install 'viz' extra to export workflow visualization: pip install agent-framework-workflow[viz]") + print("Tip: Install 'viz' extra to export workflow visualization: pip install agent-framework[viz]") # Step 3: Open the text file and read its content. async with aiofiles.open(os.path.join(DIR, "resources", "long_text.txt"), "r") as f: diff --git a/python/samples/getting_started/workflow/state-management/shared_states_with_agents.py b/python/samples/getting_started/workflow/state-management/shared_states_with_agents.py index 45c71b516c..c5584bc0fc 100644 --- a/python/samples/getting_started/workflow/state-management/shared_states_with_agents.py +++ b/python/samples/getting_started/workflow/state-management/shared_states_with_agents.py @@ -6,16 +6,17 @@ from dataclasses import dataclass from typing import Any from uuid import uuid4 -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutorRequest, AgentExecutorResponse, + ChatMessage, + Role, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, executor, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential from pydantic import BaseModel diff --git a/python/samples/getting_started/workflow/visualization/concurrent_with_visualization.py b/python/samples/getting_started/workflow/visualization/concurrent_with_visualization.py index 28cdae27f4..dfc4c3b0fd 100644 --- a/python/samples/getting_started/workflow/visualization/concurrent_with_visualization.py +++ b/python/samples/getting_started/workflow/visualization/concurrent_with_visualization.py @@ -4,20 +4,21 @@ import asyncio from dataclasses import dataclass from typing import Any -from agent_framework import ChatMessage, Role -from agent_framework.azure import AzureChatClient -from agent_framework.workflow import ( +from agent_framework import ( AgentExecutor, AgentExecutorRequest, AgentExecutorResponse, AgentRunEvent, + ChatMessage, Executor, + Role, WorkflowBuilder, WorkflowCompletedEvent, WorkflowContext, WorkflowViz, handler, ) +from agent_framework.azure import AzureChatClient from azure.identity import AzureCliCredential """ @@ -31,7 +32,7 @@ What it does: Prerequisites: - Azure AI/ Azure OpenAI for `AzureChatClient` agents. - Authentication via `azure-identity` — uses `AzureCliCredential()` (run `az login`). -- For visualization export: `pip install agent-framework-workflow[viz]` and install GraphViz binaries. +- For visualization export: `pip install agent-framework[viz]` and install GraphViz binaries. """ @@ -161,7 +162,7 @@ async def main() -> None: svg_file = viz.export(format="svg") print(f"SVG file saved to: {svg_file}") except ImportError: - print("Tip: Install 'viz' extra to export workflow visualization: pip install agent-framework-workflow[viz]") + print("Tip: Install 'viz' extra to export workflow visualization: pip install agent-framework[viz]") # 3) Run with a single prompt completion: WorkflowCompletedEvent | None = None diff --git a/python/uv.lock b/python/uv.lock index 10ba3a3b4e..06a3ee6a41 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -30,19 +30,6 @@ members = [ "agent-framework-mem0", "agent-framework-project", "agent-framework-runtime", - "agent-framework-workflow", -] - -[[package]] -name = "accessible-pygments" -version = "0.0.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pygments", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, ] [[package]] @@ -50,6 +37,7 @@ name = "agent-framework" version = "0.1.0b1" source = { editable = "packages/main" } dependencies = [ + { name = "aiofiles", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "azure-monitor-opentelemetry", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "azure-monitor-opentelemetry-exporter", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "mcp", extra = ["ws"], marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -64,27 +52,42 @@ dependencies = [ ] [package.optional-dependencies] +all = [ + { name = "agent-framework-azure", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "agent-framework-foundry", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "agent-framework-mem0", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "agent-framework-runtime", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] azure = [ { name = "agent-framework-azure", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] foundry = [ { name = "agent-framework-foundry", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] +mem0 = [ + { name = "agent-framework-mem0", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] runtime = [ { name = "agent-framework-runtime", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -workflow = [ - { name = "agent-framework-workflow", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +viz = [ + { name = "graphviz", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] [package.metadata] requires-dist = [ + { name = "agent-framework-azure", marker = "extra == 'all'", editable = "packages/azure" }, { name = "agent-framework-azure", marker = "extra == 'azure'", editable = "packages/azure" }, + { name = "agent-framework-foundry", marker = "extra == 'all'", editable = "packages/foundry" }, { name = "agent-framework-foundry", marker = "extra == 'foundry'", editable = "packages/foundry" }, + { name = "agent-framework-mem0", marker = "extra == 'all'", editable = "packages/mem0" }, + { name = "agent-framework-mem0", marker = "extra == 'mem0'", editable = "packages/mem0" }, + { name = "agent-framework-runtime", marker = "extra == 'all'", editable = "packages/runtime" }, { name = "agent-framework-runtime", marker = "extra == 'runtime'", editable = "packages/runtime" }, - { name = "agent-framework-workflow", marker = "extra == 'workflow'", editable = "packages/workflow" }, + { name = "aiofiles", specifier = ">=24.1.0" }, { name = "azure-monitor-opentelemetry", specifier = ">=1.7.0" }, { name = "azure-monitor-opentelemetry-exporter", specifier = ">=1.0.0b41" }, + { name = "graphviz", marker = "extra == 'viz'", specifier = ">=0.20.0" }, { name = "mcp", extras = ["ws"], specifier = ">=1.13" }, { name = "openai", specifier = ">=1.99.0" }, { name = "opentelemetry-api", specifier = "~=1.24" }, @@ -95,7 +98,7 @@ requires-dist = [ { name = "pydantic-settings", specifier = ">=2.10.1" }, { name = "typing-extensions", specifier = ">=4.14.0" }, ] -provides-extras = ["azure", "foundry", "workflow", "runtime"] +provides-extras = ["azure", "foundry", "viz", "runtime", "mem0", "all"] [[package]] name = "agent-framework-azure" @@ -171,43 +174,30 @@ dependencies = [ { name = "agent-framework-copilotstudio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "agent-framework-foundry", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "agent-framework-mem0", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "agent-framework-workflow", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] [package.dev-dependencies] dev = [ - { name = "aiofiles", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "autodoc-pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "diskcache", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "markdown-it-py", extra = ["linkify"], marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "markdownify", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "mypy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "myst-nb", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "opentelemetry-instrumentation-openai", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "poethepoet", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pre-commit", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pydata-sphinx-theme", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pygments", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pyright", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest-asyncio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest-cov", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest-timeout", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pytest-xdist", extra = ["psutil"], marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "redis", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "rich", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "ruff", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinx-autobuild", version = "2024.10.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx-autobuild", version = "2025.8.25", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinx-copybutton", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx-design", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinxext-rediraffe", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "tomli", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "tomli-w", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "uv", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] +docs = [ + { name = "debugpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pip", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "py2docfx", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] [package.metadata] requires-dist = [ @@ -216,41 +206,30 @@ requires-dist = [ { name = "agent-framework-copilotstudio", editable = "packages/copilotstudio" }, { name = "agent-framework-foundry", editable = "packages/foundry" }, { name = "agent-framework-mem0", editable = "packages/mem0" }, - { name = "agent-framework-workflow", editable = "packages/workflow" }, ] [package.metadata.requires-dev] dev = [ - { name = "aiofiles", specifier = ">=24.1.0" }, - { name = "autodoc-pydantic", specifier = ">=2" }, - { name = "diskcache" }, - { name = "markdown-it-py", extras = ["linkify"] }, - { name = "markdownify" }, { name = "mypy", specifier = ">=1.16.1" }, - { name = "myst-nb", specifier = "==1.1.2" }, - { name = "opentelemetry-instrumentation-openai" }, { name = "poethepoet", specifier = ">=0.36.0" }, { name = "pre-commit", specifier = ">=3.7" }, - { name = "pydata-sphinx-theme", specifier = "==0.16.1" }, - { name = "pygments" }, { name = "pyright", specifier = ">=1.1.402" }, { name = "pytest", specifier = ">=8.4.1" }, { name = "pytest-asyncio", specifier = ">=1.0.0" }, { name = "pytest-cov", specifier = ">=6.2.1" }, { name = "pytest-timeout", specifier = ">=2.3.1" }, { name = "pytest-xdist", extras = ["psutil"], specifier = ">=3.8.0" }, - { name = "redis" }, { name = "rich" }, { name = "ruff", specifier = ">=0.11.8" }, - { name = "sphinx" }, - { name = "sphinx-autobuild" }, - { name = "sphinx-copybutton" }, - { name = "sphinx-design" }, - { name = "sphinxext-rediraffe" }, { name = "tomli" }, { name = "tomli-w" }, { name = "uv", specifier = ">=0.8.2,<0.9.0" }, ] +docs = [ + { name = "debugpy", specifier = ">=1.8.16" }, + { name = "pip" }, + { name = "py2docfx", specifier = ">=0.1.20" }, +] [[package]] name = "agent-framework-runtime" @@ -263,26 +242,6 @@ dependencies = [ [package.metadata] requires-dist = [{ name = "agent-framework", editable = "packages/main" }] -[[package]] -name = "agent-framework-workflow" -version = "0.1.0b1" -source = { editable = "packages/workflow" } -dependencies = [ - { name = "agent-framework", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] - -[package.optional-dependencies] -viz = [ - { name = "graphviz", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] - -[package.metadata] -requires-dist = [ - { name = "agent-framework", editable = "packages/main" }, - { name = "graphviz", marker = "extra == 'viz'", specifier = ">=0.20.0" }, -] -provides-extras = ["viz"] - [[package]] name = "aiofiles" version = "24.1.0" @@ -402,11 +361,11 @@ wheels = [ [[package]] name = "alabaster" -version = "1.0.0" +version = "0.7.16" 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, upload-time = "2024-07-26T18:15:03.762Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776, upload-time = "2024-01-10T00:56:10.189Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511, upload-time = "2024-01-10T00:56:08.388Z" }, ] [[package]] @@ -433,15 +392,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, ] -[[package]] -name = "appnope" -version = "0.1.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, -] - [[package]] name = "asgiref" version = "3.9.1" @@ -454,15 +404,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7c/3c/0464dcada90d5da0e71018c04a140ad6349558afb30b3051b4264cc5b965/asgiref-3.9.1-py3-none-any.whl", hash = "sha256:f3bba7092a48005b5f5bacd747d36ee4a5a61f4a269a6df590b43144355ebd2c", size = 23790, upload-time = "2025-07-08T09:07:41.548Z" }, ] -[[package]] -name = "asttokens" -version = "3.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, -] - [[package]] name = "async-timeout" version = "5.0.1" @@ -481,20 +422,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] -[[package]] -name = "autodoc-pydantic" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pydantic-settings", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/df/87120e2195f08d760bc5cf8a31cfa2381a6887517aa89453b23f1ae3354f/autodoc_pydantic-2.2.0-py3-none-any.whl", hash = "sha256:8c6a36fbf6ed2700ea9c6d21ea76ad541b621fbdf16b5a80ee04673548af4d95", size = 34001, upload-time = "2024-04-27T10:57:00.542Z" }, -] - [[package]] name = "azure-ai-agents" version = "1.2.0b4" @@ -504,9 +431,9 @@ dependencies = [ { name = "isodate", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/db/cdf0ab3cf642ef766d193fadfee4cc8e70867a051c800f9e1091feb76337/azure_ai_agents-1.2.0b4.tar.gz", hash = "sha256:3da41c0f17282dd76bff7d370c714ef2d17140a119a1eb88d8653311835bbe85", size = 383620 } +sdist = { url = "https://files.pythonhosted.org/packages/30/db/cdf0ab3cf642ef766d193fadfee4cc8e70867a051c800f9e1091feb76337/azure_ai_agents-1.2.0b4.tar.gz", hash = "sha256:3da41c0f17282dd76bff7d370c714ef2d17140a119a1eb88d8653311835bbe85", size = 383620, upload-time = "2025-09-13T02:04:47.301Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/08/571e60c5f76c3ba20e6a99de636335e2480941816344dfad971a2e362c12/azure_ai_agents-1.2.0b4-py3-none-any.whl", hash = "sha256:8cfc4cd19d7d2087858148eba8b9b424a5d30fafbda87ca2d12ea5a066bec051", size = 214705 }, + { url = "https://files.pythonhosted.org/packages/3c/08/571e60c5f76c3ba20e6a99de636335e2480941816344dfad971a2e362c12/azure_ai_agents-1.2.0b4-py3-none-any.whl", hash = "sha256:8cfc4cd19d7d2087858148eba8b9b424a5d30fafbda87ca2d12ea5a066bec051", size = 214705, upload-time = "2025-09-13T02:04:49.171Z" }, ] [[package]] @@ -520,9 +447,9 @@ dependencies = [ { name = "isodate", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/16/7a7c978a79f545d62ab4327cd704c22b5d7ade8dcfb58ea193257aebabf9/azure_ai_projects-1.1.0b4.tar.gz", hash = "sha256:39e2f1396270b375069c2d9c82ccfe91c11384eca9f61d59adbc12fb6d6a32ca", size = 147568 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/16/7a7c978a79f545d62ab4327cd704c22b5d7ade8dcfb58ea193257aebabf9/azure_ai_projects-1.1.0b4.tar.gz", hash = "sha256:39e2f1396270b375069c2d9c82ccfe91c11384eca9f61d59adbc12fb6d6a32ca", size = 147568, upload-time = "2025-09-12T17:35:08.52Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/10/8b7bd070e3cc804343dab124ce66a3b7999a72d5be0e49232cbcd1d36e18/azure_ai_projects-1.1.0b4-py3-none-any.whl", hash = "sha256:d8aab84fd7cd7c5937e78141e37ca4473dc5ed6cce2c0490c634418abe14afea", size = 126670 }, + { url = "https://files.pythonhosted.org/packages/db/10/8b7bd070e3cc804343dab124ce66a3b7999a72d5be0e49232cbcd1d36e18/azure_ai_projects-1.1.0b4-py3-none-any.whl", hash = "sha256:d8aab84fd7cd7c5937e78141e37ca4473dc5ed6cce2c0490c634418abe14afea", size = 126670, upload-time = "2025-09-12T17:35:10.039Z" }, ] [[package]] @@ -534,9 +461,9 @@ dependencies = [ { name = "six", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/15/6b/2653adc0f33adba8f11b1903701e6b1c10d34ce5d8e25dfa13a422f832b0/azure_core-1.35.1.tar.gz", hash = "sha256:435d05d6df0fff2f73fb3c15493bb4721ede14203f1ff1382aa6b6b2bdd7e562", size = 345290 } +sdist = { url = "https://files.pythonhosted.org/packages/15/6b/2653adc0f33adba8f11b1903701e6b1c10d34ce5d8e25dfa13a422f832b0/azure_core-1.35.1.tar.gz", hash = "sha256:435d05d6df0fff2f73fb3c15493bb4721ede14203f1ff1382aa6b6b2bdd7e562", size = 345290, upload-time = "2025-09-11T22:58:04.481Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/52/805980aa1ba18282077c484dba634ef0ede1e84eec8be9c92b2e162d0ed6/azure_core-1.35.1-py3-none-any.whl", hash = "sha256:12da0c9e08e48e198f9158b56ddbe33b421477e1dc98c2e1c8f9e254d92c468b", size = 211800 }, + { url = "https://files.pythonhosted.org/packages/27/52/805980aa1ba18282077c484dba634ef0ede1e84eec8be9c92b2e162d0ed6/azure_core-1.35.1-py3-none-any.whl", hash = "sha256:12da0c9e08e48e198f9158b56ddbe33b421477e1dc98c2e1c8f9e254d92c468b", size = 211800, upload-time = "2025-09-11T22:58:06.281Z" }, ] [[package]] @@ -563,9 +490,9 @@ dependencies = [ { name = "msal-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/9e/4c9682a286c3c89e437579bd9f64f311020e5125c1321fd3a653166b5716/azure_identity-1.25.0.tar.gz", hash = "sha256:4177df34d684cddc026e6cf684e1abb57767aa9d84e7f2129b080ec45eee7733", size = 278507 } +sdist = { url = "https://files.pythonhosted.org/packages/4e/9e/4c9682a286c3c89e437579bd9f64f311020e5125c1321fd3a653166b5716/azure_identity-1.25.0.tar.gz", hash = "sha256:4177df34d684cddc026e6cf684e1abb57767aa9d84e7f2129b080ec45eee7733", size = 278507, upload-time = "2025-09-12T01:30:04.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/54/81683b6756676a22e037b209695b08008258e603f7e47c56834029c5922a/azure_identity-1.25.0-py3-none-any.whl", hash = "sha256:becaec086bbdf8d1a6aa4fb080c2772a0f824a97d50c29637ec8cc4933f1e82d", size = 190861 }, + { url = "https://files.pythonhosted.org/packages/75/54/81683b6756676a22e037b209695b08008258e603f7e47c56834029c5922a/azure_identity-1.25.0-py3-none-any.whl", hash = "sha256:becaec086bbdf8d1a6aa4fb080c2772a0f824a97d50c29637ec8cc4933f1e82d", size = 190861, upload-time = "2025-09-12T01:30:06.474Z" }, ] [[package]] @@ -651,19 +578,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, ] -[[package]] -name = "beautifulsoup4" -version = "4.13.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "soupsieve", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/85/2e/3e5079847e653b1f6dc647aa24549d68c6addb4c595cc0d902d1b19308ad/beautifulsoup4-4.13.5.tar.gz", hash = "sha256:5e70131382930e7c3de33450a2f54a63d5e4b19386eab43a5b34d594268f3695", size = 622954, upload-time = "2025-08-24T14:06:13.168Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/eb/f4151e0c7377a6e08a38108609ba5cede57986802757848688aeedd1b9e8/beautifulsoup4-4.13.5-py3-none-any.whl", hash = "sha256:642085eaa22233aceadff9c69651bc51e8bf3f874fb6d7104ece2beb24b47c4a", size = 105113, upload-time = "2025-08-24T14:06:14.884Z" }, -] - [[package]] name = "certifi" version = "2025.8.3" @@ -849,15 +763,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "comm" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, -] - [[package]] name = "coverage" version = "7.10.6" @@ -1020,24 +925,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/57/ecc9ae29fa5b2d90107cd1d9bf8ed19aacb74b2264d986ae9d44fe9bdf87/debugpy-1.8.16-py2.py3-none-any.whl", hash = "sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e", size = 5287700, upload-time = "2025-08-06T18:00:42.333Z" }, ] -[[package]] -name = "decorator" -version = "5.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, -] - -[[package]] -name = "diskcache" -version = "5.6.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/21/1c1ffc1a039ddcc459db43cc108658f32c57d271d7289a2794e401d0fdb6/diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc", size = 67916, upload-time = "2023-08-31T06:12:00.316Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/27/4570e78fc0bf5ea0ca45eb1de3818a23787af9b390c0b0a0033a1b8236f9/diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19", size = 45550, upload-time = "2023-08-31T06:11:58.822Z" }, -] - [[package]] name = "distlib" version = "0.4.0" @@ -1058,11 +945,11 @@ wheels = [ [[package]] name = "docutils" -version = "0.21.2" +version = "0.19" 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, upload-time = "2024-04-23T18:57:18.24Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/330ea8d383eb2ce973df34d1239b3b21e91cd8c865d21ff82902d952f91f/docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", size = 2056383, upload-time = "2022-07-05T20:17:31.045Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, + { url = "https://files.pythonhosted.org/packages/93/69/e391bd51bc08ed9141ecd899a0ddb61ab6465309f1eb470905c0c8868081/docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc", size = 570472, upload-time = "2022-07-05T20:17:26.388Z" }, ] [[package]] @@ -1086,24 +973,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612, upload-time = "2024-04-08T09:04:17.414Z" }, ] -[[package]] -name = "executing" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, -] - -[[package]] -name = "fastjsonschema" -version = "2.21.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, -] - [[package]] name = "filelock" version = "3.19.1" @@ -1290,50 +1159,53 @@ wheels = [ [[package]] name = "grpcio" -version = "1.74.0" +version = "1.75.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/38/b4/35feb8f7cab7239c5b94bd2db71abb3d6adb5f335ad8f131abb6060840b6/grpcio-1.74.0.tar.gz", hash = "sha256:80d1f4fbb35b0742d3e3d3bb654b7381cd5f015f8497279a1e9c21ba623e01b1", size = 12756048, upload-time = "2025-07-24T18:54:23.039Z" } +dependencies = [ + { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/88/fe2844eefd3d2188bc0d7a2768c6375b46dfd96469ea52d8aeee8587d7e0/grpcio-1.75.0.tar.gz", hash = "sha256:b989e8b09489478c2d19fecc744a298930f40d8b27c3638afbfe84d22f36ce4e", size = 12722485, upload-time = "2025-09-16T09:20:21.731Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/54/68e51a90797ad7afc5b0a7881426c337f6a9168ebab73c3210b76aa7c90d/grpcio-1.74.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:85bd5cdf4ed7b2d6438871adf6afff9af7096486fcf51818a81b77ef4dd30907", size = 5481935, upload-time = "2025-07-24T18:52:43.756Z" }, - { url = "https://files.pythonhosted.org/packages/32/2a/af817c7e9843929e93e54d09c9aee2555c2e8d81b93102a9426b36e91833/grpcio-1.74.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:68c8ebcca945efff9d86d8d6d7bfb0841cf0071024417e2d7f45c5e46b5b08eb", size = 10986796, upload-time = "2025-07-24T18:52:47.219Z" }, - { url = "https://files.pythonhosted.org/packages/d5/94/d67756638d7bb07750b07d0826c68e414124574b53840ba1ff777abcd388/grpcio-1.74.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:e154d230dc1bbbd78ad2fdc3039fa50ad7ffcf438e4eb2fa30bce223a70c7486", size = 5983663, upload-time = "2025-07-24T18:52:49.463Z" }, - { url = "https://files.pythonhosted.org/packages/35/f5/c5e4853bf42148fea8532d49e919426585b73eafcf379a712934652a8de9/grpcio-1.74.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8978003816c7b9eabe217f88c78bc26adc8f9304bf6a594b02e5a49b2ef9c11", size = 6653765, upload-time = "2025-07-24T18:52:51.094Z" }, - { url = "https://files.pythonhosted.org/packages/fd/75/a1991dd64b331d199935e096cc9daa3415ee5ccbe9f909aa48eded7bba34/grpcio-1.74.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3d7bd6e3929fd2ea7fbc3f562e4987229ead70c9ae5f01501a46701e08f1ad9", size = 6215172, upload-time = "2025-07-24T18:52:53.282Z" }, - { url = "https://files.pythonhosted.org/packages/01/a4/7cef3dbb3b073d0ce34fd507efc44ac4c9442a0ef9fba4fb3f5c551efef5/grpcio-1.74.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:136b53c91ac1d02c8c24201bfdeb56f8b3ac3278668cbb8e0ba49c88069e1bdc", size = 6329142, upload-time = "2025-07-24T18:52:54.927Z" }, - { url = "https://files.pythonhosted.org/packages/bf/d3/587920f882b46e835ad96014087054655312400e2f1f1446419e5179a383/grpcio-1.74.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fe0f540750a13fd8e5da4b3eaba91a785eea8dca5ccd2bc2ffe978caa403090e", size = 7018632, upload-time = "2025-07-24T18:52:56.523Z" }, - { url = "https://files.pythonhosted.org/packages/1f/95/c70a3b15a0bc83334b507e3d2ae20ee8fa38d419b8758a4d838f5c2a7d32/grpcio-1.74.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4e4181bfc24413d1e3a37a0b7889bea68d973d4b45dd2bc68bb766c140718f82", size = 6509641, upload-time = "2025-07-24T18:52:58.495Z" }, - { url = "https://files.pythonhosted.org/packages/4b/06/2e7042d06247d668ae69ea6998eca33f475fd4e2855f94dcb2aa5daef334/grpcio-1.74.0-cp310-cp310-win32.whl", hash = "sha256:1733969040989f7acc3d94c22f55b4a9501a30f6aaacdbccfaba0a3ffb255ab7", size = 3817478, upload-time = "2025-07-24T18:53:00.128Z" }, - { url = "https://files.pythonhosted.org/packages/93/20/e02b9dcca3ee91124060b65bbf5b8e1af80b3b76a30f694b44b964ab4d71/grpcio-1.74.0-cp310-cp310-win_amd64.whl", hash = "sha256:9e912d3c993a29df6c627459af58975b2e5c897d93287939b9d5065f000249b5", size = 4493971, upload-time = "2025-07-24T18:53:02.068Z" }, - { url = "https://files.pythonhosted.org/packages/e7/77/b2f06db9f240a5abeddd23a0e49eae2b6ac54d85f0e5267784ce02269c3b/grpcio-1.74.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:69e1a8180868a2576f02356565f16635b99088da7df3d45aaa7e24e73a054e31", size = 5487368, upload-time = "2025-07-24T18:53:03.548Z" }, - { url = "https://files.pythonhosted.org/packages/48/99/0ac8678a819c28d9a370a663007581744a9f2a844e32f0fa95e1ddda5b9e/grpcio-1.74.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8efe72fde5500f47aca1ef59495cb59c885afe04ac89dd11d810f2de87d935d4", size = 10999804, upload-time = "2025-07-24T18:53:05.095Z" }, - { url = "https://files.pythonhosted.org/packages/45/c6/a2d586300d9e14ad72e8dc211c7aecb45fe9846a51e558c5bca0c9102c7f/grpcio-1.74.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a8f0302f9ac4e9923f98d8e243939a6fb627cd048f5cd38595c97e38020dffce", size = 5987667, upload-time = "2025-07-24T18:53:07.157Z" }, - { url = "https://files.pythonhosted.org/packages/c9/57/5f338bf56a7f22584e68d669632e521f0de460bb3749d54533fc3d0fca4f/grpcio-1.74.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f609a39f62a6f6f05c7512746798282546358a37ea93c1fcbadf8b2fed162e3", size = 6655612, upload-time = "2025-07-24T18:53:09.244Z" }, - { url = "https://files.pythonhosted.org/packages/82/ea/a4820c4c44c8b35b1903a6c72a5bdccec92d0840cf5c858c498c66786ba5/grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c98e0b7434a7fa4e3e63f250456eaef52499fba5ae661c58cc5b5477d11e7182", size = 6219544, upload-time = "2025-07-24T18:53:11.221Z" }, - { url = "https://files.pythonhosted.org/packages/a4/17/0537630a921365928f5abb6d14c79ba4dcb3e662e0dbeede8af4138d9dcf/grpcio-1.74.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:662456c4513e298db6d7bd9c3b8df6f75f8752f0ba01fb653e252ed4a59b5a5d", size = 6334863, upload-time = "2025-07-24T18:53:12.925Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a6/85ca6cb9af3f13e1320d0a806658dca432ff88149d5972df1f7b51e87127/grpcio-1.74.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3d14e3c4d65e19d8430a4e28ceb71ace4728776fd6c3ce34016947474479683f", size = 7019320, upload-time = "2025-07-24T18:53:15.002Z" }, - { url = "https://files.pythonhosted.org/packages/4f/a7/fe2beab970a1e25d2eff108b3cf4f7d9a53c185106377a3d1989216eba45/grpcio-1.74.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bf949792cee20d2078323a9b02bacbbae002b9e3b9e2433f2741c15bdeba1c4", size = 6514228, upload-time = "2025-07-24T18:53:16.999Z" }, - { url = "https://files.pythonhosted.org/packages/6a/c2/2f9c945c8a248cebc3ccda1b7a1bf1775b9d7d59e444dbb18c0014e23da6/grpcio-1.74.0-cp311-cp311-win32.whl", hash = "sha256:55b453812fa7c7ce2f5c88be3018fb4a490519b6ce80788d5913f3f9d7da8c7b", size = 3817216, upload-time = "2025-07-24T18:53:20.564Z" }, - { url = "https://files.pythonhosted.org/packages/ff/d1/a9cf9c94b55becda2199299a12b9feef0c79946b0d9d34c989de6d12d05d/grpcio-1.74.0-cp311-cp311-win_amd64.whl", hash = "sha256:86ad489db097141a907c559988c29718719aa3e13370d40e20506f11b4de0d11", size = 4495380, upload-time = "2025-07-24T18:53:22.058Z" }, - { url = "https://files.pythonhosted.org/packages/4c/5d/e504d5d5c4469823504f65687d6c8fb97b7f7bf0b34873b7598f1df24630/grpcio-1.74.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8533e6e9c5bd630ca98062e3a1326249e6ada07d05acf191a77bc33f8948f3d8", size = 5445551, upload-time = "2025-07-24T18:53:23.641Z" }, - { url = "https://files.pythonhosted.org/packages/43/01/730e37056f96f2f6ce9f17999af1556df62ee8dab7fa48bceeaab5fd3008/grpcio-1.74.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:2918948864fec2a11721d91568effffbe0a02b23ecd57f281391d986847982f6", size = 10979810, upload-time = "2025-07-24T18:53:25.349Z" }, - { url = "https://files.pythonhosted.org/packages/79/3d/09fd100473ea5c47083889ca47ffd356576173ec134312f6aa0e13111dee/grpcio-1.74.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:60d2d48b0580e70d2e1954d0d19fa3c2e60dd7cbed826aca104fff518310d1c5", size = 5941946, upload-time = "2025-07-24T18:53:27.387Z" }, - { url = "https://files.pythonhosted.org/packages/8a/99/12d2cca0a63c874c6d3d195629dcd85cdf5d6f98a30d8db44271f8a97b93/grpcio-1.74.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3601274bc0523f6dc07666c0e01682c94472402ac2fd1226fd96e079863bfa49", size = 6621763, upload-time = "2025-07-24T18:53:29.193Z" }, - { url = "https://files.pythonhosted.org/packages/9d/2c/930b0e7a2f1029bbc193443c7bc4dc2a46fedb0203c8793dcd97081f1520/grpcio-1.74.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:176d60a5168d7948539def20b2a3adcce67d72454d9ae05969a2e73f3a0feee7", size = 6180664, upload-time = "2025-07-24T18:53:30.823Z" }, - { url = "https://files.pythonhosted.org/packages/db/d5/ff8a2442180ad0867717e670f5ec42bfd8d38b92158ad6bcd864e6d4b1ed/grpcio-1.74.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e759f9e8bc908aaae0412642afe5416c9f983a80499448fcc7fab8692ae044c3", size = 6301083, upload-time = "2025-07-24T18:53:32.454Z" }, - { url = "https://files.pythonhosted.org/packages/b0/ba/b361d390451a37ca118e4ec7dccec690422e05bc85fba2ec72b06cefec9f/grpcio-1.74.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9e7c4389771855a92934b2846bd807fc25a3dfa820fd912fe6bd8136026b2707", size = 6994132, upload-time = "2025-07-24T18:53:34.506Z" }, - { url = "https://files.pythonhosted.org/packages/3b/0c/3a5fa47d2437a44ced74141795ac0251bbddeae74bf81df3447edd767d27/grpcio-1.74.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cce634b10aeab37010449124814b05a62fb5f18928ca878f1bf4750d1f0c815b", size = 6489616, upload-time = "2025-07-24T18:53:36.217Z" }, - { url = "https://files.pythonhosted.org/packages/ae/95/ab64703b436d99dc5217228babc76047d60e9ad14df129e307b5fec81fd0/grpcio-1.74.0-cp312-cp312-win32.whl", hash = "sha256:885912559974df35d92219e2dc98f51a16a48395f37b92865ad45186f294096c", size = 3807083, upload-time = "2025-07-24T18:53:37.911Z" }, - { url = "https://files.pythonhosted.org/packages/84/59/900aa2445891fc47a33f7d2f76e00ca5d6ae6584b20d19af9c06fa09bf9a/grpcio-1.74.0-cp312-cp312-win_amd64.whl", hash = "sha256:42f8fee287427b94be63d916c90399ed310ed10aadbf9e2e5538b3e497d269bc", size = 4490123, upload-time = "2025-07-24T18:53:39.528Z" }, - { url = "https://files.pythonhosted.org/packages/d4/d8/1004a5f468715221450e66b051c839c2ce9a985aa3ee427422061fcbb6aa/grpcio-1.74.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:2bc2d7d8d184e2362b53905cb1708c84cb16354771c04b490485fa07ce3a1d89", size = 5449488, upload-time = "2025-07-24T18:53:41.174Z" }, - { url = "https://files.pythonhosted.org/packages/94/0e/33731a03f63740d7743dced423846c831d8e6da808fcd02821a4416df7fa/grpcio-1.74.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c14e803037e572c177ba54a3e090d6eb12efd795d49327c5ee2b3bddb836bf01", size = 10974059, upload-time = "2025-07-24T18:53:43.066Z" }, - { url = "https://files.pythonhosted.org/packages/0d/c6/3d2c14d87771a421205bdca991467cfe473ee4c6a1231c1ede5248c62ab8/grpcio-1.74.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f6ec94f0e50eb8fa1744a731088b966427575e40c2944a980049798b127a687e", size = 5945647, upload-time = "2025-07-24T18:53:45.269Z" }, - { url = "https://files.pythonhosted.org/packages/c5/83/5a354c8aaff58594eef7fffebae41a0f8995a6258bbc6809b800c33d4c13/grpcio-1.74.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:566b9395b90cc3d0d0c6404bc8572c7c18786ede549cdb540ae27b58afe0fb91", size = 6626101, upload-time = "2025-07-24T18:53:47.015Z" }, - { url = "https://files.pythonhosted.org/packages/3f/ca/4fdc7bf59bf6994aa45cbd4ef1055cd65e2884de6113dbd49f75498ddb08/grpcio-1.74.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1ea6176d7dfd5b941ea01c2ec34de9531ba494d541fe2057c904e601879f249", size = 6182562, upload-time = "2025-07-24T18:53:48.967Z" }, - { url = "https://files.pythonhosted.org/packages/fd/48/2869e5b2c1922583686f7ae674937986807c2f676d08be70d0a541316270/grpcio-1.74.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:64229c1e9cea079420527fa8ac45d80fc1e8d3f94deaa35643c381fa8d98f362", size = 6303425, upload-time = "2025-07-24T18:53:50.847Z" }, - { url = "https://files.pythonhosted.org/packages/a6/0e/bac93147b9a164f759497bc6913e74af1cb632c733c7af62c0336782bd38/grpcio-1.74.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:0f87bddd6e27fc776aacf7ebfec367b6d49cad0455123951e4488ea99d9b9b8f", size = 6996533, upload-time = "2025-07-24T18:53:52.747Z" }, - { url = "https://files.pythonhosted.org/packages/84/35/9f6b2503c1fd86d068b46818bbd7329db26a87cdd8c01e0d1a9abea1104c/grpcio-1.74.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3b03d8f2a07f0fea8c8f74deb59f8352b770e3900d143b3d1475effcb08eec20", size = 6491489, upload-time = "2025-07-24T18:53:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/75/33/a04e99be2a82c4cbc4039eb3a76f6c3632932b9d5d295221389d10ac9ca7/grpcio-1.74.0-cp313-cp313-win32.whl", hash = "sha256:b6a73b2ba83e663b2480a90b82fdae6a7aa6427f62bf43b29912c0cfd1aa2bfa", size = 3805811, upload-time = "2025-07-24T18:53:56.798Z" }, - { url = "https://files.pythonhosted.org/packages/34/80/de3eb55eb581815342d097214bed4c59e806b05f1b3110df03b2280d6dfd/grpcio-1.74.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd3c71aeee838299c5887230b8a1822795325ddfea635edd82954c1eaa831e24", size = 4489214, upload-time = "2025-07-24T18:53:59.771Z" }, + { url = "https://files.pythonhosted.org/packages/23/90/91f780f6cb8b2aa1bc8b8f8561a4e9d3bfe5dea10a4532843f2b044e18ac/grpcio-1.75.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:1ec9cbaec18d9597c718b1ed452e61748ac0b36ba350d558f9ded1a94cc15ec7", size = 5696373, upload-time = "2025-09-16T09:18:07.971Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c6/eaf9065ff15d0994e1674e71e1ca9542ee47f832b4df0fde1b35e5641fa1/grpcio-1.75.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:7ee5ee42bfae8238b66a275f9ebcf6f295724375f2fa6f3b52188008b6380faf", size = 11465905, upload-time = "2025-09-16T09:18:12.383Z" }, + { url = "https://files.pythonhosted.org/packages/8a/21/ae33e514cb7c3f936b378d1c7aab6d8e986814b3489500c5cc860c48ce88/grpcio-1.75.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9146e40378f551eed66c887332afc807fcce593c43c698e21266a4227d4e20d2", size = 6282149, upload-time = "2025-09-16T09:18:15.427Z" }, + { url = "https://files.pythonhosted.org/packages/d5/46/dff6344e6f3e81707bc87bba796592036606aca04b6e9b79ceec51902b80/grpcio-1.75.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0c40f368541945bb664857ecd7400acb901053a1abbcf9f7896361b2cfa66798", size = 6940277, upload-time = "2025-09-16T09:18:17.564Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5f/e52cb2c16e097d950c36e7bb2ef46a3b2e4c7ae6b37acb57d88538182b85/grpcio-1.75.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:50a6e43a9adc6938e2a16c9d9f8a2da9dd557ddd9284b73b07bd03d0e098d1e9", size = 6460422, upload-time = "2025-09-16T09:18:19.657Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/527533f0bd9cace7cd800b7dae903e273cc987fc472a398a4bb6747fec9b/grpcio-1.75.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dce15597ca11913b78e1203c042d5723e3ea7f59e7095a1abd0621be0e05b895", size = 7089969, upload-time = "2025-09-16T09:18:21.73Z" }, + { url = "https://files.pythonhosted.org/packages/88/4f/1d448820bc88a2be7045aac817a59ba06870e1ebad7ed19525af7ac079e7/grpcio-1.75.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:851194eec47755101962da423f575ea223c9dd7f487828fe5693920e8745227e", size = 8033548, upload-time = "2025-09-16T09:18:23.819Z" }, + { url = "https://files.pythonhosted.org/packages/37/00/19e87ab12c8b0d73a252eef48664030de198514a4e30bdf337fa58bcd4dd/grpcio-1.75.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ca123db0813eef80625a4242a0c37563cb30a3edddebe5ee65373854cf187215", size = 7487161, upload-time = "2025-09-16T09:18:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/37/d0/f7b9deaa6ccca9997fa70b4e143cf976eaec9476ecf4d05f7440ac400635/grpcio-1.75.0-cp310-cp310-win32.whl", hash = "sha256:222b0851e20c04900c63f60153503e918b08a5a0fad8198401c0b1be13c6815b", size = 3946254, upload-time = "2025-09-16T09:18:28.42Z" }, + { url = "https://files.pythonhosted.org/packages/6d/42/8d04744c7dc720cc9805a27f879cbf7043bb5c78dce972f6afb8613860de/grpcio-1.75.0-cp310-cp310-win_amd64.whl", hash = "sha256:bb58e38a50baed9b21492c4b3f3263462e4e37270b7ea152fc10124b4bd1c318", size = 4640072, upload-time = "2025-09-16T09:18:30.426Z" }, + { url = "https://files.pythonhosted.org/packages/95/b7/a6f42596fc367656970f5811e5d2d9912ca937aa90621d5468a11680ef47/grpcio-1.75.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:7f89d6d0cd43170a80ebb4605cad54c7d462d21dc054f47688912e8bf08164af", size = 5699769, upload-time = "2025-09-16T09:18:32.536Z" }, + { url = "https://files.pythonhosted.org/packages/c2/42/284c463a311cd2c5f804fd4fdbd418805460bd5d702359148dd062c1685d/grpcio-1.75.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:cb6c5b075c2d092f81138646a755f0dad94e4622300ebef089f94e6308155d82", size = 11480362, upload-time = "2025-09-16T09:18:35.562Z" }, + { url = "https://files.pythonhosted.org/packages/0b/10/60d54d5a03062c3ae91bddb6e3acefe71264307a419885f453526d9203ff/grpcio-1.75.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:494dcbade5606128cb9f530ce00331a90ecf5e7c5b243d373aebdb18e503c346", size = 6284753, upload-time = "2025-09-16T09:18:38.055Z" }, + { url = "https://files.pythonhosted.org/packages/cf/af/381a4bfb04de5e2527819452583e694df075c7a931e9bf1b2a603b593ab2/grpcio-1.75.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:050760fd29c8508844a720f06c5827bb00de8f5e02f58587eb21a4444ad706e5", size = 6944103, upload-time = "2025-09-16T09:18:40.844Z" }, + { url = "https://files.pythonhosted.org/packages/16/18/c80dd7e1828bd6700ce242c1616871927eef933ed0c2cee5c636a880e47b/grpcio-1.75.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:266fa6209b68a537b2728bb2552f970e7e78c77fe43c6e9cbbe1f476e9e5c35f", size = 6464036, upload-time = "2025-09-16T09:18:43.351Z" }, + { url = "https://files.pythonhosted.org/packages/79/3f/78520c7ed9ccea16d402530bc87958bbeb48c42a2ec8032738a7864d38f8/grpcio-1.75.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:06d22e1d8645e37bc110f4c589cb22c283fd3de76523065f821d6e81de33f5d4", size = 7097455, upload-time = "2025-09-16T09:18:45.465Z" }, + { url = "https://files.pythonhosted.org/packages/ad/69/3cebe4901a865eb07aefc3ee03a02a632e152e9198dadf482a7faf926f31/grpcio-1.75.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9880c323595d851292785966cadb6c708100b34b163cab114e3933f5773cba2d", size = 8037203, upload-time = "2025-09-16T09:18:47.878Z" }, + { url = "https://files.pythonhosted.org/packages/04/ed/1e483d1eba5032642c10caf28acf07ca8de0508244648947764956db346a/grpcio-1.75.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:55a2d5ae79cd0f68783fb6ec95509be23746e3c239290b2ee69c69a38daa961a", size = 7492085, upload-time = "2025-09-16T09:18:50.907Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/6ef676aa7dbd9578dfca990bb44d41a49a1e36344ca7d79de6b59733ba96/grpcio-1.75.0-cp311-cp311-win32.whl", hash = "sha256:352dbdf25495eef584c8de809db280582093bc3961d95a9d78f0dfb7274023a2", size = 3944697, upload-time = "2025-09-16T09:18:53.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/83/b753373098b81ec5cb01f71c21dfd7aafb5eb48a1566d503e9fd3c1254fe/grpcio-1.75.0-cp311-cp311-win_amd64.whl", hash = "sha256:678b649171f229fb16bda1a2473e820330aa3002500c4f9fd3a74b786578e90f", size = 4642235, upload-time = "2025-09-16T09:18:56.095Z" }, + { url = "https://files.pythonhosted.org/packages/0d/93/a1b29c2452d15cecc4a39700fbf54721a3341f2ddbd1bd883f8ec0004e6e/grpcio-1.75.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fa35ccd9501ffdd82b861809cbfc4b5b13f4b4c5dc3434d2d9170b9ed38a9054", size = 5661861, upload-time = "2025-09-16T09:18:58.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ce/7280df197e602d14594e61d1e60e89dfa734bb59a884ba86cdd39686aadb/grpcio-1.75.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:0fcb77f2d718c1e58cc04ef6d3b51e0fa3b26cf926446e86c7eba105727b6cd4", size = 11459982, upload-time = "2025-09-16T09:19:01.211Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9b/37e61349771f89b543a0a0bbc960741115ea8656a2414bfb24c4de6f3dd7/grpcio-1.75.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36764a4ad9dc1eb891042fab51e8cdf7cc014ad82cee807c10796fb708455041", size = 6239680, upload-time = "2025-09-16T09:19:04.443Z" }, + { url = "https://files.pythonhosted.org/packages/a6/66/f645d9d5b22ca307f76e71abc83ab0e574b5dfef3ebde4ec8b865dd7e93e/grpcio-1.75.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:725e67c010f63ef17fc052b261004942763c0b18dcd84841e6578ddacf1f9d10", size = 6908511, upload-time = "2025-09-16T09:19:07.884Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9a/34b11cd62d03c01b99068e257595804c695c3c119596c7077f4923295e19/grpcio-1.75.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91fbfc43f605c5ee015c9056d580a70dd35df78a7bad97e05426795ceacdb59f", size = 6429105, upload-time = "2025-09-16T09:19:10.085Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/76eaceaad1f42c1e7e6a5b49a61aac40fc5c9bee4b14a1630f056ac3a57e/grpcio-1.75.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a9337ac4ce61c388e02019d27fa837496c4b7837cbbcec71b05934337e51531", size = 7060578, upload-time = "2025-09-16T09:19:12.283Z" }, + { url = "https://files.pythonhosted.org/packages/3d/82/181a0e3f1397b6d43239e95becbeb448563f236c0db11ce990f073b08d01/grpcio-1.75.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ee16e232e3d0974750ab5f4da0ab92b59d6473872690b5e40dcec9a22927f22e", size = 8003283, upload-time = "2025-09-16T09:19:15.601Z" }, + { url = "https://files.pythonhosted.org/packages/de/09/a335bca211f37a3239be4b485e3c12bf3da68d18b1f723affdff2b9e9680/grpcio-1.75.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:55dfb9122973cc69520b23d39867726722cafb32e541435707dc10249a1bdbc6", size = 7460319, upload-time = "2025-09-16T09:19:18.409Z" }, + { url = "https://files.pythonhosted.org/packages/aa/59/6330105cdd6bc4405e74c96838cd7e148c3653ae3996e540be6118220c79/grpcio-1.75.0-cp312-cp312-win32.whl", hash = "sha256:fb64dd62face3d687a7b56cd881e2ea39417af80f75e8b36f0f81dfd93071651", size = 3934011, upload-time = "2025-09-16T09:19:21.013Z" }, + { url = "https://files.pythonhosted.org/packages/ff/14/e1309a570b7ebdd1c8ca24c4df6b8d6690009fa8e0d997cb2c026ce850c9/grpcio-1.75.0-cp312-cp312-win_amd64.whl", hash = "sha256:6b365f37a9c9543a9e91c6b4103d68d38d5bcb9965b11d5092b3c157bd6a5ee7", size = 4637934, upload-time = "2025-09-16T09:19:23.19Z" }, + { url = "https://files.pythonhosted.org/packages/00/64/dbce0ffb6edaca2b292d90999dd32a3bd6bc24b5b77618ca28440525634d/grpcio-1.75.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:1bb78d052948d8272c820bb928753f16a614bb2c42fbf56ad56636991b427518", size = 5666860, upload-time = "2025-09-16T09:19:25.417Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e6/da02c8fa882ad3a7f868d380bb3da2c24d35dd983dd12afdc6975907a352/grpcio-1.75.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:9dc4a02796394dd04de0b9673cb79a78901b90bb16bf99ed8cb528c61ed9372e", size = 11455148, upload-time = "2025-09-16T09:19:28.615Z" }, + { url = "https://files.pythonhosted.org/packages/ba/a0/84f87f6c2cf2a533cfce43b2b620eb53a51428ec0c8fe63e5dd21d167a70/grpcio-1.75.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:437eeb16091d31498585d73b133b825dc80a8db43311e332c08facf820d36894", size = 6243865, upload-time = "2025-09-16T09:19:31.342Z" }, + { url = "https://files.pythonhosted.org/packages/be/12/53da07aa701a4839dd70d16e61ce21ecfcc9e929058acb2f56e9b2dd8165/grpcio-1.75.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:c2c39984e846bd5da45c5f7bcea8fafbe47c98e1ff2b6f40e57921b0c23a52d0", size = 6915102, upload-time = "2025-09-16T09:19:33.658Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c0/7eaceafd31f52ec4bf128bbcf36993b4bc71f64480f3687992ddd1a6e315/grpcio-1.75.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38d665f44b980acdbb2f0e1abf67605ba1899f4d2443908df9ec8a6f26d2ed88", size = 6432042, upload-time = "2025-09-16T09:19:36.583Z" }, + { url = "https://files.pythonhosted.org/packages/6b/12/a2ce89a9f4fc52a16ed92951f1b05f53c17c4028b3db6a4db7f08332bee8/grpcio-1.75.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e8e752ab5cc0a9c5b949808c000ca7586223be4f877b729f034b912364c3964", size = 7062984, upload-time = "2025-09-16T09:19:39.163Z" }, + { url = "https://files.pythonhosted.org/packages/55/a6/2642a9b491e24482d5685c0f45c658c495a5499b43394846677abed2c966/grpcio-1.75.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3a6788b30aa8e6f207c417874effe3f79c2aa154e91e78e477c4825e8b431ce0", size = 8001212, upload-time = "2025-09-16T09:19:41.726Z" }, + { url = "https://files.pythonhosted.org/packages/19/20/530d4428750e9ed6ad4254f652b869a20a40a276c1f6817b8c12d561f5ef/grpcio-1.75.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc33e67cab6141c54e75d85acd5dec616c5095a957ff997b4330a6395aa9b51", size = 7457207, upload-time = "2025-09-16T09:19:44.368Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6f/843670007e0790af332a21468d10059ea9fdf97557485ae633b88bd70efc/grpcio-1.75.0-cp313-cp313-win32.whl", hash = "sha256:c8cfc780b7a15e06253aae5f228e1e84c0d3c4daa90faf5bc26b751174da4bf9", size = 3934235, upload-time = "2025-09-16T09:19:46.815Z" }, + { url = "https://files.pythonhosted.org/packages/4b/92/c846b01b38fdf9e2646a682b12e30a70dc7c87dfe68bd5e009ee1501c14b/grpcio-1.75.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c91d5b16eff3cbbe76b7a1eaaf3d91e7a954501e9d4f915554f87c470475c3d", size = 4637558, upload-time = "2025-09-16T09:19:49.698Z" }, ] [[package]] @@ -1466,103 +1338,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] -[[package]] -name = "ipykernel" -version = "6.30.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "appnope", marker = "sys_platform == 'darwin'" }, - { name = "comm", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "debugpy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "ipython", version = "9.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "jupyter-client", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "jupyter-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "matplotlib-inline", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nest-asyncio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "packaging", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "psutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyzmq", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "tornado", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, -] - -[[package]] -name = "ipython" -version = "8.37.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and sys_platform == 'linux'", - "python_full_version < '3.11' and sys_platform == 'win32'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "exceptiongroup", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "jedi", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "matplotlib-inline", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "pexpect", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux')" }, - { name = "prompt-toolkit", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "pygments", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "stack-data", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "traitlets", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "typing-extensions", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/91/d0/274fbf7b0b12643cbbc001ce13e6a5b1607ac4929d1b11c72460152c9fc3/ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2", size = 831864, upload-time = "2025-05-31T16:39:06.38Z" }, -] - -[[package]] -name = "ipython" -version = "9.5.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and sys_platform == 'linux'", - "python_full_version >= '3.13' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "ipython-pygments-lexers", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "jedi", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "matplotlib-inline", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "pexpect", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux')" }, - { name = "prompt-toolkit", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "pygments", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "stack-data", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "traitlets", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "typing-extensions", marker = "(python_full_version == '3.11.*' and sys_platform == 'darwin') or (python_full_version == '3.11.*' and sys_platform == 'linux') or (python_full_version == '3.11.*' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6e/71/a86262bf5a68bf211bcc71fe302af7e05f18a2852fdc610a854d20d085e6/ipython-9.5.0.tar.gz", hash = "sha256:129c44b941fe6d9b82d36fc7a7c18127ddb1d6f02f78f867f402e2e3adde3113", size = 4389137, upload-time = "2025-08-29T12:15:21.519Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/08/2a/5628a99d04acb2d2f2e749cdf4ea571d2575e898df0528a090948018b726/ipython-9.5.0-py3-none-any.whl", hash = "sha256:88369ffa1d5817d609120daa523a6da06d02518e582347c29f8451732a9c5e72", size = 612426, upload-time = "2025-08-29T12:15:18.866Z" }, -] - -[[package]] -name = "ipython-pygments-lexers" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pygments", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, -] - [[package]] name = "isodate" version = "0.7.2" @@ -1572,18 +1347,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/aa/0aca39a37d3c7eb941ba736ede56d689e7be91cab5d9ca846bde3999eba6/isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15", size = 22320, upload-time = "2024-10-08T23:04:09.501Z" }, ] -[[package]] -name = "jedi" -version = "0.19.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "parso", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, -] - [[package]] name = "jinja2" version = "3.1.6" @@ -1600,72 +1363,73 @@ wheels = [ name = "jiter" version = "0.11.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/c0/a3bb4cc13aced219dd18191ea66e874266bd8aa7b96744e495e1c733aa2d/jiter-0.11.0.tar.gz", hash = "sha256:1d9637eaf8c1d6a63d6562f2a6e5ab3af946c66037eb1b894e8fad75422266e4", size = 167094 } +sdist = { url = "https://files.pythonhosted.org/packages/9d/c0/a3bb4cc13aced219dd18191ea66e874266bd8aa7b96744e495e1c733aa2d/jiter-0.11.0.tar.gz", hash = "sha256:1d9637eaf8c1d6a63d6562f2a6e5ab3af946c66037eb1b894e8fad75422266e4", size = 167094, upload-time = "2025-09-15T09:20:38.212Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/21/7dd1235a19e26979be6098e87e4cced2e061752f3a40a17bbce6dea7fae1/jiter-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3893ce831e1c0094a83eeaf56c635a167d6fa8cc14393cc14298fd6fdc2a2449", size = 309875 }, - { url = "https://files.pythonhosted.org/packages/71/f9/462b54708aa85b135733ccba70529dd68a18511bf367a87c5fd28676c841/jiter-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25c625b9b61b5a8725267fdf867ef2e51b429687f6a4eef211f4612e95607179", size = 316505 }, - { url = "https://files.pythonhosted.org/packages/bd/40/14e2eeaac6a47bff27d213834795472355fd39769272eb53cb7aa83d5aa8/jiter-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd4ca85fb6a62cf72e1c7f5e34ddef1b660ce4ed0886ec94a1ef9777d35eaa1f", size = 337613 }, - { url = "https://files.pythonhosted.org/packages/d3/ed/a5f1f8419c92b150a7c7fb5ccba1fb1e192887ad713d780e70874f0ce996/jiter-0.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:572208127034725e79c28437b82414028c3562335f2b4f451d98136d0fc5f9cd", size = 361438 }, - { url = "https://files.pythonhosted.org/packages/dd/f5/70682c023dfcdd463a53faf5d30205a7d99c51d70d3e303c932d0936e5a2/jiter-0.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:494ba627c7f550ad3dabb21862864b8f2216098dc18ff62f37b37796f2f7c325", size = 486180 }, - { url = "https://files.pythonhosted.org/packages/7c/39/020d08cbab4eab48142ad88b837c41eb08a15c0767fdb7c0d3265128a44b/jiter-0.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8da18a99f58bca3ecc2d2bba99cac000a924e115b6c4f0a2b98f752b6fbf39a", size = 376681 }, - { url = "https://files.pythonhosted.org/packages/52/10/b86733f6e594cf51dd142f37c602d8df87c554c5844958deaab0de30eb5d/jiter-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ffd3b0fff3fabbb02cc09910c08144db6bb5697a98d227a074401e01ee63dd", size = 348685 }, - { url = "https://files.pythonhosted.org/packages/fb/ee/8861665e83a9e703aa5f65fddddb6225428e163e6b0baa95a7f9a8fb9aae/jiter-0.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8fe6530aa738a4f7d4e4702aa8f9581425d04036a5f9e25af65ebe1f708f23be", size = 385573 }, - { url = "https://files.pythonhosted.org/packages/25/74/05afec03600951f128293813b5a208c9ba1bf587c57a344c05a42a69e1b1/jiter-0.11.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e35d66681c133a03d7e974e7eedae89720fe8ca3bd09f01a4909b86a8adf31f5", size = 516669 }, - { url = "https://files.pythonhosted.org/packages/93/d1/2e5bfe147cfbc2a5eef7f73eb75dc5c6669da4fa10fc7937181d93af9495/jiter-0.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c59459beca2fbc9718b6f1acb7bfb59ebc3eb4294fa4d40e9cb679dafdcc6c60", size = 508767 }, - { url = "https://files.pythonhosted.org/packages/87/50/597f71307e10426b5c082fd05d38c615ddbdd08c3348d8502963307f0652/jiter-0.11.0-cp310-cp310-win32.whl", hash = "sha256:b7b0178417b0dcfc5f259edbc6db2b1f5896093ed9035ee7bab0f2be8854726d", size = 205476 }, - { url = "https://files.pythonhosted.org/packages/c7/86/1e5214b3272e311754da26e63edec93a183811d4fc2e0118addec365df8b/jiter-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:11df2bf99fb4754abddd7f5d940a48e51f9d11624d6313ca4314145fcad347f0", size = 204708 }, - { url = "https://files.pythonhosted.org/packages/38/55/a69fefeef09c2eaabae44b935a1aa81517e49639c0a0c25d861cb18cd7ac/jiter-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cb5d9db02979c3f49071fce51a48f4b4e4cf574175fb2b11c7a535fa4867b222", size = 309503 }, - { url = "https://files.pythonhosted.org/packages/bd/d5/a6aba9e6551f32f9c127184f398208e4eddb96c59ac065c8a92056089d28/jiter-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1dc6a123f3471c4730db7ca8ba75f1bb3dcb6faeb8d46dd781083e7dee88b32d", size = 317688 }, - { url = "https://files.pythonhosted.org/packages/bb/f3/5e86f57c1883971cdc8535d0429c2787bf734840a231da30a3be12850562/jiter-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09858f8d230f031c7b8e557429102bf050eea29c77ad9c34c8fe253c5329acb7", size = 337418 }, - { url = "https://files.pythonhosted.org/packages/5e/4f/a71d8a24c2a70664970574a8e0b766663f5ef788f7fe1cc20ee0c016d488/jiter-0.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbe2196c4a0ce760925a74ab4456bf644748ab0979762139626ad138f6dac72d", size = 361423 }, - { url = "https://files.pythonhosted.org/packages/8f/e5/b09076f4e7fd9471b91e16f9f3dc7330b161b738f3b39b2c37054a36e26a/jiter-0.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5beb56d22b63647bafd0b74979216fdee80c580c0c63410be8c11053860ffd09", size = 486367 }, - { url = "https://files.pythonhosted.org/packages/fb/f1/98cb3a36f5e62f80cd860f0179f948d9eab5a316d55d3e1bab98d9767af5/jiter-0.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97025d09ef549795d8dc720a824312cee3253c890ac73c621721ddfc75066789", size = 376335 }, - { url = "https://files.pythonhosted.org/packages/9f/d8/ec74886497ea393c29dbd7651ddecc1899e86404a6b1f84a3ddab0ab59fd/jiter-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50880a6da65d8c23a2cf53c412847d9757e74cc9a3b95c5704a1d1a24667347", size = 348981 }, - { url = "https://files.pythonhosted.org/packages/24/93/d22ad7fa3b86ade66c86153ceea73094fc2af8b20c59cb7fceab9fea4704/jiter-0.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:452d80a1c86c095a242007bd9fc5d21b8a8442307193378f891cb8727e469648", size = 385797 }, - { url = "https://files.pythonhosted.org/packages/c8/bd/e25ff4a4df226e9b885f7cb01ee4b9dc74e3000e612d6f723860d71a1f34/jiter-0.11.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e84e58198d4894668eec2da660ffff60e0f3e60afa790ecc50cb12b0e02ca1d4", size = 516597 }, - { url = "https://files.pythonhosted.org/packages/be/fb/beda613db7d93ffa2fdd2683f90f2f5dce8daf4bc2d0d2829e7de35308c6/jiter-0.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df64edcfc5dd5279a791eea52aa113d432c933119a025b0b5739f90d2e4e75f1", size = 508853 }, - { url = "https://files.pythonhosted.org/packages/20/64/c5b0d93490634e41e38e2a15de5d54fdbd2c9f64a19abb0f95305b63373c/jiter-0.11.0-cp311-cp311-win32.whl", hash = "sha256:144fc21337d21b1d048f7f44bf70881e1586401d405ed3a98c95a114a9994982", size = 205140 }, - { url = "https://files.pythonhosted.org/packages/a1/e6/c347c0e6f5796e97d4356b7e5ff0ce336498b7f4ef848fae621a56f1ccf3/jiter-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:b0f32e644d241293b892b1a6dd8f0b9cc029bfd94c97376b2681c36548aabab7", size = 204311 }, - { url = "https://files.pythonhosted.org/packages/ba/b5/3009b112b8f673e568ef79af9863d8309a15f0a8cdcc06ed6092051f377e/jiter-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:2fb7b377688cc3850bbe5c192a6bd493562a0bc50cbc8b047316428fbae00ada", size = 305510 }, - { url = "https://files.pythonhosted.org/packages/fe/82/15514244e03b9e71e086bbe2a6de3e4616b48f07d5f834200c873956fb8c/jiter-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1b7cbe3f25bd0d8abb468ba4302a5d45617ee61b2a7a638f63fee1dc086be99", size = 316521 }, - { url = "https://files.pythonhosted.org/packages/92/94/7a2e905f40ad2d6d660e00b68d818f9e29fb87ffe82774f06191e93cbe4a/jiter-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0a7f0ec81d5b7588c5cade1eb1925b91436ae6726dc2df2348524aeabad5de6", size = 338214 }, - { url = "https://files.pythonhosted.org/packages/a8/9c/5791ed5bdc76f12110158d3316a7a3ec0b1413d018b41c5ed399549d3ad5/jiter-0.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07630bb46ea2a6b9c6ed986c6e17e35b26148cce2c535454b26ee3f0e8dcaba1", size = 361280 }, - { url = "https://files.pythonhosted.org/packages/d4/7f/b7d82d77ff0d2cb06424141000176b53a9e6b16a1125525bb51ea4990c2e/jiter-0.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7764f27d28cd4a9cbc61704dfcd80c903ce3aad106a37902d3270cd6673d17f4", size = 487895 }, - { url = "https://files.pythonhosted.org/packages/42/44/10a1475d46f1fc1fd5cc2e82c58e7bca0ce5852208e0fa5df2f949353321/jiter-0.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4a6c4a737d486f77f842aeb22807edecb4a9417e6700c7b981e16d34ba7c72", size = 378421 }, - { url = "https://files.pythonhosted.org/packages/9a/5f/0dc34563d8164d31d07bc09d141d3da08157a68dcd1f9b886fa4e917805b/jiter-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf408d2a0abd919b60de8c2e7bc5eeab72d4dafd18784152acc7c9adc3291591", size = 347932 }, - { url = "https://files.pythonhosted.org/packages/f7/de/b68f32a4fcb7b4a682b37c73a0e5dae32180140cd1caf11aef6ad40ddbf2/jiter-0.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cdef53eda7d18e799625023e1e250dbc18fbc275153039b873ec74d7e8883e09", size = 386959 }, - { url = "https://files.pythonhosted.org/packages/76/0a/c08c92e713b6e28972a846a81ce374883dac2f78ec6f39a0dad9f2339c3a/jiter-0.11.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:53933a38ef7b551dd9c7f1064f9d7bb235bb3168d0fa5f14f0798d1b7ea0d9c5", size = 517187 }, - { url = "https://files.pythonhosted.org/packages/89/b5/4a283bec43b15aad54fcae18d951f06a2ec3f78db5708d3b59a48e9c3fbd/jiter-0.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11840d2324c9ab5162fc1abba23bc922124fedcff0d7b7f85fffa291e2f69206", size = 509461 }, - { url = "https://files.pythonhosted.org/packages/34/a5/f8bad793010534ea73c985caaeef8cc22dfb1fedb15220ecdf15c623c07a/jiter-0.11.0-cp312-cp312-win32.whl", hash = "sha256:4f01a744d24a5f2bb4a11657a1b27b61dc038ae2e674621a74020406e08f749b", size = 206664 }, - { url = "https://files.pythonhosted.org/packages/ed/42/5823ec2b1469395a160b4bf5f14326b4a098f3b6898fbd327366789fa5d3/jiter-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:29fff31190ab3a26de026da2f187814f4b9c6695361e20a9ac2123e4d4378a4c", size = 203520 }, - { url = "https://files.pythonhosted.org/packages/97/c4/d530e514d0f4f29b2b68145e7b389cbc7cac7f9c8c23df43b04d3d10fa3e/jiter-0.11.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4441a91b80a80249f9a6452c14b2c24708f139f64de959943dfeaa6cb915e8eb", size = 305021 }, - { url = "https://files.pythonhosted.org/packages/7a/77/796a19c567c5734cbfc736a6f987affc0d5f240af8e12063c0fb93990ffa/jiter-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff85fc6d2a431251ad82dbd1ea953affb5a60376b62e7d6809c5cd058bb39471", size = 314384 }, - { url = "https://files.pythonhosted.org/packages/14/9c/824334de0b037b91b6f3fa9fe5a191c83977c7ec4abe17795d3cb6d174cf/jiter-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5e86126d64706fd28dfc46f910d496923c6f95b395138c02d0e252947f452bd", size = 337389 }, - { url = "https://files.pythonhosted.org/packages/a2/95/ed4feab69e6cf9b2176ea29d4ef9d01a01db210a3a2c8a31a44ecdc68c38/jiter-0.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad8bd82165961867a10f52010590ce0b7a8c53da5ddd8bbb62fef68c181b921", size = 360519 }, - { url = "https://files.pythonhosted.org/packages/b5/0c/2ad00f38d3e583caba3909d95b7da1c3a7cd82c0aa81ff4317a8016fb581/jiter-0.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b42c2cd74273455ce439fd9528db0c6e84b5623cb74572305bdd9f2f2961d3df", size = 487198 }, - { url = "https://files.pythonhosted.org/packages/ea/8b/919b64cf3499b79bdfba6036da7b0cac5d62d5c75a28fb45bad7819e22f0/jiter-0.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0062dab98172dd0599fcdbf90214d0dcde070b1ff38a00cc1b90e111f071982", size = 377835 }, - { url = "https://files.pythonhosted.org/packages/29/7f/8ebe15b6e0a8026b0d286c083b553779b4dd63db35b43a3f171b544de91d/jiter-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb948402821bc76d1f6ef0f9e19b816f9b09f8577844ba7140f0b6afe994bc64", size = 347655 }, - { url = "https://files.pythonhosted.org/packages/8e/64/332127cef7e94ac75719dda07b9a472af6158ba819088d87f17f3226a769/jiter-0.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25a5b1110cca7329fd0daf5060faa1234be5c11e988948e4f1a1923b6a457fe1", size = 386135 }, - { url = "https://files.pythonhosted.org/packages/20/c8/557b63527442f84c14774159948262a9d4fabb0d61166f11568f22fc60d2/jiter-0.11.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bf11807e802a214daf6c485037778843fadd3e2ec29377ae17e0706ec1a25758", size = 516063 }, - { url = "https://files.pythonhosted.org/packages/86/13/4164c819df4a43cdc8047f9a42880f0ceef5afeb22e8b9675c0528ebdccd/jiter-0.11.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbb57da40631c267861dd0090461222060960012d70fd6e4c799b0f62d0ba166", size = 508139 }, - { url = "https://files.pythonhosted.org/packages/fa/70/6e06929b401b331d41ddb4afb9f91cd1168218e3371972f0afa51c9f3c31/jiter-0.11.0-cp313-cp313-win32.whl", hash = "sha256:8e36924dad32c48d3c5e188d169e71dc6e84d6cb8dedefea089de5739d1d2f80", size = 206369 }, - { url = "https://files.pythonhosted.org/packages/f4/0d/8185b8e15de6dce24f6afae63380e16377dd75686d56007baa4f29723ea1/jiter-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:452d13e4fd59698408087235259cebe67d9d49173b4dacb3e8d35ce4acf385d6", size = 202538 }, - { url = "https://files.pythonhosted.org/packages/13/3a/d61707803260d59520721fa326babfae25e9573a88d8b7b9cb54c5423a59/jiter-0.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:089f9df9f69532d1339e83142438668f52c97cd22ee2d1195551c2b1a9e6cf33", size = 313737 }, - { url = "https://files.pythonhosted.org/packages/cd/cc/c9f0eec5d00f2a1da89f6bdfac12b8afdf8d5ad974184863c75060026457/jiter-0.11.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ed1fe69a8c69bf0f2a962d8d706c7b89b50f1332cd6b9fbda014f60bd03a03", size = 346183 }, - { url = "https://files.pythonhosted.org/packages/a6/87/fc632776344e7aabbab05a95a0075476f418c5d29ab0f2eec672b7a1f0ac/jiter-0.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a4d71d7ea6ea8786291423fe209acf6f8d398a0759d03e7f24094acb8ab686ba", size = 204225 }, - { url = "https://files.pythonhosted.org/packages/ee/3b/e7f45be7d3969bdf2e3cd4b816a7a1d272507cd0edd2d6dc4b07514f2d9a/jiter-0.11.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9a6dff27eca70930bdbe4cbb7c1a4ba8526e13b63dc808c0670083d2d51a4a72", size = 304414 }, - { url = "https://files.pythonhosted.org/packages/06/32/13e8e0d152631fcc1907ceb4943711471be70496d14888ec6e92034e2caf/jiter-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ae2a7593a62132c7d4c2abbee80bbbb94fdc6d157e2c6cc966250c564ef774", size = 314223 }, - { url = "https://files.pythonhosted.org/packages/0c/7e/abedd5b5a20ca083f778d96bba0d2366567fcecb0e6e34ff42640d5d7a18/jiter-0.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b13a431dba4b059e9e43019d3022346d009baf5066c24dcdea321a303cde9f0", size = 337306 }, - { url = "https://files.pythonhosted.org/packages/ac/e2/30d59bdc1204c86aa975ec72c48c482fee6633120ee9c3ab755e4dfefea8/jiter-0.11.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:af62e84ca3889604ebb645df3b0a3f3bcf6b92babbff642bd214616f57abb93a", size = 360565 }, - { url = "https://files.pythonhosted.org/packages/fe/88/567288e0d2ed9fa8f7a3b425fdaf2cb82b998633c24fe0d98f5417321aa8/jiter-0.11.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6f3b32bb723246e6b351aecace52aba78adb8eeb4b2391630322dc30ff6c773", size = 486465 }, - { url = "https://files.pythonhosted.org/packages/18/6e/7b72d09273214cadd15970e91dd5ed9634bee605176107db21e1e4205eb1/jiter-0.11.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adcab442f4a099a358a7f562eaa54ed6456fb866e922c6545a717be51dbed7d7", size = 377581 }, - { url = "https://files.pythonhosted.org/packages/58/52/4db456319f9d14deed325f70102577492e9d7e87cf7097bda9769a1fcacb/jiter-0.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9967c2ab338ee2b2c0102fd379ec2693c496abf71ffd47e4d791d1f593b68e2", size = 347102 }, - { url = "https://files.pythonhosted.org/packages/ce/b4/433d5703c38b26083aec7a733eb5be96f9c6085d0e270a87ca6482cbf049/jiter-0.11.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e7d0bed3b187af8b47a981d9742ddfc1d9b252a7235471ad6078e7e4e5fe75c2", size = 386477 }, - { url = "https://files.pythonhosted.org/packages/c8/7a/a60bfd9c55b55b07c5c441c5085f06420b6d493ce9db28d069cc5b45d9f3/jiter-0.11.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:f6fe0283e903ebc55f1a6cc569b8c1f3bf4abd026fed85e3ff8598a9e6f982f0", size = 516004 }, - { url = "https://files.pythonhosted.org/packages/2e/46/f8363e5ecc179b4ed0ca6cb0a6d3bfc266078578c71ff30642ea2ce2f203/jiter-0.11.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5821e3d66606b29ae5b497230b304f1376f38137d69e35f8d2bd5f310ff73", size = 507855 }, - { url = "https://files.pythonhosted.org/packages/90/33/396083357d51d7ff0f9805852c288af47480d30dd31d8abc74909b020761/jiter-0.11.0-cp314-cp314-win32.whl", hash = "sha256:c2d13ba7567ca8799f17c76ed56b1d49be30df996eb7fa33e46b62800562a5e2", size = 205802 }, - { url = "https://files.pythonhosted.org/packages/e7/ab/eb06ca556b2551d41de7d03bf2ee24285fa3d0c58c5f8d95c64c9c3281b1/jiter-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fb4790497369d134a07fc763cc88888c46f734abdd66f9fdf7865038bf3a8f40", size = 313405 }, - { url = "https://files.pythonhosted.org/packages/af/22/7ab7b4ec3a1c1f03aef376af11d23b05abcca3fb31fbca1e7557053b1ba2/jiter-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2bbf24f16ba5ad4441a9845e40e4ea0cb9eed00e76ba94050664ef53ef4406", size = 347102 }, + { url = "https://files.pythonhosted.org/packages/25/21/7dd1235a19e26979be6098e87e4cced2e061752f3a40a17bbce6dea7fae1/jiter-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3893ce831e1c0094a83eeaf56c635a167d6fa8cc14393cc14298fd6fdc2a2449", size = 309875, upload-time = "2025-09-15T09:18:48.41Z" }, + { url = "https://files.pythonhosted.org/packages/71/f9/462b54708aa85b135733ccba70529dd68a18511bf367a87c5fd28676c841/jiter-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:25c625b9b61b5a8725267fdf867ef2e51b429687f6a4eef211f4612e95607179", size = 316505, upload-time = "2025-09-15T09:18:51.057Z" }, + { url = "https://files.pythonhosted.org/packages/bd/40/14e2eeaac6a47bff27d213834795472355fd39769272eb53cb7aa83d5aa8/jiter-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd4ca85fb6a62cf72e1c7f5e34ddef1b660ce4ed0886ec94a1ef9777d35eaa1f", size = 337613, upload-time = "2025-09-15T09:18:52.358Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ed/a5f1f8419c92b150a7c7fb5ccba1fb1e192887ad713d780e70874f0ce996/jiter-0.11.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:572208127034725e79c28437b82414028c3562335f2b4f451d98136d0fc5f9cd", size = 361438, upload-time = "2025-09-15T09:18:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f5/70682c023dfcdd463a53faf5d30205a7d99c51d70d3e303c932d0936e5a2/jiter-0.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:494ba627c7f550ad3dabb21862864b8f2216098dc18ff62f37b37796f2f7c325", size = 486180, upload-time = "2025-09-15T09:18:56.158Z" }, + { url = "https://files.pythonhosted.org/packages/7c/39/020d08cbab4eab48142ad88b837c41eb08a15c0767fdb7c0d3265128a44b/jiter-0.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8da18a99f58bca3ecc2d2bba99cac000a924e115b6c4f0a2b98f752b6fbf39a", size = 376681, upload-time = "2025-09-15T09:18:57.553Z" }, + { url = "https://files.pythonhosted.org/packages/52/10/b86733f6e594cf51dd142f37c602d8df87c554c5844958deaab0de30eb5d/jiter-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4ffd3b0fff3fabbb02cc09910c08144db6bb5697a98d227a074401e01ee63dd", size = 348685, upload-time = "2025-09-15T09:18:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/fb/ee/8861665e83a9e703aa5f65fddddb6225428e163e6b0baa95a7f9a8fb9aae/jiter-0.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8fe6530aa738a4f7d4e4702aa8f9581425d04036a5f9e25af65ebe1f708f23be", size = 385573, upload-time = "2025-09-15T09:19:00.593Z" }, + { url = "https://files.pythonhosted.org/packages/25/74/05afec03600951f128293813b5a208c9ba1bf587c57a344c05a42a69e1b1/jiter-0.11.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e35d66681c133a03d7e974e7eedae89720fe8ca3bd09f01a4909b86a8adf31f5", size = 516669, upload-time = "2025-09-15T09:19:02.369Z" }, + { url = "https://files.pythonhosted.org/packages/93/d1/2e5bfe147cfbc2a5eef7f73eb75dc5c6669da4fa10fc7937181d93af9495/jiter-0.11.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c59459beca2fbc9718b6f1acb7bfb59ebc3eb4294fa4d40e9cb679dafdcc6c60", size = 508767, upload-time = "2025-09-15T09:19:04.011Z" }, + { url = "https://files.pythonhosted.org/packages/87/50/597f71307e10426b5c082fd05d38c615ddbdd08c3348d8502963307f0652/jiter-0.11.0-cp310-cp310-win32.whl", hash = "sha256:b7b0178417b0dcfc5f259edbc6db2b1f5896093ed9035ee7bab0f2be8854726d", size = 205476, upload-time = "2025-09-15T09:19:05.594Z" }, + { url = "https://files.pythonhosted.org/packages/c7/86/1e5214b3272e311754da26e63edec93a183811d4fc2e0118addec365df8b/jiter-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:11df2bf99fb4754abddd7f5d940a48e51f9d11624d6313ca4314145fcad347f0", size = 204708, upload-time = "2025-09-15T09:19:06.955Z" }, + { url = "https://files.pythonhosted.org/packages/38/55/a69fefeef09c2eaabae44b935a1aa81517e49639c0a0c25d861cb18cd7ac/jiter-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cb5d9db02979c3f49071fce51a48f4b4e4cf574175fb2b11c7a535fa4867b222", size = 309503, upload-time = "2025-09-15T09:19:08.191Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d5/a6aba9e6551f32f9c127184f398208e4eddb96c59ac065c8a92056089d28/jiter-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1dc6a123f3471c4730db7ca8ba75f1bb3dcb6faeb8d46dd781083e7dee88b32d", size = 317688, upload-time = "2025-09-15T09:19:09.918Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f3/5e86f57c1883971cdc8535d0429c2787bf734840a231da30a3be12850562/jiter-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09858f8d230f031c7b8e557429102bf050eea29c77ad9c34c8fe253c5329acb7", size = 337418, upload-time = "2025-09-15T09:19:11.078Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/a71d8a24c2a70664970574a8e0b766663f5ef788f7fe1cc20ee0c016d488/jiter-0.11.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbe2196c4a0ce760925a74ab4456bf644748ab0979762139626ad138f6dac72d", size = 361423, upload-time = "2025-09-15T09:19:13.286Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e5/b09076f4e7fd9471b91e16f9f3dc7330b161b738f3b39b2c37054a36e26a/jiter-0.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5beb56d22b63647bafd0b74979216fdee80c580c0c63410be8c11053860ffd09", size = 486367, upload-time = "2025-09-15T09:19:14.546Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f1/98cb3a36f5e62f80cd860f0179f948d9eab5a316d55d3e1bab98d9767af5/jiter-0.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97025d09ef549795d8dc720a824312cee3253c890ac73c621721ddfc75066789", size = 376335, upload-time = "2025-09-15T09:19:15.939Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d8/ec74886497ea393c29dbd7651ddecc1899e86404a6b1f84a3ddab0ab59fd/jiter-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d50880a6da65d8c23a2cf53c412847d9757e74cc9a3b95c5704a1d1a24667347", size = 348981, upload-time = "2025-09-15T09:19:17.568Z" }, + { url = "https://files.pythonhosted.org/packages/24/93/d22ad7fa3b86ade66c86153ceea73094fc2af8b20c59cb7fceab9fea4704/jiter-0.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:452d80a1c86c095a242007bd9fc5d21b8a8442307193378f891cb8727e469648", size = 385797, upload-time = "2025-09-15T09:19:19.121Z" }, + { url = "https://files.pythonhosted.org/packages/c8/bd/e25ff4a4df226e9b885f7cb01ee4b9dc74e3000e612d6f723860d71a1f34/jiter-0.11.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e84e58198d4894668eec2da660ffff60e0f3e60afa790ecc50cb12b0e02ca1d4", size = 516597, upload-time = "2025-09-15T09:19:20.301Z" }, + { url = "https://files.pythonhosted.org/packages/be/fb/beda613db7d93ffa2fdd2683f90f2f5dce8daf4bc2d0d2829e7de35308c6/jiter-0.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df64edcfc5dd5279a791eea52aa113d432c933119a025b0b5739f90d2e4e75f1", size = 508853, upload-time = "2025-09-15T09:19:22.075Z" }, + { url = "https://files.pythonhosted.org/packages/20/64/c5b0d93490634e41e38e2a15de5d54fdbd2c9f64a19abb0f95305b63373c/jiter-0.11.0-cp311-cp311-win32.whl", hash = "sha256:144fc21337d21b1d048f7f44bf70881e1586401d405ed3a98c95a114a9994982", size = 205140, upload-time = "2025-09-15T09:19:23.351Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e6/c347c0e6f5796e97d4356b7e5ff0ce336498b7f4ef848fae621a56f1ccf3/jiter-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:b0f32e644d241293b892b1a6dd8f0b9cc029bfd94c97376b2681c36548aabab7", size = 204311, upload-time = "2025-09-15T09:19:24.591Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b5/3009b112b8f673e568ef79af9863d8309a15f0a8cdcc06ed6092051f377e/jiter-0.11.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:2fb7b377688cc3850bbe5c192a6bd493562a0bc50cbc8b047316428fbae00ada", size = 305510, upload-time = "2025-09-15T09:19:25.893Z" }, + { url = "https://files.pythonhosted.org/packages/fe/82/15514244e03b9e71e086bbe2a6de3e4616b48f07d5f834200c873956fb8c/jiter-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1b7cbe3f25bd0d8abb468ba4302a5d45617ee61b2a7a638f63fee1dc086be99", size = 316521, upload-time = "2025-09-15T09:19:27.525Z" }, + { url = "https://files.pythonhosted.org/packages/92/94/7a2e905f40ad2d6d660e00b68d818f9e29fb87ffe82774f06191e93cbe4a/jiter-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0a7f0ec81d5b7588c5cade1eb1925b91436ae6726dc2df2348524aeabad5de6", size = 338214, upload-time = "2025-09-15T09:19:28.727Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9c/5791ed5bdc76f12110158d3316a7a3ec0b1413d018b41c5ed399549d3ad5/jiter-0.11.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07630bb46ea2a6b9c6ed986c6e17e35b26148cce2c535454b26ee3f0e8dcaba1", size = 361280, upload-time = "2025-09-15T09:19:30.013Z" }, + { url = "https://files.pythonhosted.org/packages/d4/7f/b7d82d77ff0d2cb06424141000176b53a9e6b16a1125525bb51ea4990c2e/jiter-0.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7764f27d28cd4a9cbc61704dfcd80c903ce3aad106a37902d3270cd6673d17f4", size = 487895, upload-time = "2025-09-15T09:19:31.424Z" }, + { url = "https://files.pythonhosted.org/packages/42/44/10a1475d46f1fc1fd5cc2e82c58e7bca0ce5852208e0fa5df2f949353321/jiter-0.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4a6c4a737d486f77f842aeb22807edecb4a9417e6700c7b981e16d34ba7c72", size = 378421, upload-time = "2025-09-15T09:19:32.746Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5f/0dc34563d8164d31d07bc09d141d3da08157a68dcd1f9b886fa4e917805b/jiter-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf408d2a0abd919b60de8c2e7bc5eeab72d4dafd18784152acc7c9adc3291591", size = 347932, upload-time = "2025-09-15T09:19:34.612Z" }, + { url = "https://files.pythonhosted.org/packages/f7/de/b68f32a4fcb7b4a682b37c73a0e5dae32180140cd1caf11aef6ad40ddbf2/jiter-0.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cdef53eda7d18e799625023e1e250dbc18fbc275153039b873ec74d7e8883e09", size = 386959, upload-time = "2025-09-15T09:19:35.994Z" }, + { url = "https://files.pythonhosted.org/packages/76/0a/c08c92e713b6e28972a846a81ce374883dac2f78ec6f39a0dad9f2339c3a/jiter-0.11.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:53933a38ef7b551dd9c7f1064f9d7bb235bb3168d0fa5f14f0798d1b7ea0d9c5", size = 517187, upload-time = "2025-09-15T09:19:37.426Z" }, + { url = "https://files.pythonhosted.org/packages/89/b5/4a283bec43b15aad54fcae18d951f06a2ec3f78db5708d3b59a48e9c3fbd/jiter-0.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11840d2324c9ab5162fc1abba23bc922124fedcff0d7b7f85fffa291e2f69206", size = 509461, upload-time = "2025-09-15T09:19:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/34/a5/f8bad793010534ea73c985caaeef8cc22dfb1fedb15220ecdf15c623c07a/jiter-0.11.0-cp312-cp312-win32.whl", hash = "sha256:4f01a744d24a5f2bb4a11657a1b27b61dc038ae2e674621a74020406e08f749b", size = 206664, upload-time = "2025-09-15T09:19:40.096Z" }, + { url = "https://files.pythonhosted.org/packages/ed/42/5823ec2b1469395a160b4bf5f14326b4a098f3b6898fbd327366789fa5d3/jiter-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:29fff31190ab3a26de026da2f187814f4b9c6695361e20a9ac2123e4d4378a4c", size = 203520, upload-time = "2025-09-15T09:19:41.798Z" }, + { url = "https://files.pythonhosted.org/packages/97/c4/d530e514d0f4f29b2b68145e7b389cbc7cac7f9c8c23df43b04d3d10fa3e/jiter-0.11.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:4441a91b80a80249f9a6452c14b2c24708f139f64de959943dfeaa6cb915e8eb", size = 305021, upload-time = "2025-09-15T09:19:43.523Z" }, + { url = "https://files.pythonhosted.org/packages/7a/77/796a19c567c5734cbfc736a6f987affc0d5f240af8e12063c0fb93990ffa/jiter-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff85fc6d2a431251ad82dbd1ea953affb5a60376b62e7d6809c5cd058bb39471", size = 314384, upload-time = "2025-09-15T09:19:44.849Z" }, + { url = "https://files.pythonhosted.org/packages/14/9c/824334de0b037b91b6f3fa9fe5a191c83977c7ec4abe17795d3cb6d174cf/jiter-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5e86126d64706fd28dfc46f910d496923c6f95b395138c02d0e252947f452bd", size = 337389, upload-time = "2025-09-15T09:19:46.094Z" }, + { url = "https://files.pythonhosted.org/packages/a2/95/ed4feab69e6cf9b2176ea29d4ef9d01a01db210a3a2c8a31a44ecdc68c38/jiter-0.11.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad8bd82165961867a10f52010590ce0b7a8c53da5ddd8bbb62fef68c181b921", size = 360519, upload-time = "2025-09-15T09:19:47.494Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0c/2ad00f38d3e583caba3909d95b7da1c3a7cd82c0aa81ff4317a8016fb581/jiter-0.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b42c2cd74273455ce439fd9528db0c6e84b5623cb74572305bdd9f2f2961d3df", size = 487198, upload-time = "2025-09-15T09:19:49.116Z" }, + { url = "https://files.pythonhosted.org/packages/ea/8b/919b64cf3499b79bdfba6036da7b0cac5d62d5c75a28fb45bad7819e22f0/jiter-0.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0062dab98172dd0599fcdbf90214d0dcde070b1ff38a00cc1b90e111f071982", size = 377835, upload-time = "2025-09-15T09:19:50.468Z" }, + { url = "https://files.pythonhosted.org/packages/29/7f/8ebe15b6e0a8026b0d286c083b553779b4dd63db35b43a3f171b544de91d/jiter-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb948402821bc76d1f6ef0f9e19b816f9b09f8577844ba7140f0b6afe994bc64", size = 347655, upload-time = "2025-09-15T09:19:51.726Z" }, + { url = "https://files.pythonhosted.org/packages/8e/64/332127cef7e94ac75719dda07b9a472af6158ba819088d87f17f3226a769/jiter-0.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25a5b1110cca7329fd0daf5060faa1234be5c11e988948e4f1a1923b6a457fe1", size = 386135, upload-time = "2025-09-15T09:19:53.075Z" }, + { url = "https://files.pythonhosted.org/packages/20/c8/557b63527442f84c14774159948262a9d4fabb0d61166f11568f22fc60d2/jiter-0.11.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:bf11807e802a214daf6c485037778843fadd3e2ec29377ae17e0706ec1a25758", size = 516063, upload-time = "2025-09-15T09:19:54.447Z" }, + { url = "https://files.pythonhosted.org/packages/86/13/4164c819df4a43cdc8047f9a42880f0ceef5afeb22e8b9675c0528ebdccd/jiter-0.11.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbb57da40631c267861dd0090461222060960012d70fd6e4c799b0f62d0ba166", size = 508139, upload-time = "2025-09-15T09:19:55.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/70/6e06929b401b331d41ddb4afb9f91cd1168218e3371972f0afa51c9f3c31/jiter-0.11.0-cp313-cp313-win32.whl", hash = "sha256:8e36924dad32c48d3c5e188d169e71dc6e84d6cb8dedefea089de5739d1d2f80", size = 206369, upload-time = "2025-09-15T09:19:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/f4/0d/8185b8e15de6dce24f6afae63380e16377dd75686d56007baa4f29723ea1/jiter-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:452d13e4fd59698408087235259cebe67d9d49173b4dacb3e8d35ce4acf385d6", size = 202538, upload-time = "2025-09-15T09:19:58.35Z" }, + { url = "https://files.pythonhosted.org/packages/13/3a/d61707803260d59520721fa326babfae25e9573a88d8b7b9cb54c5423a59/jiter-0.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:089f9df9f69532d1339e83142438668f52c97cd22ee2d1195551c2b1a9e6cf33", size = 313737, upload-time = "2025-09-15T09:19:59.638Z" }, + { url = "https://files.pythonhosted.org/packages/cd/cc/c9f0eec5d00f2a1da89f6bdfac12b8afdf8d5ad974184863c75060026457/jiter-0.11.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ed1fe69a8c69bf0f2a962d8d706c7b89b50f1332cd6b9fbda014f60bd03a03", size = 346183, upload-time = "2025-09-15T09:20:01.442Z" }, + { url = "https://files.pythonhosted.org/packages/a6/87/fc632776344e7aabbab05a95a0075476f418c5d29ab0f2eec672b7a1f0ac/jiter-0.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a4d71d7ea6ea8786291423fe209acf6f8d398a0759d03e7f24094acb8ab686ba", size = 204225, upload-time = "2025-09-15T09:20:03.102Z" }, + { url = "https://files.pythonhosted.org/packages/ee/3b/e7f45be7d3969bdf2e3cd4b816a7a1d272507cd0edd2d6dc4b07514f2d9a/jiter-0.11.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9a6dff27eca70930bdbe4cbb7c1a4ba8526e13b63dc808c0670083d2d51a4a72", size = 304414, upload-time = "2025-09-15T09:20:04.357Z" }, + { url = "https://files.pythonhosted.org/packages/06/32/13e8e0d152631fcc1907ceb4943711471be70496d14888ec6e92034e2caf/jiter-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ae2a7593a62132c7d4c2abbee80bbbb94fdc6d157e2c6cc966250c564ef774", size = 314223, upload-time = "2025-09-15T09:20:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/0c/7e/abedd5b5a20ca083f778d96bba0d2366567fcecb0e6e34ff42640d5d7a18/jiter-0.11.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b13a431dba4b059e9e43019d3022346d009baf5066c24dcdea321a303cde9f0", size = 337306, upload-time = "2025-09-15T09:20:06.917Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e2/30d59bdc1204c86aa975ec72c48c482fee6633120ee9c3ab755e4dfefea8/jiter-0.11.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:af62e84ca3889604ebb645df3b0a3f3bcf6b92babbff642bd214616f57abb93a", size = 360565, upload-time = "2025-09-15T09:20:08.283Z" }, + { url = "https://files.pythonhosted.org/packages/fe/88/567288e0d2ed9fa8f7a3b425fdaf2cb82b998633c24fe0d98f5417321aa8/jiter-0.11.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6f3b32bb723246e6b351aecace52aba78adb8eeb4b2391630322dc30ff6c773", size = 486465, upload-time = "2025-09-15T09:20:09.613Z" }, + { url = "https://files.pythonhosted.org/packages/18/6e/7b72d09273214cadd15970e91dd5ed9634bee605176107db21e1e4205eb1/jiter-0.11.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:adcab442f4a099a358a7f562eaa54ed6456fb866e922c6545a717be51dbed7d7", size = 377581, upload-time = "2025-09-15T09:20:10.884Z" }, + { url = "https://files.pythonhosted.org/packages/58/52/4db456319f9d14deed325f70102577492e9d7e87cf7097bda9769a1fcacb/jiter-0.11.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9967c2ab338ee2b2c0102fd379ec2693c496abf71ffd47e4d791d1f593b68e2", size = 347102, upload-time = "2025-09-15T09:20:12.175Z" }, + { url = "https://files.pythonhosted.org/packages/ce/b4/433d5703c38b26083aec7a733eb5be96f9c6085d0e270a87ca6482cbf049/jiter-0.11.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e7d0bed3b187af8b47a981d9742ddfc1d9b252a7235471ad6078e7e4e5fe75c2", size = 386477, upload-time = "2025-09-15T09:20:13.428Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7a/a60bfd9c55b55b07c5c441c5085f06420b6d493ce9db28d069cc5b45d9f3/jiter-0.11.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:f6fe0283e903ebc55f1a6cc569b8c1f3bf4abd026fed85e3ff8598a9e6f982f0", size = 516004, upload-time = "2025-09-15T09:20:14.848Z" }, + { url = "https://files.pythonhosted.org/packages/2e/46/f8363e5ecc179b4ed0ca6cb0a6d3bfc266078578c71ff30642ea2ce2f203/jiter-0.11.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5821e3d66606b29ae5b497230b304f1376f38137d69e35f8d2bd5f310ff73", size = 507855, upload-time = "2025-09-15T09:20:16.176Z" }, + { url = "https://files.pythonhosted.org/packages/90/33/396083357d51d7ff0f9805852c288af47480d30dd31d8abc74909b020761/jiter-0.11.0-cp314-cp314-win32.whl", hash = "sha256:c2d13ba7567ca8799f17c76ed56b1d49be30df996eb7fa33e46b62800562a5e2", size = 205802, upload-time = "2025-09-15T09:20:17.661Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/eb06ca556b2551d41de7d03bf2ee24285fa3d0c58c5f8d95c64c9c3281b1/jiter-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fb4790497369d134a07fc763cc88888c46f734abdd66f9fdf7865038bf3a8f40", size = 313405, upload-time = "2025-09-15T09:20:18.918Z" }, + { url = "https://files.pythonhosted.org/packages/af/22/7ab7b4ec3a1c1f03aef376af11d23b05abcca3fb31fbca1e7557053b1ba2/jiter-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e2bbf24f16ba5ad4441a9845e40e4ea0cb9eed00e76ba94050664ef53ef4406", size = 347102, upload-time = "2025-09-15T09:20:20.16Z" }, + { url = "https://files.pythonhosted.org/packages/70/f3/ce100253c80063a7b8b406e1d1562657fd4b9b4e1b562db40e68645342fb/jiter-0.11.0-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:902b43386c04739229076bd1c4c69de5d115553d982ab442a8ae82947c72ede7", size = 336380, upload-time = "2025-09-15T09:20:36.867Z" }, ] [[package]] @@ -1695,95 +1459,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] -[[package]] -name = "jupyter-cache" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "click", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "importlib-metadata", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nbclient", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nbformat", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyyaml", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sqlalchemy", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "tabulate", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bb/f7/3627358075f183956e8c4974603232b03afd4ddc7baf72c2bc9fff522291/jupyter_cache-1.0.1.tar.gz", hash = "sha256:16e808eb19e3fb67a223db906e131ea6e01f03aa27f49a7214ce6a5fec186fb9", size = 32048, upload-time = "2024-11-15T16:03:55.322Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl", hash = "sha256:9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6", size = 33907, upload-time = "2024-11-15T16:03:54.021Z" }, -] - -[[package]] -name = "jupyter-client" -version = "8.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jupyter-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "python-dateutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyzmq", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "tornado", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload-time = "2024-09-17T10:44:17.613Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload-time = "2024-09-17T10:44:15.218Z" }, -] - -[[package]] -name = "jupyter-core" -version = "5.8.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "platformdirs", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, -] - -[[package]] -name = "linkify-it-py" -version = "2.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "uc-micro-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/ae/bb56c6828e4797ba5a4821eec7c43b8bf40f69cda4d4f5f8c8a2810ec96a/linkify-it-py-2.0.3.tar.gz", hash = "sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048", size = 27946, upload-time = "2024-02-04T14:48:04.179Z" } -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, upload-time = "2024-02-04T14:48:02.496Z" }, -] - [[package]] name = "markdown-it-py" -version = "3.0.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } 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, upload-time = "2023-06-03T06:41:11.019Z" }, -] - -[package.optional-dependencies] -linkify = [ - { name = "linkify-it-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] - -[[package]] -name = "markdownify" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "six", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/83/1b/6f2697b51eaca81f08852fd2734745af15718fea10222a1d40f8a239c4ea/markdownify-1.2.0.tar.gz", hash = "sha256:f6c367c54eb24ee953921804dfe6d6575c5e5b42c643955e7242034435de634c", size = 18771, upload-time = "2025-08-09T17:44:15.302Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/e2/7af643acb4cae0741dffffaa7f3f7c9e7ab4046724543ba1777c401d821c/markdownify-1.2.0-py3-none-any.whl", hash = "sha256:48e150a1c4993d4d50f282f725c0111bd9eb25645d41fa2f543708fd44161351", size = 15561, upload-time = "2025-08-09T17:44:14.074Z" }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] @@ -1844,18 +1529,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] -[[package]] -name = "matplotlib-inline" -version = "0.1.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, -] - [[package]] name = "mcp" version = "1.14.0" @@ -1873,9 +1546,9 @@ dependencies = [ { name = "starlette", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "uvicorn", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/fd/d6e941a52446198b73e5e4a953441f667f1469aeb06fb382d9f6729d6168/mcp-1.14.0.tar.gz", hash = "sha256:2e7d98b195e08b2abc1dc6191f6f3dc0059604ac13ee6a40f88676274787fac4", size = 454855 } +sdist = { url = "https://files.pythonhosted.org/packages/95/fd/d6e941a52446198b73e5e4a953441f667f1469aeb06fb382d9f6729d6168/mcp-1.14.0.tar.gz", hash = "sha256:2e7d98b195e08b2abc1dc6191f6f3dc0059604ac13ee6a40f88676274787fac4", size = 454855, upload-time = "2025-09-11T17:40:48.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/7b/84b0dd4c2c5a499d2c5d63fb7a1224c25fc4c8b6c24623fa7a566471480d/mcp-1.14.0-py3-none-any.whl", hash = "sha256:b2d27feba27b4c53d41b58aa7f4d090ae0cb740cbc4e339af10f8cbe54c4e19d", size = 163805 }, + { url = "https://files.pythonhosted.org/packages/04/7b/84b0dd4c2c5a499d2c5d63fb7a1224c25fc4c8b6c24623fa7a566471480d/mcp-1.14.0-py3-none-any.whl", hash = "sha256:b2d27feba27b4c53d41b58aa7f4d090ae0cb740cbc4e339af10f8cbe54c4e19d", size = 163805, upload-time = "2025-09-11T17:40:46.891Z" }, ] [package.optional-dependencies] @@ -1883,18 +1556,6 @@ ws = [ { name = "websockets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -[[package]] -name = "mdit-py-plugins" -version = "0.5.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, -] - [[package]] name = "mdurl" version = "0.1.2" @@ -1929,9 +1590,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5a/6a/dfc2fc0316b7dc4f6d24792b4a31a873b026be76792af1e0c3e65f843ef0/microsoft_agents_activity-0.3.1.tar.gz", hash = "sha256:c7567fc30f8e6f2a2d74cd65a1f7f31ade0d7ec9dd94531677d0d7b0648c77ee", size = 44886 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/6a/dfc2fc0316b7dc4f6d24792b4a31a873b026be76792af1e0c3e65f843ef0/microsoft_agents_activity-0.3.1.tar.gz", hash = "sha256:c7567fc30f8e6f2a2d74cd65a1f7f31ade0d7ec9dd94531677d0d7b0648c77ee", size = 44886, upload-time = "2025-09-09T23:19:43.044Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8b/50ce2243e2900e94358f37009121145bb8224a388d95d704856aa2686667/microsoft_agents_activity-0.3.1-py3-none-any.whl", hash = "sha256:d7fc2e9cf2843ec8d6d42608b808b159a12cbb61e1fc7d7b1aaf29899f20746a", size = 111904 }, + { url = "https://files.pythonhosted.org/packages/25/8b/50ce2243e2900e94358f37009121145bb8224a388d95d704856aa2686667/microsoft_agents_activity-0.3.1-py3-none-any.whl", hash = "sha256:d7fc2e9cf2843ec8d6d42608b808b159a12cbb61e1fc7d7b1aaf29899f20746a", size = 111904, upload-time = "2025-09-09T23:19:50.722Z" }, ] [[package]] @@ -1941,9 +1602,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "microsoft-agents-hosting-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/a5/2381ffd14d6a584f9f7ab80c7b6c634f658ea651b38702eb403c930d8396/microsoft_agents_copilotstudio_client-0.3.1.tar.gz", hash = "sha256:c529209241c9d11b7a6e8696f96a3d43121c10b49e44f00e5066f9cf5256f4f3", size = 5024 } +sdist = { url = "https://files.pythonhosted.org/packages/e9/a5/2381ffd14d6a584f9f7ab80c7b6c634f658ea651b38702eb403c930d8396/microsoft_agents_copilotstudio_client-0.3.1.tar.gz", hash = "sha256:c529209241c9d11b7a6e8696f96a3d43121c10b49e44f00e5066f9cf5256f4f3", size = 5024, upload-time = "2025-09-09T23:19:44.833Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/97/35/8b4e9c691f2ce89653007f358519bbadff1fe0d495c3723c9dbbfa962a33/microsoft_agents_copilotstudio_client-0.3.1-py3-none-any.whl", hash = "sha256:cac7485405325b990202452c9c14848cbdb25d13e6cdaf7bd3eca3a5c1fb3989", size = 7420 }, + { url = "https://files.pythonhosted.org/packages/97/35/8b4e9c691f2ce89653007f358519bbadff1fe0d495c3723c9dbbfa962a33/microsoft_agents_copilotstudio_client-0.3.1-py3-none-any.whl", hash = "sha256:cac7485405325b990202452c9c14848cbdb25d13e6cdaf7bd3eca3a5c1fb3989", size = 7420, upload-time = "2025-09-09T23:19:52.287Z" }, ] [[package]] @@ -1957,9 +1618,9 @@ dependencies = [ { name = "pyjwt", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "python-dotenv", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/14/a1365e0bab1486c2d16aabeb192ca90715794edf4e68be4815c245884420/microsoft_agents_hosting_core-0.3.1.tar.gz", hash = "sha256:0b76bda10e7a54ff3c86e56cbabaad5ac7a4c2a076c9833af3b2f4c86fa85e89", size = 81137 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/14/a1365e0bab1486c2d16aabeb192ca90715794edf4e68be4815c245884420/microsoft_agents_hosting_core-0.3.1.tar.gz", hash = "sha256:0b76bda10e7a54ff3c86e56cbabaad5ac7a4c2a076c9833af3b2f4c86fa85e89", size = 81137, upload-time = "2025-09-09T23:19:46.73Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/1b/543ddaa2daf8593911a02a07a6a78366d4a6a0053ec86a557c19fa97b60e/microsoft_agents_hosting_core-0.3.1-py3-none-any.whl", hash = "sha256:a4b41556b15321b74f539c5a0a89f70955459b7ec57e9e4b24e61bba27f1cbbc", size = 94573 }, + { url = "https://files.pythonhosted.org/packages/f0/1b/543ddaa2daf8593911a02a07a6a78366d4a6a0053ec86a557c19fa97b60e/microsoft_agents_hosting_core-0.3.1-py3-none-any.whl", hash = "sha256:a4b41556b15321b74f539c5a0a89f70955459b7ec57e9e4b24e61bba27f1cbbc", size = 94573, upload-time = "2025-09-09T23:19:53.855Z" }, ] [[package]] @@ -2116,39 +1777,39 @@ dependencies = [ { name = "tomli", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/14/a3/931e09fc02d7ba96da65266884da4e4a8806adcdb8a57faaacc6edf1d538/mypy-1.18.1.tar.gz", hash = "sha256:9e988c64ad3ac5987f43f5154f884747faf62141b7f842e87465b45299eea5a9", size = 3448447 } +sdist = { url = "https://files.pythonhosted.org/packages/14/a3/931e09fc02d7ba96da65266884da4e4a8806adcdb8a57faaacc6edf1d538/mypy-1.18.1.tar.gz", hash = "sha256:9e988c64ad3ac5987f43f5154f884747faf62141b7f842e87465b45299eea5a9", size = 3448447, upload-time = "2025-09-11T23:00:47.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/06/29ea5a34c23938ae93bc0040eb2900eb3f0f2ef4448cc59af37ab3ddae73/mypy-1.18.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2761b6ae22a2b7d8e8607fb9b81ae90bc2e95ec033fd18fa35e807af6c657763", size = 12811535 }, - { url = "https://files.pythonhosted.org/packages/a8/40/04c38cb04fa9f1dc224b3e9634021a92c47b1569f1c87dfe6e63168883bb/mypy-1.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b10e3ea7f2eec23b4929a3fabf84505da21034a4f4b9613cda81217e92b74f3", size = 11897559 }, - { url = "https://files.pythonhosted.org/packages/46/bf/4c535bd45ea86cebbc1a3b6a781d442f53a4883f322ebd2d442db6444d0b/mypy-1.18.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:261fbfced030228bc0f724d5d92f9ae69f46373bdfd0e04a533852677a11dbea", size = 12507430 }, - { url = "https://files.pythonhosted.org/packages/e2/e1/cbefb16f2be078d09e28e0b9844e981afb41f6ffc85beb68b86c6976e641/mypy-1.18.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4dc6b34a1c6875e6286e27d836a35c0d04e8316beac4482d42cfea7ed2527df8", size = 13243717 }, - { url = "https://files.pythonhosted.org/packages/65/e8/3e963da63176f16ca9caea7fa48f1bc8766de317cd961528c0391565fd47/mypy-1.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1cabb353194d2942522546501c0ff75c4043bf3b63069cb43274491b44b773c9", size = 13492052 }, - { url = "https://files.pythonhosted.org/packages/4b/09/d5d70c252a3b5b7530662d145437bd1de15f39fa0b48a27ee4e57d254aa1/mypy-1.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:738b171690c8e47c93569635ee8ec633d2cdb06062f510b853b5f233020569a9", size = 9765846 }, - { url = "https://files.pythonhosted.org/packages/32/28/47709d5d9e7068b26c0d5189c8137c8783e81065ad1102b505214a08b548/mypy-1.18.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c903857b3e28fc5489e54042684a9509039ea0aedb2a619469438b544ae1961", size = 12734635 }, - { url = "https://files.pythonhosted.org/packages/7c/12/ee5c243e52497d0e59316854041cf3b3130131b92266d0764aca4dec3c00/mypy-1.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a0c8392c19934c2b6c65566d3a6abdc6b51d5da7f5d04e43f0eb627d6eeee65", size = 11817287 }, - { url = "https://files.pythonhosted.org/packages/48/bd/2aeb950151005fe708ab59725afed7c4aeeb96daf844f86a05d4b8ac34f8/mypy-1.18.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f85eb7efa2ec73ef63fc23b8af89c2fe5bf2a4ad985ed2d3ff28c1bb3c317c92", size = 12430464 }, - { url = "https://files.pythonhosted.org/packages/71/e8/7a20407aafb488acb5734ad7fb5e8c2ef78d292ca2674335350fa8ebef67/mypy-1.18.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:82ace21edf7ba8af31c3308a61dc72df30500f4dbb26f99ac36b4b80809d7e94", size = 13164555 }, - { url = "https://files.pythonhosted.org/packages/e8/c9/5f39065252e033b60f397096f538fb57c1d9fd70a7a490f314df20dd9d64/mypy-1.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a2dfd53dfe632f1ef5d161150a4b1f2d0786746ae02950eb3ac108964ee2975a", size = 13359222 }, - { url = "https://files.pythonhosted.org/packages/85/b6/d54111ef3c1e55992cd2ec9b8b6ce9c72a407423e93132cae209f7e7ba60/mypy-1.18.1-cp311-cp311-win_amd64.whl", hash = "sha256:320f0ad4205eefcb0e1a72428dde0ad10be73da9f92e793c36228e8ebf7298c0", size = 9760441 }, - { url = "https://files.pythonhosted.org/packages/e7/14/1c3f54d606cb88a55d1567153ef3a8bc7b74702f2ff5eb64d0994f9e49cb/mypy-1.18.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:502cde8896be8e638588b90fdcb4c5d5b8c1b004dfc63fd5604a973547367bb9", size = 12911082 }, - { url = "https://files.pythonhosted.org/packages/90/83/235606c8b6d50a8eba99773add907ce1d41c068edb523f81eb0d01603a83/mypy-1.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7509549b5e41be279afc1228242d0e397f1af2919a8f2877ad542b199dc4083e", size = 11919107 }, - { url = "https://files.pythonhosted.org/packages/ca/25/4e2ce00f8d15b99d0c68a2536ad63e9eac033f723439ef80290ec32c1ff5/mypy-1.18.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5956ecaabb3a245e3f34100172abca1507be687377fe20e24d6a7557e07080e2", size = 12472551 }, - { url = "https://files.pythonhosted.org/packages/32/bb/92642a9350fc339dd9dcefcf6862d171b52294af107d521dce075f32f298/mypy-1.18.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8750ceb014a96c9890421c83f0db53b0f3b8633e2864c6f9bc0a8e93951ed18d", size = 13340554 }, - { url = "https://files.pythonhosted.org/packages/cd/ee/38d01db91c198fb6350025d28f9719ecf3c8f2c55a0094bfbf3ef478cc9a/mypy-1.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fb89ea08ff41adf59476b235293679a6eb53a7b9400f6256272fb6029bec3ce5", size = 13530933 }, - { url = "https://files.pythonhosted.org/packages/da/8d/6d991ae631f80d58edbf9d7066e3f2a96e479dca955d9a968cd6e90850a3/mypy-1.18.1-cp312-cp312-win_amd64.whl", hash = "sha256:2657654d82fcd2a87e02a33e0d23001789a554059bbf34702d623dafe353eabf", size = 9828426 }, - { url = "https://files.pythonhosted.org/packages/e4/ec/ef4a7260e1460a3071628a9277a7579e7da1b071bc134ebe909323f2fbc7/mypy-1.18.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d70d2b5baf9b9a20bc9c730015615ae3243ef47fb4a58ad7b31c3e0a59b5ef1f", size = 12918671 }, - { url = "https://files.pythonhosted.org/packages/a1/82/0ea6c3953f16223f0b8eda40c1aeac6bd266d15f4902556ae6e91f6fca4c/mypy-1.18.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8367e33506300f07a43012fc546402f283c3f8bcff1dc338636affb710154ce", size = 11913023 }, - { url = "https://files.pythonhosted.org/packages/ae/ef/5e2057e692c2690fc27b3ed0a4dbde4388330c32e2576a23f0302bc8358d/mypy-1.18.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:913f668ec50c3337b89df22f973c1c8f0b29ee9e290a8b7fe01cc1ef7446d42e", size = 12473355 }, - { url = "https://files.pythonhosted.org/packages/98/43/b7e429fc4be10e390a167b0cd1810d41cb4e4add4ae50bab96faff695a3b/mypy-1.18.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a0e70b87eb27b33209fa4792b051c6947976f6ab829daa83819df5f58330c71", size = 13346944 }, - { url = "https://files.pythonhosted.org/packages/89/4e/899dba0bfe36bbd5b7c52e597de4cf47b5053d337b6d201a30e3798e77a6/mypy-1.18.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c378d946e8a60be6b6ede48c878d145546fb42aad61df998c056ec151bf6c746", size = 13512574 }, - { url = "https://files.pythonhosted.org/packages/f5/f8/7661021a5b0e501b76440454d786b0f01bb05d5c4b125fcbda02023d0250/mypy-1.18.1-cp313-cp313-win_amd64.whl", hash = "sha256:2cd2c1e0f3a7465f22731987fff6fc427e3dcbb4ca5f7db5bbeaff2ff9a31f6d", size = 9837684 }, - { url = "https://files.pythonhosted.org/packages/bf/87/7b173981466219eccc64c107cf8e5ab9eb39cc304b4c07df8e7881533e4f/mypy-1.18.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ba24603c58e34dd5b096dfad792d87b304fc6470cbb1c22fd64e7ebd17edcc61", size = 12900265 }, - { url = "https://files.pythonhosted.org/packages/ae/cc/b10e65bae75b18a5ac8f81b1e8e5867677e418f0dd2c83b8e2de9ba96ebd/mypy-1.18.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ed36662fb92ae4cb3cacc682ec6656208f323bbc23d4b08d091eecfc0863d4b5", size = 11942890 }, - { url = "https://files.pythonhosted.org/packages/39/d4/aeefa07c44d09f4c2102e525e2031bc066d12e5351f66b8a83719671004d/mypy-1.18.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:040ecc95e026f71a9ad7956fea2724466602b561e6a25c2e5584160d3833aaa8", size = 12472291 }, - { url = "https://files.pythonhosted.org/packages/c6/07/711e78668ff8e365f8c19735594ea95938bff3639a4c46a905e3ed8ff2d6/mypy-1.18.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:937e3ed86cb731276706e46e03512547e43c391a13f363e08d0fee49a7c38a0d", size = 13318610 }, - { url = "https://files.pythonhosted.org/packages/ca/85/df3b2d39339c31d360ce299b418c55e8194ef3205284739b64962f6074e7/mypy-1.18.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f95cc4f01c0f1701ca3b0355792bccec13ecb2ec1c469e5b85a6ef398398b1d", size = 13513697 }, - { url = "https://files.pythonhosted.org/packages/b1/df/462866163c99ea73bb28f0eb4d415c087e30de5d36ee0f5429d42e28689b/mypy-1.18.1-cp314-cp314-win_amd64.whl", hash = "sha256:e4f16c0019d48941220ac60b893615be2f63afedaba6a0801bdcd041b96991ce", size = 9985739 }, - { url = "https://files.pythonhosted.org/packages/e0/1d/4b97d3089b48ef3d904c9ca69fab044475bd03245d878f5f0b3ea1daf7ce/mypy-1.18.1-py3-none-any.whl", hash = "sha256:b76a4de66a0ac01da1be14ecc8ae88ddea33b8380284a9e3eae39d57ebcbe26e", size = 2352212 }, + { url = "https://files.pythonhosted.org/packages/fc/06/29ea5a34c23938ae93bc0040eb2900eb3f0f2ef4448cc59af37ab3ddae73/mypy-1.18.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2761b6ae22a2b7d8e8607fb9b81ae90bc2e95ec033fd18fa35e807af6c657763", size = 12811535, upload-time = "2025-09-11T22:58:55.399Z" }, + { url = "https://files.pythonhosted.org/packages/a8/40/04c38cb04fa9f1dc224b3e9634021a92c47b1569f1c87dfe6e63168883bb/mypy-1.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b10e3ea7f2eec23b4929a3fabf84505da21034a4f4b9613cda81217e92b74f3", size = 11897559, upload-time = "2025-09-11T22:59:48.041Z" }, + { url = "https://files.pythonhosted.org/packages/46/bf/4c535bd45ea86cebbc1a3b6a781d442f53a4883f322ebd2d442db6444d0b/mypy-1.18.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:261fbfced030228bc0f724d5d92f9ae69f46373bdfd0e04a533852677a11dbea", size = 12507430, upload-time = "2025-09-11T22:59:30.415Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e1/cbefb16f2be078d09e28e0b9844e981afb41f6ffc85beb68b86c6976e641/mypy-1.18.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4dc6b34a1c6875e6286e27d836a35c0d04e8316beac4482d42cfea7ed2527df8", size = 13243717, upload-time = "2025-09-11T22:59:11.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/e8/3e963da63176f16ca9caea7fa48f1bc8766de317cd961528c0391565fd47/mypy-1.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1cabb353194d2942522546501c0ff75c4043bf3b63069cb43274491b44b773c9", size = 13492052, upload-time = "2025-09-11T23:00:09.29Z" }, + { url = "https://files.pythonhosted.org/packages/4b/09/d5d70c252a3b5b7530662d145437bd1de15f39fa0b48a27ee4e57d254aa1/mypy-1.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:738b171690c8e47c93569635ee8ec633d2cdb06062f510b853b5f233020569a9", size = 9765846, upload-time = "2025-09-11T22:58:26.198Z" }, + { url = "https://files.pythonhosted.org/packages/32/28/47709d5d9e7068b26c0d5189c8137c8783e81065ad1102b505214a08b548/mypy-1.18.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c903857b3e28fc5489e54042684a9509039ea0aedb2a619469438b544ae1961", size = 12734635, upload-time = "2025-09-11T23:00:24.983Z" }, + { url = "https://files.pythonhosted.org/packages/7c/12/ee5c243e52497d0e59316854041cf3b3130131b92266d0764aca4dec3c00/mypy-1.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a0c8392c19934c2b6c65566d3a6abdc6b51d5da7f5d04e43f0eb627d6eeee65", size = 11817287, upload-time = "2025-09-11T22:59:07.38Z" }, + { url = "https://files.pythonhosted.org/packages/48/bd/2aeb950151005fe708ab59725afed7c4aeeb96daf844f86a05d4b8ac34f8/mypy-1.18.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f85eb7efa2ec73ef63fc23b8af89c2fe5bf2a4ad985ed2d3ff28c1bb3c317c92", size = 12430464, upload-time = "2025-09-11T22:58:48.084Z" }, + { url = "https://files.pythonhosted.org/packages/71/e8/7a20407aafb488acb5734ad7fb5e8c2ef78d292ca2674335350fa8ebef67/mypy-1.18.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:82ace21edf7ba8af31c3308a61dc72df30500f4dbb26f99ac36b4b80809d7e94", size = 13164555, upload-time = "2025-09-11T23:00:13.803Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c9/5f39065252e033b60f397096f538fb57c1d9fd70a7a490f314df20dd9d64/mypy-1.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a2dfd53dfe632f1ef5d161150a4b1f2d0786746ae02950eb3ac108964ee2975a", size = 13359222, upload-time = "2025-09-11T23:00:33.469Z" }, + { url = "https://files.pythonhosted.org/packages/85/b6/d54111ef3c1e55992cd2ec9b8b6ce9c72a407423e93132cae209f7e7ba60/mypy-1.18.1-cp311-cp311-win_amd64.whl", hash = "sha256:320f0ad4205eefcb0e1a72428dde0ad10be73da9f92e793c36228e8ebf7298c0", size = 9760441, upload-time = "2025-09-11T23:00:44.826Z" }, + { url = "https://files.pythonhosted.org/packages/e7/14/1c3f54d606cb88a55d1567153ef3a8bc7b74702f2ff5eb64d0994f9e49cb/mypy-1.18.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:502cde8896be8e638588b90fdcb4c5d5b8c1b004dfc63fd5604a973547367bb9", size = 12911082, upload-time = "2025-09-11T23:00:41.465Z" }, + { url = "https://files.pythonhosted.org/packages/90/83/235606c8b6d50a8eba99773add907ce1d41c068edb523f81eb0d01603a83/mypy-1.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7509549b5e41be279afc1228242d0e397f1af2919a8f2877ad542b199dc4083e", size = 11919107, upload-time = "2025-09-11T22:58:40.903Z" }, + { url = "https://files.pythonhosted.org/packages/ca/25/4e2ce00f8d15b99d0c68a2536ad63e9eac033f723439ef80290ec32c1ff5/mypy-1.18.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5956ecaabb3a245e3f34100172abca1507be687377fe20e24d6a7557e07080e2", size = 12472551, upload-time = "2025-09-11T22:58:37.272Z" }, + { url = "https://files.pythonhosted.org/packages/32/bb/92642a9350fc339dd9dcefcf6862d171b52294af107d521dce075f32f298/mypy-1.18.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8750ceb014a96c9890421c83f0db53b0f3b8633e2864c6f9bc0a8e93951ed18d", size = 13340554, upload-time = "2025-09-11T22:59:38.756Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ee/38d01db91c198fb6350025d28f9719ecf3c8f2c55a0094bfbf3ef478cc9a/mypy-1.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fb89ea08ff41adf59476b235293679a6eb53a7b9400f6256272fb6029bec3ce5", size = 13530933, upload-time = "2025-09-11T22:59:20.228Z" }, + { url = "https://files.pythonhosted.org/packages/da/8d/6d991ae631f80d58edbf9d7066e3f2a96e479dca955d9a968cd6e90850a3/mypy-1.18.1-cp312-cp312-win_amd64.whl", hash = "sha256:2657654d82fcd2a87e02a33e0d23001789a554059bbf34702d623dafe353eabf", size = 9828426, upload-time = "2025-09-11T23:00:21.007Z" }, + { url = "https://files.pythonhosted.org/packages/e4/ec/ef4a7260e1460a3071628a9277a7579e7da1b071bc134ebe909323f2fbc7/mypy-1.18.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d70d2b5baf9b9a20bc9c730015615ae3243ef47fb4a58ad7b31c3e0a59b5ef1f", size = 12918671, upload-time = "2025-09-11T22:58:29.814Z" }, + { url = "https://files.pythonhosted.org/packages/a1/82/0ea6c3953f16223f0b8eda40c1aeac6bd266d15f4902556ae6e91f6fca4c/mypy-1.18.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8367e33506300f07a43012fc546402f283c3f8bcff1dc338636affb710154ce", size = 11913023, upload-time = "2025-09-11T23:00:29.049Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ef/5e2057e692c2690fc27b3ed0a4dbde4388330c32e2576a23f0302bc8358d/mypy-1.18.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:913f668ec50c3337b89df22f973c1c8f0b29ee9e290a8b7fe01cc1ef7446d42e", size = 12473355, upload-time = "2025-09-11T23:00:04.544Z" }, + { url = "https://files.pythonhosted.org/packages/98/43/b7e429fc4be10e390a167b0cd1810d41cb4e4add4ae50bab96faff695a3b/mypy-1.18.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a0e70b87eb27b33209fa4792b051c6947976f6ab829daa83819df5f58330c71", size = 13346944, upload-time = "2025-09-11T22:58:23.024Z" }, + { url = "https://files.pythonhosted.org/packages/89/4e/899dba0bfe36bbd5b7c52e597de4cf47b5053d337b6d201a30e3798e77a6/mypy-1.18.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c378d946e8a60be6b6ede48c878d145546fb42aad61df998c056ec151bf6c746", size = 13512574, upload-time = "2025-09-11T22:59:52.152Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f8/7661021a5b0e501b76440454d786b0f01bb05d5c4b125fcbda02023d0250/mypy-1.18.1-cp313-cp313-win_amd64.whl", hash = "sha256:2cd2c1e0f3a7465f22731987fff6fc427e3dcbb4ca5f7db5bbeaff2ff9a31f6d", size = 9837684, upload-time = "2025-09-11T22:58:44.454Z" }, + { url = "https://files.pythonhosted.org/packages/bf/87/7b173981466219eccc64c107cf8e5ab9eb39cc304b4c07df8e7881533e4f/mypy-1.18.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ba24603c58e34dd5b096dfad792d87b304fc6470cbb1c22fd64e7ebd17edcc61", size = 12900265, upload-time = "2025-09-11T22:59:03.4Z" }, + { url = "https://files.pythonhosted.org/packages/ae/cc/b10e65bae75b18a5ac8f81b1e8e5867677e418f0dd2c83b8e2de9ba96ebd/mypy-1.18.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ed36662fb92ae4cb3cacc682ec6656208f323bbc23d4b08d091eecfc0863d4b5", size = 11942890, upload-time = "2025-09-11T23:00:00.607Z" }, + { url = "https://files.pythonhosted.org/packages/39/d4/aeefa07c44d09f4c2102e525e2031bc066d12e5351f66b8a83719671004d/mypy-1.18.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:040ecc95e026f71a9ad7956fea2724466602b561e6a25c2e5584160d3833aaa8", size = 12472291, upload-time = "2025-09-11T22:59:43.425Z" }, + { url = "https://files.pythonhosted.org/packages/c6/07/711e78668ff8e365f8c19735594ea95938bff3639a4c46a905e3ed8ff2d6/mypy-1.18.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:937e3ed86cb731276706e46e03512547e43c391a13f363e08d0fee49a7c38a0d", size = 13318610, upload-time = "2025-09-11T23:00:17.604Z" }, + { url = "https://files.pythonhosted.org/packages/ca/85/df3b2d39339c31d360ce299b418c55e8194ef3205284739b64962f6074e7/mypy-1.18.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f95cc4f01c0f1701ca3b0355792bccec13ecb2ec1c469e5b85a6ef398398b1d", size = 13513697, upload-time = "2025-09-11T22:58:59.534Z" }, + { url = "https://files.pythonhosted.org/packages/b1/df/462866163c99ea73bb28f0eb4d415c087e30de5d36ee0f5429d42e28689b/mypy-1.18.1-cp314-cp314-win_amd64.whl", hash = "sha256:e4f16c0019d48941220ac60b893615be2f63afedaba6a0801bdcd041b96991ce", size = 9985739, upload-time = "2025-09-11T22:58:51.644Z" }, + { url = "https://files.pythonhosted.org/packages/e0/1d/4b97d3089b48ef3d904c9ca69fab044475bd03245d878f5f0b3ea1daf7ce/mypy-1.18.1-py3-none-any.whl", hash = "sha256:b76a4de66a0ac01da1be14ecc8ae88ddea33b8380284a9e3eae39d57ebcbe26e", size = 2352212, upload-time = "2025-09-11T22:59:26.576Z" }, ] [[package]] @@ -2160,86 +1821,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] -[[package]] -name = "myst-nb" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "importlib-metadata", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "ipykernel", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "ipython", version = "9.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "jupyter-cache", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "myst-parser", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nbclient", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nbformat", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyyaml", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/e3/01c093f6a46be2edc0fd370cbf6d227495ea19452939b2810b36657c63d4/myst_nb-1.1.2.tar.gz", hash = "sha256:961b4005657029ca89892a4c75edbf0856c54ceaf6172368b46bf7676c1f7700", size = 78036, upload-time = "2024-09-24T13:29:47.299Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/45/cf78b2f09c46b36f486b75c34a8b48580e53b543bd9a467b3c7eb9054b70/myst_nb-1.1.2-py3-none-any.whl", hash = "sha256:9b7034e5d62640cb6daf03f9ca16ef45d0462fced27944c77aa3f98c7cdcd566", size = 80281, upload-time = "2024-09-24T13:29:45.73Z" }, -] - -[[package]] -name = "myst-parser" -version = "4.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "docutils", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "jinja2", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "markdown-it-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "mdit-py-plugins", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyyaml", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" }, -] - -[[package]] -name = "nbclient" -version = "0.10.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jupyter-client", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "jupyter-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "nbformat", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424, upload-time = "2024-12-19T10:32:27.164Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434, upload-time = "2024-12-19T10:32:24.139Z" }, -] - -[[package]] -name = "nbformat" -version = "5.10.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fastjsonschema", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "jsonschema", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "jupyter-core", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "traitlets", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, -] - -[[package]] -name = "nest-asyncio" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, -] - [[package]] name = "nodeenv" version = "1.9.1" @@ -2574,21 +2155,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/bb/3f/79b6c9a240221f5614a143eab6a0ecacdcb23b93cc35ff2b78234f68804f/opentelemetry_instrumentation_flask-0.57b0-py3-none-any.whl", hash = "sha256:5ecd614f194825725b61ee9ba8e37dcd4d3f9b5d40fef759df8650d6a91b1cb9", size = 14688, upload-time = "2025-07-29T15:42:04.162Z" }, ] -[[package]] -name = "opentelemetry-instrumentation-openai" -version = "0.47.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "opentelemetry-instrumentation", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "opentelemetry-semantic-conventions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "opentelemetry-semantic-conventions-ai", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/76/46/3e59891b433869c731131b5ececdaa3ee1d4a45d19169299b52d1397c8e5/opentelemetry_instrumentation_openai-0.47.1.tar.gz", hash = "sha256:a9ad8d898f8f03581fff1764b605d2c277381ced3083a66e7bddb951b95afb2a", size = 25411 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/4e/ee98a8e9b9d58425ff84aff63d06fdf004727cdac2cfe3a2916a1869a2e2/opentelemetry_instrumentation_openai-0.47.1-py3-none-any.whl", hash = "sha256:2bc426c1324f7e9babee8d2a02d7966562ec993da5d280c597bd29a92997e2ed", size = 35274 }, -] - [[package]] name = "opentelemetry-instrumentation-psycopg2" version = "0.57b0" @@ -2742,15 +2308,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] -[[package]] -name = "parso" -version = "0.8.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, -] - [[package]] name = "pastel" version = "0.2.1" @@ -2770,15 +2327,12 @@ wheels = [ ] [[package]] -name = "pexpect" -version = "4.9.0" +name = "pip" +version = "25.2" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ptyprocess", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/16/650289cd3f43d5a2fadfd98c68bd1e1e7f2550a1a5326768cddfbcedb2c5/pip-25.2.tar.gz", hash = "sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2", size = 1840021, upload-time = "2025-07-30T21:50:15.401Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, + { url = "https://files.pythonhosted.org/packages/b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa/pip-25.2-py3-none-any.whl", hash = "sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717", size = 1752557, upload-time = "2025-07-30T21:50:13.323Z" }, ] [[package]] @@ -2858,18 +2412,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, ] -[[package]] -name = "prompt-toolkit" -version = "3.0.52" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "wcwidth", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, -] - [[package]] name = "propcache" version = "0.3.2" @@ -2989,21 +2531,16 @@ wheels = [ ] [[package]] -name = "ptyprocess" -version = "0.7.0" +name = "py2docfx" +version = "0.1.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +dependencies = [ + { name = "pyyaml", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinx", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "wheel", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] - -[[package]] -name = "pure-eval" -version = "0.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/77b954fb853ddd3857a814e2a723b5ce2e8c0e59fbed7b83a962db714e66/py2docfx-0.1.20-py3-none-any.whl", hash = "sha256:d450e62591e8b96c5c8be2001f909ca5a1bb2e4dde8c0c8dc7ffb1aec45e4369", size = 11400026, upload-time = "2025-08-08T02:57:00.075Z" }, ] [[package]] @@ -3025,9 +2562,9 @@ dependencies = [ { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-inspection", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495 } +sdist = { url = "https://files.pythonhosted.org/packages/ff/5d/09a551ba512d7ca404d785072700d3f6727a02f6f3c24ecfd081c7cf0aa8/pydantic-2.11.9.tar.gz", hash = "sha256:6b8ffda597a14812a7975c90b82a8a2e777d9257aba3453f973acd3c032a18e2", size = 788495, upload-time = "2025-09-13T11:26:39.325Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855 }, + { url = "https://files.pythonhosted.org/packages/3e/d3/108f2006987c58e76691d5ae5d200dd3e0f532cb4e5fa3560751c3a1feba/pydantic-2.11.9-py3-none-any.whl", hash = "sha256:c42dd626f5cfc1c6950ce6205ea58c93efa406da65f479dcb4029d5934857da2", size = 444855, upload-time = "2025-09-13T11:26:36.909Z" }, ] [[package]] @@ -3131,25 +2668,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/58/f0/427018098906416f580e3cf1366d3b1abfb408a0652e9f31600c24a1903c/pydantic_settings-2.10.1-py3-none-any.whl", hash = "sha256:a60952460b99cf661dc25c29c0ef171721f98bfcb52ef8d9ea4c943d7c8cc796", size = 45235, upload-time = "2025-06-24T13:26:45.485Z" }, ] -[[package]] -name = "pydata-sphinx-theme" -version = "0.16.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "accessible-pygments", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "babel", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "beautifulsoup4", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "docutils", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pygments", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/00/20/bb50f9de3a6de69e6abd6b087b52fa2418a0418b19597601605f855ad044/pydata_sphinx_theme-0.16.1.tar.gz", hash = "sha256:a08b7f0b7f70387219dc659bff0893a7554d5eb39b59d3b8ef37b8401b7642d7", size = 2412693 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl", hash = "sha256:225331e8ac4b32682c18fcac5a57a6f717c4e632cea5dd0e247b55155faeccde", size = 6723264 }, -] - [[package]] name = "pygments" version = "2.19.2" @@ -3213,9 +2731,9 @@ dependencies = [ { name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (python_full_version < '3.13' and sys_platform == 'win32')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119 } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095 }, + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, ] [[package]] @@ -3367,77 +2885,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] -[[package]] -name = "pyzmq" -version = "27.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cffi", marker = "(implementation_name == 'pypy' and sys_platform == 'darwin') or (implementation_name == 'pypy' and sys_platform == 'linux') or (implementation_name == 'pypy' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/b9/52aa9ec2867528b54f1e60846728d8b4d84726630874fee3a91e66c7df81/pyzmq-27.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4", size = 1329850, upload-time = "2025-09-08T23:07:26.274Z" }, - { url = "https://files.pythonhosted.org/packages/99/64/5653e7b7425b169f994835a2b2abf9486264401fdef18df91ddae47ce2cc/pyzmq-27.1.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556", size = 906380, upload-time = "2025-09-08T23:07:29.78Z" }, - { url = "https://files.pythonhosted.org/packages/73/78/7d713284dbe022f6440e391bd1f3c48d9185673878034cfb3939cdf333b2/pyzmq-27.1.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b", size = 666421, upload-time = "2025-09-08T23:07:31.263Z" }, - { url = "https://files.pythonhosted.org/packages/30/76/8f099f9d6482450428b17c4d6b241281af7ce6a9de8149ca8c1c649f6792/pyzmq-27.1.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e", size = 854149, upload-time = "2025-09-08T23:07:33.17Z" }, - { url = "https://files.pythonhosted.org/packages/59/f0/37fbfff06c68016019043897e4c969ceab18bde46cd2aca89821fcf4fb2e/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526", size = 1655070, upload-time = "2025-09-08T23:07:35.205Z" }, - { url = "https://files.pythonhosted.org/packages/47/14/7254be73f7a8edc3587609554fcaa7bfd30649bf89cd260e4487ca70fdaa/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1", size = 2033441, upload-time = "2025-09-08T23:07:37.432Z" }, - { url = "https://files.pythonhosted.org/packages/22/dc/49f2be26c6f86f347e796a4d99b19167fc94503f0af3fd010ad262158822/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386", size = 1891529, upload-time = "2025-09-08T23:07:39.047Z" }, - { url = "https://files.pythonhosted.org/packages/a3/3e/154fb963ae25be70c0064ce97776c937ecc7d8b0259f22858154a9999769/pyzmq-27.1.0-cp310-cp310-win32.whl", hash = "sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda", size = 567276, upload-time = "2025-09-08T23:07:40.695Z" }, - { url = "https://files.pythonhosted.org/packages/62/b2/f4ab56c8c595abcb26b2be5fd9fa9e6899c1e5ad54964e93ae8bb35482be/pyzmq-27.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f", size = 632208, upload-time = "2025-09-08T23:07:42.298Z" }, - { url = "https://files.pythonhosted.org/packages/3b/e3/be2cc7ab8332bdac0522fdb64c17b1b6241a795bee02e0196636ec5beb79/pyzmq-27.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32", size = 559766, upload-time = "2025-09-08T23:07:43.869Z" }, - { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, - { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, - { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038, upload-time = "2025-09-08T23:07:51.234Z" }, - { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531, upload-time = "2025-09-08T23:07:52.795Z" }, - { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786, upload-time = "2025-09-08T23:07:55.047Z" }, - { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220, upload-time = "2025-09-08T23:07:57.172Z" }, - { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, - { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, - { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, - { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, - { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, - { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, - { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, - { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, - { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, - { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, - { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, - { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, - { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, - { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, - { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, - { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, - { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, - { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, - { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, - { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, - { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" }, - { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, - { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, - { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, - { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, - { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, - { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" }, - { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" }, - { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" }, - { url = "https://files.pythonhosted.org/packages/f3/81/a65e71c1552f74dec9dff91d95bafb6e0d33338a8dfefbc88aa562a20c92/pyzmq-27.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6", size = 836266, upload-time = "2025-09-08T23:09:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/58/ed/0202ca350f4f2b69faa95c6d931e3c05c3a397c184cacb84cb4f8f42f287/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90", size = 800206, upload-time = "2025-09-08T23:09:41.902Z" }, - { url = "https://files.pythonhosted.org/packages/47/42/1ff831fa87fe8f0a840ddb399054ca0009605d820e2b44ea43114f5459f4/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62", size = 567747, upload-time = "2025-09-08T23:09:43.741Z" }, - { url = "https://files.pythonhosted.org/packages/d1/db/5c4d6807434751e3f21231bee98109aa57b9b9b55e058e450d0aef59b70f/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74", size = 747371, upload-time = "2025-09-08T23:09:45.575Z" }, - { url = "https://files.pythonhosted.org/packages/26/af/78ce193dbf03567eb8c0dc30e3df2b9e56f12a670bf7eb20f9fb532c7e8a/pyzmq-27.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba", size = 544862, upload-time = "2025-09-08T23:09:47.448Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, - { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, - { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371, upload-time = "2025-09-08T23:09:54.563Z" }, - { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, -] - [[package]] name = "qdrant-client" version = "1.15.1" @@ -3457,18 +2904,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/33/d8df6a2b214ffbe4138db9a1efe3248f67dc3c671f82308bea1582ecbbb7/qdrant_client-1.15.1-py3-none-any.whl", hash = "sha256:2b975099b378382f6ca1cfb43f0d59e541be6e16a5892f282a4b8de7eff5cb63", size = 337331, upload-time = "2025-07-31T19:35:17.539Z" }, ] -[[package]] -name = "redis" -version = "6.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "async-timeout", marker = "(python_full_version < '3.11.3' and sys_platform == 'darwin') or (python_full_version < '3.11.3' and sys_platform == 'linux') or (python_full_version < '3.11.3' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0d/d6/e8b92798a5bd67d659d51a18170e91c16ac3b59738d91894651ee255ed49/redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010", size = 4647399, upload-time = "2025-08-07T08:10:11.441Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/02/89e2ed7e85db6c93dfa9e8f691c5087df4e3551ab39081a4d7c6d1f90e05/redis-6.4.0-py3-none-any.whl", hash = "sha256:f0544fa9604264e9464cdf4814e7d4830f74b165d52f2a330a760a88dd248b7f", size = 279847, upload-time = "2025-08-07T08:10:09.84Z" }, -] - [[package]] name = "referencing" version = "0.36.2" @@ -3524,15 +2959,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, ] -[[package]] -name = "roman-numerals-py" -version = "3.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/76/48fd56d17c5bdbdf65609abbc67288728a98ed4c02919428d4f52d23b24b/roman_numerals_py-3.1.0.tar.gz", hash = "sha256:be4bf804f083a4ce001b5eb7e3c0862479d10f94c936f6c4e5f250aa5ff5bd2d", size = 9017, upload-time = "2025-02-22T07:34:54.333Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, -] - [[package]] name = "rpds-py" version = "0.27.1" @@ -3672,26 +3098,26 @@ wheels = [ name = "ruff" version = "0.13.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6e/1a/1f4b722862840295bcaba8c9e5261572347509548faaa99b2d57ee7bfe6a/ruff-0.13.0.tar.gz", hash = "sha256:5b4b1ee7eb35afae128ab94459b13b2baaed282b1fb0f472a73c82c996c8ae60", size = 5372863 } +sdist = { url = "https://files.pythonhosted.org/packages/6e/1a/1f4b722862840295bcaba8c9e5261572347509548faaa99b2d57ee7bfe6a/ruff-0.13.0.tar.gz", hash = "sha256:5b4b1ee7eb35afae128ab94459b13b2baaed282b1fb0f472a73c82c996c8ae60", size = 5372863, upload-time = "2025-09-10T16:25:37.917Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ac/fe/6f87b419dbe166fd30a991390221f14c5b68946f389ea07913e1719741e0/ruff-0.13.0-py3-none-linux_armv6l.whl", hash = "sha256:137f3d65d58ee828ae136a12d1dc33d992773d8f7644bc6b82714570f31b2004", size = 12187826 }, - { url = "https://files.pythonhosted.org/packages/e4/25/c92296b1fc36d2499e12b74a3fdb230f77af7bdf048fad7b0a62e94ed56a/ruff-0.13.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:21ae48151b66e71fd111b7d79f9ad358814ed58c339631450c66a4be33cc28b9", size = 12933428 }, - { url = "https://files.pythonhosted.org/packages/44/cf/40bc7221a949470307d9c35b4ef5810c294e6cfa3caafb57d882731a9f42/ruff-0.13.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:64de45f4ca5441209e41742d527944635a05a6e7c05798904f39c85bafa819e3", size = 12095543 }, - { url = "https://files.pythonhosted.org/packages/f1/03/8b5ff2a211efb68c63a1d03d157e924997ada87d01bebffbd13a0f3fcdeb/ruff-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2c653ae9b9d46e0ef62fc6fbf5b979bda20a0b1d2b22f8f7eb0cde9f4963b8", size = 12312489 }, - { url = "https://files.pythonhosted.org/packages/37/fc/2336ef6d5e9c8d8ea8305c5f91e767d795cd4fc171a6d97ef38a5302dadc/ruff-0.13.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4cec632534332062bc9eb5884a267b689085a1afea9801bf94e3ba7498a2d207", size = 11991631 }, - { url = "https://files.pythonhosted.org/packages/39/7f/f6d574d100fca83d32637d7f5541bea2f5e473c40020bbc7fc4a4d5b7294/ruff-0.13.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd628101d9f7d122e120ac7c17e0a0f468b19bc925501dbe03c1cb7f5415b24", size = 13720602 }, - { url = "https://files.pythonhosted.org/packages/fd/c8/a8a5b81d8729b5d1f663348d11e2a9d65a7a9bd3c399763b1a51c72be1ce/ruff-0.13.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:afe37db8e1466acb173bb2a39ca92df00570e0fd7c94c72d87b51b21bb63efea", size = 14697751 }, - { url = "https://files.pythonhosted.org/packages/57/f5/183ec292272ce7ec5e882aea74937f7288e88ecb500198b832c24debc6d3/ruff-0.13.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f96a8d90bb258d7d3358b372905fe7333aaacf6c39e2408b9f8ba181f4b6ef2", size = 14095317 }, - { url = "https://files.pythonhosted.org/packages/9f/8d/7f9771c971724701af7926c14dab31754e7b303d127b0d3f01116faef456/ruff-0.13.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b5e3d883e4f924c5298e3f2ee0f3085819c14f68d1e5b6715597681433f153", size = 13144418 }, - { url = "https://files.pythonhosted.org/packages/a8/a6/7985ad1778e60922d4bef546688cd8a25822c58873e9ff30189cfe5dc4ab/ruff-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03447f3d18479df3d24917a92d768a89f873a7181a064858ea90a804a7538991", size = 13370843 }, - { url = "https://files.pythonhosted.org/packages/64/1c/bafdd5a7a05a50cc51d9f5711da704942d8dd62df3d8c70c311e98ce9f8a/ruff-0.13.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fbc6b1934eb1c0033da427c805e27d164bb713f8e273a024a7e86176d7f462cf", size = 13321891 }, - { url = "https://files.pythonhosted.org/packages/bc/3e/7817f989cb9725ef7e8d2cee74186bf90555279e119de50c750c4b7a72fe/ruff-0.13.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a8ab6a3e03665d39d4a25ee199d207a488724f022db0e1fe4002968abdb8001b", size = 12119119 }, - { url = "https://files.pythonhosted.org/packages/58/07/9df080742e8d1080e60c426dce6e96a8faf9a371e2ce22eef662e3839c95/ruff-0.13.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2a5c62f8ccc6dd2fe259917482de7275cecc86141ee10432727c4816235bc41", size = 11961594 }, - { url = "https://files.pythonhosted.org/packages/6a/f4/ae1185349197d26a2316840cb4d6c3fba61d4ac36ed728bf0228b222d71f/ruff-0.13.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b7b85ca27aeeb1ab421bc787009831cffe6048faae08ad80867edab9f2760945", size = 12933377 }, - { url = "https://files.pythonhosted.org/packages/b6/39/e776c10a3b349fc8209a905bfb327831d7516f6058339a613a8d2aaecacd/ruff-0.13.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:79ea0c44a3032af768cabfd9616e44c24303af49d633b43e3a5096e009ebe823", size = 13418555 }, - { url = "https://files.pythonhosted.org/packages/46/09/dca8df3d48e8b3f4202bf20b1658898e74b6442ac835bfe2c1816d926697/ruff-0.13.0-py3-none-win32.whl", hash = "sha256:4e473e8f0e6a04e4113f2e1de12a5039579892329ecc49958424e5568ef4f768", size = 12141613 }, - { url = "https://files.pythonhosted.org/packages/61/21/0647eb71ed99b888ad50e44d8ec65d7148babc0e242d531a499a0bbcda5f/ruff-0.13.0-py3-none-win_amd64.whl", hash = "sha256:48e5c25c7a3713eea9ce755995767f4dcd1b0b9599b638b12946e892123d1efb", size = 13258250 }, - { url = "https://files.pythonhosted.org/packages/e1/a3/03216a6a86c706df54422612981fb0f9041dbb452c3401501d4a22b942c9/ruff-0.13.0-py3-none-win_arm64.whl", hash = "sha256:ab80525317b1e1d38614addec8ac954f1b3e662de9d59114ecbf771d00cf613e", size = 12312357 }, + { url = "https://files.pythonhosted.org/packages/ac/fe/6f87b419dbe166fd30a991390221f14c5b68946f389ea07913e1719741e0/ruff-0.13.0-py3-none-linux_armv6l.whl", hash = "sha256:137f3d65d58ee828ae136a12d1dc33d992773d8f7644bc6b82714570f31b2004", size = 12187826, upload-time = "2025-09-10T16:24:39.5Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/c92296b1fc36d2499e12b74a3fdb230f77af7bdf048fad7b0a62e94ed56a/ruff-0.13.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:21ae48151b66e71fd111b7d79f9ad358814ed58c339631450c66a4be33cc28b9", size = 12933428, upload-time = "2025-09-10T16:24:43.866Z" }, + { url = "https://files.pythonhosted.org/packages/44/cf/40bc7221a949470307d9c35b4ef5810c294e6cfa3caafb57d882731a9f42/ruff-0.13.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:64de45f4ca5441209e41742d527944635a05a6e7c05798904f39c85bafa819e3", size = 12095543, upload-time = "2025-09-10T16:24:46.638Z" }, + { url = "https://files.pythonhosted.org/packages/f1/03/8b5ff2a211efb68c63a1d03d157e924997ada87d01bebffbd13a0f3fcdeb/ruff-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2c653ae9b9d46e0ef62fc6fbf5b979bda20a0b1d2b22f8f7eb0cde9f4963b8", size = 12312489, upload-time = "2025-09-10T16:24:49.556Z" }, + { url = "https://files.pythonhosted.org/packages/37/fc/2336ef6d5e9c8d8ea8305c5f91e767d795cd4fc171a6d97ef38a5302dadc/ruff-0.13.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4cec632534332062bc9eb5884a267b689085a1afea9801bf94e3ba7498a2d207", size = 11991631, upload-time = "2025-09-10T16:24:53.439Z" }, + { url = "https://files.pythonhosted.org/packages/39/7f/f6d574d100fca83d32637d7f5541bea2f5e473c40020bbc7fc4a4d5b7294/ruff-0.13.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd628101d9f7d122e120ac7c17e0a0f468b19bc925501dbe03c1cb7f5415b24", size = 13720602, upload-time = "2025-09-10T16:24:56.392Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c8/a8a5b81d8729b5d1f663348d11e2a9d65a7a9bd3c399763b1a51c72be1ce/ruff-0.13.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:afe37db8e1466acb173bb2a39ca92df00570e0fd7c94c72d87b51b21bb63efea", size = 14697751, upload-time = "2025-09-10T16:24:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/57/f5/183ec292272ce7ec5e882aea74937f7288e88ecb500198b832c24debc6d3/ruff-0.13.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f96a8d90bb258d7d3358b372905fe7333aaacf6c39e2408b9f8ba181f4b6ef2", size = 14095317, upload-time = "2025-09-10T16:25:03.025Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8d/7f9771c971724701af7926c14dab31754e7b303d127b0d3f01116faef456/ruff-0.13.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b5e3d883e4f924c5298e3f2ee0f3085819c14f68d1e5b6715597681433f153", size = 13144418, upload-time = "2025-09-10T16:25:06.272Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a6/7985ad1778e60922d4bef546688cd8a25822c58873e9ff30189cfe5dc4ab/ruff-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03447f3d18479df3d24917a92d768a89f873a7181a064858ea90a804a7538991", size = 13370843, upload-time = "2025-09-10T16:25:09.965Z" }, + { url = "https://files.pythonhosted.org/packages/64/1c/bafdd5a7a05a50cc51d9f5711da704942d8dd62df3d8c70c311e98ce9f8a/ruff-0.13.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fbc6b1934eb1c0033da427c805e27d164bb713f8e273a024a7e86176d7f462cf", size = 13321891, upload-time = "2025-09-10T16:25:12.969Z" }, + { url = "https://files.pythonhosted.org/packages/bc/3e/7817f989cb9725ef7e8d2cee74186bf90555279e119de50c750c4b7a72fe/ruff-0.13.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a8ab6a3e03665d39d4a25ee199d207a488724f022db0e1fe4002968abdb8001b", size = 12119119, upload-time = "2025-09-10T16:25:16.621Z" }, + { url = "https://files.pythonhosted.org/packages/58/07/9df080742e8d1080e60c426dce6e96a8faf9a371e2ce22eef662e3839c95/ruff-0.13.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2a5c62f8ccc6dd2fe259917482de7275cecc86141ee10432727c4816235bc41", size = 11961594, upload-time = "2025-09-10T16:25:19.49Z" }, + { url = "https://files.pythonhosted.org/packages/6a/f4/ae1185349197d26a2316840cb4d6c3fba61d4ac36ed728bf0228b222d71f/ruff-0.13.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b7b85ca27aeeb1ab421bc787009831cffe6048faae08ad80867edab9f2760945", size = 12933377, upload-time = "2025-09-10T16:25:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/b6/39/e776c10a3b349fc8209a905bfb327831d7516f6058339a613a8d2aaecacd/ruff-0.13.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:79ea0c44a3032af768cabfd9616e44c24303af49d633b43e3a5096e009ebe823", size = 13418555, upload-time = "2025-09-10T16:25:25.681Z" }, + { url = "https://files.pythonhosted.org/packages/46/09/dca8df3d48e8b3f4202bf20b1658898e74b6442ac835bfe2c1816d926697/ruff-0.13.0-py3-none-win32.whl", hash = "sha256:4e473e8f0e6a04e4113f2e1de12a5039579892329ecc49958424e5568ef4f768", size = 12141613, upload-time = "2025-09-10T16:25:28.664Z" }, + { url = "https://files.pythonhosted.org/packages/61/21/0647eb71ed99b888ad50e44d8ec65d7148babc0e242d531a499a0bbcda5f/ruff-0.13.0-py3-none-win_amd64.whl", hash = "sha256:48e5c25c7a3713eea9ce755995767f4dcd1b0b9599b638b12946e892123d1efb", size = 13258250, upload-time = "2025-09-10T16:25:31.773Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a3/03216a6a86c706df54422612981fb0f9041dbb452c3401501d4a22b942c9/ruff-0.13.0-py3-none-win_arm64.whl", hash = "sha256:ab80525317b1e1d38614addec8ac954f1b3e662de9d59114ecbf771d00cf613e", size = 12312357, upload-time = "2025-09-10T16:25:35.595Z" }, ] [[package]] @@ -3721,161 +3147,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, ] -[[package]] -name = "soupsieve" -version = "2.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, -] - [[package]] name = "sphinx" -version = "8.1.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and sys_platform == 'linux'", - "python_full_version < '3.11' and sys_platform == 'win32'", -] -dependencies = [ - { name = "alabaster", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "babel", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "imagesize", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "jinja2", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "pygments", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "requests", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "snowballstemmer", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-applehelp", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-devhelp", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-htmlhelp", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-jsmath", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-qthelp", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-serializinghtml", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "tomli", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125, upload-time = "2024-10-13T20:27:10.448Z" }, -] - -[[package]] -name = "sphinx" -version = "8.2.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and sys_platform == 'linux'", - "python_full_version >= '3.13' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", -] -dependencies = [ - { name = "alabaster", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "babel", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "imagesize", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "jinja2", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "pygments", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "requests", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "roman-numerals-py", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "snowballstemmer", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-applehelp", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-devhelp", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-htmlhelp", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-jsmath", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-qthelp", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinxcontrib-serializinghtml", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl", hash = "sha256:4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3", size = 3589741, upload-time = "2025-03-02T22:31:56.836Z" }, -] - -[[package]] -name = "sphinx-autobuild" -version = "2024.10.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11' and sys_platform == 'darwin'", - "python_full_version < '3.11' and sys_platform == 'linux'", - "python_full_version < '3.11' and sys_platform == 'win32'", -] -dependencies = [ - { name = "colorama", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "starlette", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "uvicorn", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "watchfiles", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "websockets", marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023, upload-time = "2024-10-02T23:15:30.172Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908, upload-time = "2024-10-02T23:15:28.739Z" }, -] - -[[package]] -name = "sphinx-autobuild" -version = "2025.8.25" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.13' and sys_platform == 'darwin'", - "python_full_version == '3.12.*' and sys_platform == 'darwin'", - "python_full_version == '3.11.*' and sys_platform == 'darwin'", - "python_full_version >= '3.13' and sys_platform == 'linux'", - "python_full_version == '3.12.*' and sys_platform == 'linux'", - "python_full_version == '3.11.*' and sys_platform == 'linux'", - "python_full_version >= '3.13' and sys_platform == 'win32'", - "python_full_version == '3.12.*' and sys_platform == 'win32'", - "python_full_version == '3.11.*' and sys_platform == 'win32'", -] -dependencies = [ - { name = "colorama", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "starlette", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "uvicorn", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "watchfiles", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "websockets", marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e0/3c/a59a3a453d4133777f7ed2e83c80b7dc817d43c74b74298ca0af869662ad/sphinx_autobuild-2025.8.25.tar.gz", hash = "sha256:9cf5aab32853c8c31af572e4fecdc09c997e2b8be5a07daf2a389e270e85b213", size = 15200, upload-time = "2025-08-25T18:44:55.436Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/20/56411b52f917696995f5ad27d2ea7e9492c84a043c5b49a3a3173573cd93/sphinx_autobuild-2025.8.25-py3-none-any.whl", hash = "sha256:b750ac7d5a18603e4665294323fd20f6dcc0a984117026d1986704fa68f0379a", size = 12535, upload-time = "2025-08-25T18:44:54.164Z" }, -] - -[[package]] -name = "sphinx-copybutton" -version = "0.5.2" +version = "6.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, + { name = "alabaster", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "babel", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "imagesize", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "jinja2", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "packaging", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pygments", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "requests", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "snowballstemmer", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-applehelp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-devhelp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-htmlhelp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-jsmath", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-qthelp", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "sphinxcontrib-serializinghtml", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } +sdist = { url = "https://files.pythonhosted.org/packages/db/0b/a0f60c4abd8a69bd5b0d20edde8a8d8d9d4ca825bbd920d328d248fd0290/Sphinx-6.1.3.tar.gz", hash = "sha256:0dac3b698538ffef41716cf97ba26c1c7788dba73ce6f150c1ff5b4720786dd2", size = 6663266, upload-time = "2023-01-10T15:58:38.349Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, -] - -[[package]] -name = "sphinx-design" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338, upload-time = "2024-08-02T13:48:42.106Z" }, + { url = "https://files.pythonhosted.org/packages/2e/2c/22a20486cad91a66f4f70bd88c20c8bb306ae719cbba93d7debae7efa80d/sphinx-6.1.3-py3-none-any.whl", hash = "sha256:807d1cb3d6be87eb78a381c3e70ebd8d346b9a25f3753e9947e866b2786865fc", size = 3027954, upload-time = "2023-01-10T15:58:34.907Z" }, ] [[package]] @@ -3932,19 +3228,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, ] -[[package]] -name = "sphinxext-rediraffe" -version = "0.2.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1f/b4/e5fbb493f796430230189a1ce5f9beff1ac1b98619fc71ed35deca6059a5/sphinxext-rediraffe-0.2.7.tar.gz", hash = "sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d", size = 8735, upload-time = "2021-04-16T11:42:28.206Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/4f/c8797e796199e55cf6c8979ecdf5f4b09b81e93f87b3193c759faea63263/sphinxext_rediraffe-0.2.7-py3-none-any.whl", hash = "sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c", size = 8267, upload-time = "2021-04-16T11:42:26.95Z" }, -] - [[package]] name = "sqlalchemy" version = "2.0.43" @@ -4002,20 +3285,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/10/c78f463b4ef22eef8491f218f692be838282cd65480f6e423d7730dfd1fb/sse_starlette-3.0.2-py3-none-any.whl", hash = "sha256:16b7cbfddbcd4eaca11f7b586f3b8a080f1afe952c15813455b162edea619e5a", size = 11297, upload-time = "2025-07-27T09:07:43.268Z" }, ] -[[package]] -name = "stack-data" -version = "0.6.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "asttokens", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "executing", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pure-eval", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, -] - [[package]] name = "starlette" version = "0.48.0" @@ -4024,18 +3293,9 @@ dependencies = [ { name = "anyio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux') or (python_full_version < '3.13' and sys_platform == 'win32')" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949 } +sdist = { url = "https://files.pythonhosted.org/packages/a7/a5/d6f429d43394057b67a6b5bbe6eae2f77a6bf7459d961fdb224bf206eee6/starlette-0.48.0.tar.gz", hash = "sha256:7e8cee469a8ab2352911528110ce9088fdc6a37d9876926e73da7ce4aa4c7a46", size = 2652949, upload-time = "2025-09-13T08:41:05.699Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/72/2db2f49247d0a18b4f1bb9a5a39a0162869acf235f3a96418363947b3d46/starlette-0.48.0-py3-none-any.whl", hash = "sha256:0764ca97b097582558ecb498132ed0c7d942f233f365b86ba37770e026510659", size = 73736 }, -] - -[[package]] -name = "tabulate" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/fe/802052aecb21e3797b8f7902564ab6ea0d60ff8ca23952079064155d1ae1/tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", size = 81090, upload-time = "2022-10-06T17:21:48.54Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252, upload-time = "2022-10-06T17:21:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/be/72/2db2f49247d0a18b4f1bb9a5a39a0162869acf235f3a96418363947b3d46/starlette-0.48.0-py3-none-any.whl", hash = "sha256:0764ca97b097582558ecb498132ed0c7d942f233f365b86ba37770e026510659", size = 73736, upload-time = "2025-09-13T08:41:03.869Z" }, ] [[package]] @@ -4086,25 +3346,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, ] -[[package]] -name = "tornado" -version = "6.5.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, - { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, - { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, - { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, - { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, - { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, - { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, - { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, - { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, - { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, -] - [[package]] name = "tqdm" version = "4.67.1" @@ -4117,15 +3358,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, ] -[[package]] -name = "traitlets" -version = "5.14.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, -] - [[package]] name = "typing-extensions" version = "4.15.0" @@ -4147,15 +3379,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] -[[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, upload-time = "2024-02-09T16:52:01.654Z" } -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, upload-time = "2024-02-09T16:52:00.371Z" }, -] - [[package]] name = "urllib3" version = "2.5.0" @@ -4169,26 +3392,26 @@ wheels = [ name = "uv" version = "0.8.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/4c/c270c6b8ed3e8c7fe38ea0b99df9eff09c332421b93d55a158371f75220e/uv-0.8.17.tar.gz", hash = "sha256:2afd4525a53c8ab3a11a5a15093c503d27da67e76257a649b05e4f0bc2ebb5ae", size = 3615060 } +sdist = { url = "https://files.pythonhosted.org/packages/6f/4c/c270c6b8ed3e8c7fe38ea0b99df9eff09c332421b93d55a158371f75220e/uv-0.8.17.tar.gz", hash = "sha256:2afd4525a53c8ab3a11a5a15093c503d27da67e76257a649b05e4f0bc2ebb5ae", size = 3615060, upload-time = "2025-09-10T21:51:25.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/7d/bbaa45c88b2c91e02714a8a5c9e787c47e4898bddfdd268569163492ba45/uv-0.8.17-py3-none-linux_armv6l.whl", hash = "sha256:c51c9633ca93ef63c07df2443941e6264efd2819cc9faabfd9fe11899c6a0d6a", size = 20242144 }, - { url = "https://files.pythonhosted.org/packages/65/34/609b72034df0c62bcfb0c0ad4b11e2b55e537c0f0817588b5337d3dcca71/uv-0.8.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c28fba6d7bb5c34ade2c8da5000faebe8425a287f42a043ca01ceb24ebc81590", size = 19363081 }, - { url = "https://files.pythonhosted.org/packages/b6/bc/9417df48f0c18a9d54c2444096e03f2f56a3534c5b869f50ac620729cbc8/uv-0.8.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b009f1ec9e28de00f76814ad66e35aaae82c98a0f24015de51943dcd1c2a1895", size = 17943513 }, - { url = "https://files.pythonhosted.org/packages/63/1c/14fd54c852fd592a2b5da4b7960f3bf4a15c7e51eb20eaddabe8c8cca32d/uv-0.8.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:84d56ae50ca71aec032577adf9737974554a82a94e52cee57722745656c1d383", size = 19507222 }, - { url = "https://files.pythonhosted.org/packages/be/47/f6a68cc310feca37c965bcbd57eb999e023d35eaeda9c9759867bf3ed232/uv-0.8.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:85c2140f8553b9a4387a7395dc30cd151ef94046785fe8b198f13f2c380fb39b", size = 19865652 }, - { url = "https://files.pythonhosted.org/packages/ab/6a/fdeb2d4a2635a6927c6d549b07177bcaf6ce15bdef58e8253e75c1b70f54/uv-0.8.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2076119783e4a6d3c9e25638956cb123f0eabf4d7d407d9661cdf7f84818dcb9", size = 20831760 }, - { url = "https://files.pythonhosted.org/packages/d0/4c/bd58b8a76015aa9ac49d6b4e1211ae1ca98a0aade0c49e1a5f645fb5cd38/uv-0.8.17-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:707a55660d302924fdbcb509e63dfec8842e19d35b69bcc17af76c25db15ad6f", size = 22209056 }, - { url = "https://files.pythonhosted.org/packages/7e/2e/28f59c00a2ed6532502fb1e27da9394e505fb7b41cc0274475104b43561b/uv-0.8.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1824b76911a14aaa9eee65ad9e180e6a4d2d7c86826232c2f28ae86aee56ed0e", size = 21871684 }, - { url = "https://files.pythonhosted.org/packages/5a/1d/a8a4fc08de1f767316467e7a1989bb125734b7ed9cd98ce8969386a70653/uv-0.8.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bb9b515cc813fb1b08f1e7592f76e437e2fb44945e53cde4fee11dee3b16d0c3", size = 21145154 }, - { url = "https://files.pythonhosted.org/packages/8f/35/cb47d2d07a383c07b0e5043c6fe5555f0fd79683c6d7f9760222987c8be9/uv-0.8.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d30d02fb65193309fc12a20f9e1a9fab67f469d3e487a254ca1145fd06788f", size = 21106619 }, - { url = "https://files.pythonhosted.org/packages/6e/93/c310f0153b9dfe79bdd7f7eaef6380a8545c8939dbfc4e6bdee8f3ee7050/uv-0.8.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3941cecd9a6a46d3d4505753912c9cf3e8ae5eea30b9d0813f3656210f8c5d01", size = 19777591 }, - { url = "https://files.pythonhosted.org/packages/6c/4f/971d3c84c2f09cf8df4536c33644e6b97e10a259d8630a0c1696c1fa6e94/uv-0.8.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:cd0ad366cfe4cbe9212bd660b5b9f3a827ff35a7601cefdac2d153bfc8079eb7", size = 20845039 }, - { url = "https://files.pythonhosted.org/packages/4a/29/8ad9038e75cb91f54b81cc933dd14fcfa92fa6f8706117d43d4251a8a662/uv-0.8.17-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:505854bc75c497b95d2c65590291dc820999a4a7d9dfab4f44a9434a6cff7b5f", size = 19820370 }, - { url = "https://files.pythonhosted.org/packages/f2/c9/fc8482d1e7dfe187c6e03dcefbac0db41a5dd72aa7b017c0f80f91a04444/uv-0.8.17-py3-none-musllinux_1_1_i686.whl", hash = "sha256:dc479f661da449df37d68b36fdffa641e89fb53ad38c16a5c9f98f3211785b63", size = 20289951 }, - { url = "https://files.pythonhosted.org/packages/2d/84/ad878ed045f02aa973be46636c802d494f8270caf5ea8bd04b7bbc68aa23/uv-0.8.17-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a1d11cd805be6d137ffef4a8227905f87f459031c645ac5031c30a3bcd08abd6", size = 21234644 }, - { url = "https://files.pythonhosted.org/packages/f8/03/3fa2641513922988e641050b3adbc87de527f44c2cc8328510703616be6a/uv-0.8.17-py3-none-win32.whl", hash = "sha256:d13a616eb0b2b33c7aa09746cc85860101d595655b58653f0b499af19f33467c", size = 19216757 }, - { url = "https://files.pythonhosted.org/packages/1a/c4/0082f437bac162ab95e5a3a389a184c122d45eb5593960aab92fdf80374b/uv-0.8.17-py3-none-win_amd64.whl", hash = "sha256:cf85b84b81b41d57a9b6eeded8473ec06ace8ee959ad0bb57e102b5ad023bd34", size = 21125811 }, - { url = "https://files.pythonhosted.org/packages/50/a2/29f57b118b3492c9d5ab1a99ba4906e7d7f8b658881d31bc2c4408d64d07/uv-0.8.17-py3-none-win_arm64.whl", hash = "sha256:64d649a8c4c3732b05dc712544963b004cf733d95fdc5d26f43c5493553ff0a7", size = 19564631 }, + { url = "https://files.pythonhosted.org/packages/b9/7d/bbaa45c88b2c91e02714a8a5c9e787c47e4898bddfdd268569163492ba45/uv-0.8.17-py3-none-linux_armv6l.whl", hash = "sha256:c51c9633ca93ef63c07df2443941e6264efd2819cc9faabfd9fe11899c6a0d6a", size = 20242144, upload-time = "2025-09-10T21:50:18.081Z" }, + { url = "https://files.pythonhosted.org/packages/65/34/609b72034df0c62bcfb0c0ad4b11e2b55e537c0f0817588b5337d3dcca71/uv-0.8.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c28fba6d7bb5c34ade2c8da5000faebe8425a287f42a043ca01ceb24ebc81590", size = 19363081, upload-time = "2025-09-10T21:50:22.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/bc/9417df48f0c18a9d54c2444096e03f2f56a3534c5b869f50ac620729cbc8/uv-0.8.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b009f1ec9e28de00f76814ad66e35aaae82c98a0f24015de51943dcd1c2a1895", size = 17943513, upload-time = "2025-09-10T21:50:25.824Z" }, + { url = "https://files.pythonhosted.org/packages/63/1c/14fd54c852fd592a2b5da4b7960f3bf4a15c7e51eb20eaddabe8c8cca32d/uv-0.8.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:84d56ae50ca71aec032577adf9737974554a82a94e52cee57722745656c1d383", size = 19507222, upload-time = "2025-09-10T21:50:29.237Z" }, + { url = "https://files.pythonhosted.org/packages/be/47/f6a68cc310feca37c965bcbd57eb999e023d35eaeda9c9759867bf3ed232/uv-0.8.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:85c2140f8553b9a4387a7395dc30cd151ef94046785fe8b198f13f2c380fb39b", size = 19865652, upload-time = "2025-09-10T21:50:32.87Z" }, + { url = "https://files.pythonhosted.org/packages/ab/6a/fdeb2d4a2635a6927c6d549b07177bcaf6ce15bdef58e8253e75c1b70f54/uv-0.8.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2076119783e4a6d3c9e25638956cb123f0eabf4d7d407d9661cdf7f84818dcb9", size = 20831760, upload-time = "2025-09-10T21:50:37.803Z" }, + { url = "https://files.pythonhosted.org/packages/d0/4c/bd58b8a76015aa9ac49d6b4e1211ae1ca98a0aade0c49e1a5f645fb5cd38/uv-0.8.17-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:707a55660d302924fdbcb509e63dfec8842e19d35b69bcc17af76c25db15ad6f", size = 22209056, upload-time = "2025-09-10T21:50:41.749Z" }, + { url = "https://files.pythonhosted.org/packages/7e/2e/28f59c00a2ed6532502fb1e27da9394e505fb7b41cc0274475104b43561b/uv-0.8.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1824b76911a14aaa9eee65ad9e180e6a4d2d7c86826232c2f28ae86aee56ed0e", size = 21871684, upload-time = "2025-09-10T21:50:45.331Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1d/a8a4fc08de1f767316467e7a1989bb125734b7ed9cd98ce8969386a70653/uv-0.8.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bb9b515cc813fb1b08f1e7592f76e437e2fb44945e53cde4fee11dee3b16d0c3", size = 21145154, upload-time = "2025-09-10T21:50:50.388Z" }, + { url = "https://files.pythonhosted.org/packages/8f/35/cb47d2d07a383c07b0e5043c6fe5555f0fd79683c6d7f9760222987c8be9/uv-0.8.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d30d02fb65193309fc12a20f9e1a9fab67f469d3e487a254ca1145fd06788f", size = 21106619, upload-time = "2025-09-10T21:50:54.5Z" }, + { url = "https://files.pythonhosted.org/packages/6e/93/c310f0153b9dfe79bdd7f7eaef6380a8545c8939dbfc4e6bdee8f3ee7050/uv-0.8.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3941cecd9a6a46d3d4505753912c9cf3e8ae5eea30b9d0813f3656210f8c5d01", size = 19777591, upload-time = "2025-09-10T21:50:57.765Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/971d3c84c2f09cf8df4536c33644e6b97e10a259d8630a0c1696c1fa6e94/uv-0.8.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:cd0ad366cfe4cbe9212bd660b5b9f3a827ff35a7601cefdac2d153bfc8079eb7", size = 20845039, upload-time = "2025-09-10T21:51:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/4a/29/8ad9038e75cb91f54b81cc933dd14fcfa92fa6f8706117d43d4251a8a662/uv-0.8.17-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:505854bc75c497b95d2c65590291dc820999a4a7d9dfab4f44a9434a6cff7b5f", size = 19820370, upload-time = "2025-09-10T21:51:04.616Z" }, + { url = "https://files.pythonhosted.org/packages/f2/c9/fc8482d1e7dfe187c6e03dcefbac0db41a5dd72aa7b017c0f80f91a04444/uv-0.8.17-py3-none-musllinux_1_1_i686.whl", hash = "sha256:dc479f661da449df37d68b36fdffa641e89fb53ad38c16a5c9f98f3211785b63", size = 20289951, upload-time = "2025-09-10T21:51:08.605Z" }, + { url = "https://files.pythonhosted.org/packages/2d/84/ad878ed045f02aa973be46636c802d494f8270caf5ea8bd04b7bbc68aa23/uv-0.8.17-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a1d11cd805be6d137ffef4a8227905f87f459031c645ac5031c30a3bcd08abd6", size = 21234644, upload-time = "2025-09-10T21:51:12.429Z" }, + { url = "https://files.pythonhosted.org/packages/f8/03/3fa2641513922988e641050b3adbc87de527f44c2cc8328510703616be6a/uv-0.8.17-py3-none-win32.whl", hash = "sha256:d13a616eb0b2b33c7aa09746cc85860101d595655b58653f0b499af19f33467c", size = 19216757, upload-time = "2025-09-10T21:51:16.021Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c4/0082f437bac162ab95e5a3a389a184c122d45eb5593960aab92fdf80374b/uv-0.8.17-py3-none-win_amd64.whl", hash = "sha256:cf85b84b81b41d57a9b6eeded8473ec06ace8ee959ad0bb57e102b5ad023bd34", size = 21125811, upload-time = "2025-09-10T21:51:19.397Z" }, + { url = "https://files.pythonhosted.org/packages/50/a2/29f57b118b3492c9d5ab1a99ba4906e7d7f8b658881d31bc2c4408d64d07/uv-0.8.17-py3-none-win_arm64.whl", hash = "sha256:64d649a8c4c3732b05dc712544963b004cf733d95fdc5d26f43c5493553ff0a7", size = 19564631, upload-time = "2025-09-10T21:51:22.599Z" }, ] [[package]] @@ -4220,115 +3443,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/06/04c8e804f813cf972e3262f3f8584c232de64f0cde9f703b46cf53a45090/virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026", size = 5983279, upload-time = "2025-08-13T14:24:05.111Z" }, ] -[[package]] -name = "watchfiles" -version = "1.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/9a/d451fcc97d029f5812e898fd30a53fd8c15c7bbd058fd75cfc6beb9bd761/watchfiles-1.1.0.tar.gz", hash = "sha256:693ed7ec72cbfcee399e92c895362b6e66d63dac6b91e2c11ae03d10d503e575", size = 94406, upload-time = "2025-06-15T19:06:59.42Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/dd/579d1dc57f0f895426a1211c4ef3b0cb37eb9e642bb04bdcd962b5df206a/watchfiles-1.1.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:27f30e14aa1c1e91cb653f03a63445739919aef84c8d2517997a83155e7a2fcc", size = 405757, upload-time = "2025-06-15T19:04:51.058Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a0/7a0318cd874393344d48c34d53b3dd419466adf59a29ba5b51c88dd18b86/watchfiles-1.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3366f56c272232860ab45c77c3ca7b74ee819c8e1f6f35a7125556b198bbc6df", size = 397511, upload-time = "2025-06-15T19:04:52.79Z" }, - { url = "https://files.pythonhosted.org/packages/06/be/503514656d0555ec2195f60d810eca29b938772e9bfb112d5cd5ad6f6a9e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8412eacef34cae2836d891836a7fff7b754d6bcac61f6c12ba5ca9bc7e427b68", size = 450739, upload-time = "2025-06-15T19:04:54.203Z" }, - { url = "https://files.pythonhosted.org/packages/4e/0d/a05dd9e5f136cdc29751816d0890d084ab99f8c17b86f25697288ca09bc7/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df670918eb7dd719642e05979fc84704af913d563fd17ed636f7c4783003fdcc", size = 458106, upload-time = "2025-06-15T19:04:55.607Z" }, - { url = "https://files.pythonhosted.org/packages/f1/fa/9cd16e4dfdb831072b7ac39e7bea986e52128526251038eb481effe9f48e/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7642b9bc4827b5518ebdb3b82698ada8c14c7661ddec5fe719f3e56ccd13c97", size = 484264, upload-time = "2025-06-15T19:04:57.009Z" }, - { url = "https://files.pythonhosted.org/packages/32/04/1da8a637c7e2b70e750a0308e9c8e662ada0cca46211fa9ef24a23937e0b/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:199207b2d3eeaeb80ef4411875a6243d9ad8bc35b07fc42daa6b801cc39cc41c", size = 597612, upload-time = "2025-06-15T19:04:58.409Z" }, - { url = "https://files.pythonhosted.org/packages/30/01/109f2762e968d3e58c95731a206e5d7d2a7abaed4299dd8a94597250153c/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a479466da6db5c1e8754caee6c262cd373e6e6c363172d74394f4bff3d84d7b5", size = 477242, upload-time = "2025-06-15T19:04:59.786Z" }, - { url = "https://files.pythonhosted.org/packages/b5/b8/46f58cf4969d3b7bc3ca35a98e739fa4085b0657a1540ccc29a1a0bc016f/watchfiles-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:935f9edd022ec13e447e5723a7d14456c8af254544cefbc533f6dd276c9aa0d9", size = 453148, upload-time = "2025-06-15T19:05:01.103Z" }, - { url = "https://files.pythonhosted.org/packages/a5/cd/8267594263b1770f1eb76914940d7b2d03ee55eca212302329608208e061/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8076a5769d6bdf5f673a19d51da05fc79e2bbf25e9fe755c47595785c06a8c72", size = 626574, upload-time = "2025-06-15T19:05:02.582Z" }, - { url = "https://files.pythonhosted.org/packages/a1/2f/7f2722e85899bed337cba715723e19185e288ef361360718973f891805be/watchfiles-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86b1e28d4c37e89220e924305cd9f82866bb0ace666943a6e4196c5df4d58dcc", size = 624378, upload-time = "2025-06-15T19:05:03.719Z" }, - { url = "https://files.pythonhosted.org/packages/bf/20/64c88ec43d90a568234d021ab4b2a6f42a5230d772b987c3f9c00cc27b8b/watchfiles-1.1.0-cp310-cp310-win32.whl", hash = "sha256:d1caf40c1c657b27858f9774d5c0e232089bca9cb8ee17ce7478c6e9264d2587", size = 279829, upload-time = "2025-06-15T19:05:04.822Z" }, - { url = "https://files.pythonhosted.org/packages/39/5c/a9c1ed33de7af80935e4eac09570de679c6e21c07070aa99f74b4431f4d6/watchfiles-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a89c75a5b9bc329131115a409d0acc16e8da8dfd5867ba59f1dd66ae7ea8fa82", size = 292192, upload-time = "2025-06-15T19:05:06.348Z" }, - { url = "https://files.pythonhosted.org/packages/8b/78/7401154b78ab484ccaaeef970dc2af0cb88b5ba8a1b415383da444cdd8d3/watchfiles-1.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:c9649dfc57cc1f9835551deb17689e8d44666315f2e82d337b9f07bd76ae3aa2", size = 405751, upload-time = "2025-06-15T19:05:07.679Z" }, - { url = "https://files.pythonhosted.org/packages/76/63/e6c3dbc1f78d001589b75e56a288c47723de28c580ad715eb116639152b5/watchfiles-1.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:406520216186b99374cdb58bc48e34bb74535adec160c8459894884c983a149c", size = 397313, upload-time = "2025-06-15T19:05:08.764Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a2/8afa359ff52e99af1632f90cbf359da46184207e893a5f179301b0c8d6df/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb45350fd1dc75cd68d3d72c47f5b513cb0578da716df5fba02fff31c69d5f2d", size = 450792, upload-time = "2025-06-15T19:05:09.869Z" }, - { url = "https://files.pythonhosted.org/packages/1d/bf/7446b401667f5c64972a57a0233be1104157fc3abf72c4ef2666c1bd09b2/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11ee4444250fcbeb47459a877e5e80ed994ce8e8d20283857fc128be1715dac7", size = 458196, upload-time = "2025-06-15T19:05:11.91Z" }, - { url = "https://files.pythonhosted.org/packages/58/2f/501ddbdfa3fa874ea5597c77eeea3d413579c29af26c1091b08d0c792280/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bda8136e6a80bdea23e5e74e09df0362744d24ffb8cd59c4a95a6ce3d142f79c", size = 484788, upload-time = "2025-06-15T19:05:13.373Z" }, - { url = "https://files.pythonhosted.org/packages/61/1e/9c18eb2eb5c953c96bc0e5f626f0e53cfef4bd19bd50d71d1a049c63a575/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b915daeb2d8c1f5cee4b970f2e2c988ce6514aace3c9296e58dd64dc9aa5d575", size = 597879, upload-time = "2025-06-15T19:05:14.725Z" }, - { url = "https://files.pythonhosted.org/packages/8b/6c/1467402e5185d89388b4486745af1e0325007af0017c3384cc786fff0542/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed8fc66786de8d0376f9f913c09e963c66e90ced9aa11997f93bdb30f7c872a8", size = 477447, upload-time = "2025-06-15T19:05:15.775Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a1/ec0a606bde4853d6c4a578f9391eeb3684a9aea736a8eb217e3e00aa89a1/watchfiles-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe4371595edf78c41ef8ac8df20df3943e13defd0efcb732b2e393b5a8a7a71f", size = 453145, upload-time = "2025-06-15T19:05:17.17Z" }, - { url = "https://files.pythonhosted.org/packages/90/b9/ef6f0c247a6a35d689fc970dc7f6734f9257451aefb30def5d100d6246a5/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b7c5f6fe273291f4d414d55b2c80d33c457b8a42677ad14b4b47ff025d0893e4", size = 626539, upload-time = "2025-06-15T19:05:18.557Z" }, - { url = "https://files.pythonhosted.org/packages/34/44/6ffda5537085106ff5aaa762b0d130ac6c75a08015dd1621376f708c94de/watchfiles-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7738027989881e70e3723c75921f1efa45225084228788fc59ea8c6d732eb30d", size = 624472, upload-time = "2025-06-15T19:05:19.588Z" }, - { url = "https://files.pythonhosted.org/packages/c3/e3/71170985c48028fa3f0a50946916a14055e741db11c2e7bc2f3b61f4d0e3/watchfiles-1.1.0-cp311-cp311-win32.whl", hash = "sha256:622d6b2c06be19f6e89b1d951485a232e3b59618def88dbeda575ed8f0d8dbf2", size = 279348, upload-time = "2025-06-15T19:05:20.856Z" }, - { url = "https://files.pythonhosted.org/packages/89/1b/3e39c68b68a7a171070f81fc2561d23ce8d6859659406842a0e4bebf3bba/watchfiles-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:48aa25e5992b61debc908a61ab4d3f216b64f44fdaa71eb082d8b2de846b7d12", size = 292607, upload-time = "2025-06-15T19:05:21.937Z" }, - { url = "https://files.pythonhosted.org/packages/61/9f/2973b7539f2bdb6ea86d2c87f70f615a71a1fc2dba2911795cea25968aea/watchfiles-1.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:00645eb79a3faa70d9cb15c8d4187bb72970b2470e938670240c7998dad9f13a", size = 285056, upload-time = "2025-06-15T19:05:23.12Z" }, - { url = "https://files.pythonhosted.org/packages/f6/b8/858957045a38a4079203a33aaa7d23ea9269ca7761c8a074af3524fbb240/watchfiles-1.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9dc001c3e10de4725c749d4c2f2bdc6ae24de5a88a339c4bce32300a31ede179", size = 402339, upload-time = "2025-06-15T19:05:24.516Z" }, - { url = "https://files.pythonhosted.org/packages/80/28/98b222cca751ba68e88521fabd79a4fab64005fc5976ea49b53fa205d1fa/watchfiles-1.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9ba68ec283153dead62cbe81872d28e053745f12335d037de9cbd14bd1877f5", size = 394409, upload-time = "2025-06-15T19:05:25.469Z" }, - { url = "https://files.pythonhosted.org/packages/86/50/dee79968566c03190677c26f7f47960aff738d32087087bdf63a5473e7df/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130fc497b8ee68dce163e4254d9b0356411d1490e868bd8790028bc46c5cc297", size = 450939, upload-time = "2025-06-15T19:05:26.494Z" }, - { url = "https://files.pythonhosted.org/packages/40/45/a7b56fb129700f3cfe2594a01aa38d033b92a33dddce86c8dfdfc1247b72/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50a51a90610d0845a5931a780d8e51d7bd7f309ebc25132ba975aca016b576a0", size = 457270, upload-time = "2025-06-15T19:05:27.466Z" }, - { url = "https://files.pythonhosted.org/packages/b5/c8/fa5ef9476b1d02dc6b5e258f515fcaaecf559037edf8b6feffcbc097c4b8/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc44678a72ac0910bac46fa6a0de6af9ba1355669b3dfaf1ce5f05ca7a74364e", size = 483370, upload-time = "2025-06-15T19:05:28.548Z" }, - { url = "https://files.pythonhosted.org/packages/98/68/42cfcdd6533ec94f0a7aab83f759ec11280f70b11bfba0b0f885e298f9bd/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a543492513a93b001975ae283a51f4b67973662a375a403ae82f420d2c7205ee", size = 598654, upload-time = "2025-06-15T19:05:29.997Z" }, - { url = "https://files.pythonhosted.org/packages/d3/74/b2a1544224118cc28df7e59008a929e711f9c68ce7d554e171b2dc531352/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ac164e20d17cc285f2b94dc31c384bc3aa3dd5e7490473b3db043dd70fbccfd", size = 478667, upload-time = "2025-06-15T19:05:31.172Z" }, - { url = "https://files.pythonhosted.org/packages/8c/77/e3362fe308358dc9f8588102481e599c83e1b91c2ae843780a7ded939a35/watchfiles-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7590d5a455321e53857892ab8879dce62d1f4b04748769f5adf2e707afb9d4f", size = 452213, upload-time = "2025-06-15T19:05:32.299Z" }, - { url = "https://files.pythonhosted.org/packages/6e/17/c8f1a36540c9a1558d4faf08e909399e8133599fa359bf52ec8fcee5be6f/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:37d3d3f7defb13f62ece99e9be912afe9dd8a0077b7c45ee5a57c74811d581a4", size = 626718, upload-time = "2025-06-15T19:05:33.415Z" }, - { url = "https://files.pythonhosted.org/packages/26/45/fb599be38b4bd38032643783d7496a26a6f9ae05dea1a42e58229a20ac13/watchfiles-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7080c4bb3efd70a07b1cc2df99a7aa51d98685be56be6038c3169199d0a1c69f", size = 623098, upload-time = "2025-06-15T19:05:34.534Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e7/fdf40e038475498e160cd167333c946e45d8563ae4dd65caf757e9ffe6b4/watchfiles-1.1.0-cp312-cp312-win32.whl", hash = "sha256:cbcf8630ef4afb05dc30107bfa17f16c0896bb30ee48fc24bf64c1f970f3b1fd", size = 279209, upload-time = "2025-06-15T19:05:35.577Z" }, - { url = "https://files.pythonhosted.org/packages/3f/d3/3ae9d5124ec75143bdf088d436cba39812122edc47709cd2caafeac3266f/watchfiles-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:cbd949bdd87567b0ad183d7676feb98136cde5bb9025403794a4c0db28ed3a47", size = 292786, upload-time = "2025-06-15T19:05:36.559Z" }, - { url = "https://files.pythonhosted.org/packages/26/2f/7dd4fc8b5f2b34b545e19629b4a018bfb1de23b3a496766a2c1165ca890d/watchfiles-1.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:0a7d40b77f07be87c6faa93d0951a0fcd8cbca1ddff60a1b65d741bac6f3a9f6", size = 284343, upload-time = "2025-06-15T19:05:37.5Z" }, - { url = "https://files.pythonhosted.org/packages/d3/42/fae874df96595556a9089ade83be34a2e04f0f11eb53a8dbf8a8a5e562b4/watchfiles-1.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5007f860c7f1f8df471e4e04aaa8c43673429047d63205d1630880f7637bca30", size = 402004, upload-time = "2025-06-15T19:05:38.499Z" }, - { url = "https://files.pythonhosted.org/packages/fa/55/a77e533e59c3003d9803c09c44c3651224067cbe7fb5d574ddbaa31e11ca/watchfiles-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20ecc8abbd957046f1fe9562757903f5eaf57c3bce70929fda6c7711bb58074a", size = 393671, upload-time = "2025-06-15T19:05:39.52Z" }, - { url = "https://files.pythonhosted.org/packages/05/68/b0afb3f79c8e832e6571022611adbdc36e35a44e14f129ba09709aa4bb7a/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2f0498b7d2a3c072766dba3274fe22a183dbea1f99d188f1c6c72209a1063dc", size = 449772, upload-time = "2025-06-15T19:05:40.897Z" }, - { url = "https://files.pythonhosted.org/packages/ff/05/46dd1f6879bc40e1e74c6c39a1b9ab9e790bf1f5a2fe6c08b463d9a807f4/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:239736577e848678e13b201bba14e89718f5c2133dfd6b1f7846fa1b58a8532b", size = 456789, upload-time = "2025-06-15T19:05:42.045Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ca/0eeb2c06227ca7f12e50a47a3679df0cd1ba487ea19cf844a905920f8e95/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eff4b8d89f444f7e49136dc695599a591ff769300734446c0a86cba2eb2f9895", size = 482551, upload-time = "2025-06-15T19:05:43.781Z" }, - { url = "https://files.pythonhosted.org/packages/31/47/2cecbd8694095647406645f822781008cc524320466ea393f55fe70eed3b/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12b0a02a91762c08f7264e2e79542f76870c3040bbc847fb67410ab81474932a", size = 597420, upload-time = "2025-06-15T19:05:45.244Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7e/82abc4240e0806846548559d70f0b1a6dfdca75c1b4f9fa62b504ae9b083/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29e7bc2eee15cbb339c68445959108803dc14ee0c7b4eea556400131a8de462b", size = 477950, upload-time = "2025-06-15T19:05:46.332Z" }, - { url = "https://files.pythonhosted.org/packages/25/0d/4d564798a49bf5482a4fa9416dea6b6c0733a3b5700cb8a5a503c4b15853/watchfiles-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9481174d3ed982e269c090f780122fb59cee6c3796f74efe74e70f7780ed94c", size = 451706, upload-time = "2025-06-15T19:05:47.459Z" }, - { url = "https://files.pythonhosted.org/packages/81/b5/5516cf46b033192d544102ea07c65b6f770f10ed1d0a6d388f5d3874f6e4/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:80f811146831c8c86ab17b640801c25dc0a88c630e855e2bef3568f30434d52b", size = 625814, upload-time = "2025-06-15T19:05:48.654Z" }, - { url = "https://files.pythonhosted.org/packages/0c/dd/7c1331f902f30669ac3e754680b6edb9a0dd06dea5438e61128111fadd2c/watchfiles-1.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:60022527e71d1d1fda67a33150ee42869042bce3d0fcc9cc49be009a9cded3fb", size = 622820, upload-time = "2025-06-15T19:05:50.088Z" }, - { url = "https://files.pythonhosted.org/packages/1b/14/36d7a8e27cd128d7b1009e7715a7c02f6c131be9d4ce1e5c3b73d0e342d8/watchfiles-1.1.0-cp313-cp313-win32.whl", hash = "sha256:32d6d4e583593cb8576e129879ea0991660b935177c0f93c6681359b3654bfa9", size = 279194, upload-time = "2025-06-15T19:05:51.186Z" }, - { url = "https://files.pythonhosted.org/packages/25/41/2dd88054b849aa546dbeef5696019c58f8e0774f4d1c42123273304cdb2e/watchfiles-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:f21af781a4a6fbad54f03c598ab620e3a77032c5878f3d780448421a6e1818c7", size = 292349, upload-time = "2025-06-15T19:05:52.201Z" }, - { url = "https://files.pythonhosted.org/packages/c8/cf/421d659de88285eb13941cf11a81f875c176f76a6d99342599be88e08d03/watchfiles-1.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:5366164391873ed76bfdf618818c82084c9db7fac82b64a20c44d335eec9ced5", size = 283836, upload-time = "2025-06-15T19:05:53.265Z" }, - { url = "https://files.pythonhosted.org/packages/45/10/6faf6858d527e3599cc50ec9fcae73590fbddc1420bd4fdccfebffeedbc6/watchfiles-1.1.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:17ab167cca6339c2b830b744eaf10803d2a5b6683be4d79d8475d88b4a8a4be1", size = 400343, upload-time = "2025-06-15T19:05:54.252Z" }, - { url = "https://files.pythonhosted.org/packages/03/20/5cb7d3966f5e8c718006d0e97dfe379a82f16fecd3caa7810f634412047a/watchfiles-1.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:328dbc9bff7205c215a7807da7c18dce37da7da718e798356212d22696404339", size = 392916, upload-time = "2025-06-15T19:05:55.264Z" }, - { url = "https://files.pythonhosted.org/packages/8c/07/d8f1176328fa9e9581b6f120b017e286d2a2d22ae3f554efd9515c8e1b49/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7208ab6e009c627b7557ce55c465c98967e8caa8b11833531fdf95799372633", size = 449582, upload-time = "2025-06-15T19:05:56.317Z" }, - { url = "https://files.pythonhosted.org/packages/66/e8/80a14a453cf6038e81d072a86c05276692a1826471fef91df7537dba8b46/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8f6f72974a19efead54195bc9bed4d850fc047bb7aa971268fd9a8387c89011", size = 456752, upload-time = "2025-06-15T19:05:57.359Z" }, - { url = "https://files.pythonhosted.org/packages/5a/25/0853b3fe0e3c2f5af9ea60eb2e781eade939760239a72c2d38fc4cc335f6/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d181ef50923c29cf0450c3cd47e2f0557b62218c50b2ab8ce2ecaa02bd97e670", size = 481436, upload-time = "2025-06-15T19:05:58.447Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9e/4af0056c258b861fbb29dcb36258de1e2b857be4a9509e6298abcf31e5c9/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adb4167043d3a78280d5d05ce0ba22055c266cf8655ce942f2fb881262ff3cdf", size = 596016, upload-time = "2025-06-15T19:05:59.59Z" }, - { url = "https://files.pythonhosted.org/packages/c5/fa/95d604b58aa375e781daf350897aaaa089cff59d84147e9ccff2447c8294/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5701dc474b041e2934a26d31d39f90fac8a3dee2322b39f7729867f932b1d4", size = 476727, upload-time = "2025-06-15T19:06:01.086Z" }, - { url = "https://files.pythonhosted.org/packages/65/95/fe479b2664f19be4cf5ceeb21be05afd491d95f142e72d26a42f41b7c4f8/watchfiles-1.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b067915e3c3936966a8607f6fe5487df0c9c4afb85226613b520890049deea20", size = 451864, upload-time = "2025-06-15T19:06:02.144Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/3c4af14b93a15ce55901cd7a92e1a4701910f1768c78fb30f61d2b79785b/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:9c733cda03b6d636b4219625a4acb5c6ffb10803338e437fb614fef9516825ef", size = 625626, upload-time = "2025-06-15T19:06:03.578Z" }, - { url = "https://files.pythonhosted.org/packages/da/f5/cf6aa047d4d9e128f4b7cde615236a915673775ef171ff85971d698f3c2c/watchfiles-1.1.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:cc08ef8b90d78bfac66f0def80240b0197008e4852c9f285907377b2947ffdcb", size = 622744, upload-time = "2025-06-15T19:06:05.066Z" }, - { url = "https://files.pythonhosted.org/packages/2c/00/70f75c47f05dea6fd30df90f047765f6fc2d6eb8b5a3921379b0b04defa2/watchfiles-1.1.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:9974d2f7dc561cce3bb88dfa8eb309dab64c729de85fba32e98d75cf24b66297", size = 402114, upload-time = "2025-06-15T19:06:06.186Z" }, - { url = "https://files.pythonhosted.org/packages/53/03/acd69c48db4a1ed1de26b349d94077cca2238ff98fd64393f3e97484cae6/watchfiles-1.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c68e9f1fcb4d43798ad8814c4c1b61547b014b667216cb754e606bfade587018", size = 393879, upload-time = "2025-06-15T19:06:07.369Z" }, - { url = "https://files.pythonhosted.org/packages/2f/c8/a9a2a6f9c8baa4eceae5887fecd421e1b7ce86802bcfc8b6a942e2add834/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95ab1594377effac17110e1352989bdd7bdfca9ff0e5eeccd8c69c5389b826d0", size = 450026, upload-time = "2025-06-15T19:06:08.476Z" }, - { url = "https://files.pythonhosted.org/packages/fe/51/d572260d98388e6e2b967425c985e07d47ee6f62e6455cefb46a6e06eda5/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fba9b62da882c1be1280a7584ec4515d0a6006a94d6e5819730ec2eab60ffe12", size = 457917, upload-time = "2025-06-15T19:06:09.988Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2d/4258e52917bf9f12909b6ec314ff9636276f3542f9d3807d143f27309104/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3434e401f3ce0ed6b42569128b3d1e3af773d7ec18751b918b89cd49c14eaafb", size = 483602, upload-time = "2025-06-15T19:06:11.088Z" }, - { url = "https://files.pythonhosted.org/packages/84/99/bee17a5f341a4345fe7b7972a475809af9e528deba056f8963d61ea49f75/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa257a4d0d21fcbca5b5fcba9dca5a78011cb93c0323fb8855c6d2dfbc76eb77", size = 596758, upload-time = "2025-06-15T19:06:12.197Z" }, - { url = "https://files.pythonhosted.org/packages/40/76/e4bec1d59b25b89d2b0716b41b461ed655a9a53c60dc78ad5771fda5b3e6/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd1b3879a578a8ec2076c7961076df540b9af317123f84569f5a9ddee64ce92", size = 477601, upload-time = "2025-06-15T19:06:13.391Z" }, - { url = "https://files.pythonhosted.org/packages/1f/fa/a514292956f4a9ce3c567ec0c13cce427c158e9f272062685a8a727d08fc/watchfiles-1.1.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62cc7a30eeb0e20ecc5f4bd113cd69dcdb745a07c68c0370cea919f373f65d9e", size = 451936, upload-time = "2025-06-15T19:06:14.656Z" }, - { url = "https://files.pythonhosted.org/packages/32/5d/c3bf927ec3bbeb4566984eba8dd7a8eb69569400f5509904545576741f88/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:891c69e027748b4a73847335d208e374ce54ca3c335907d381fde4e41661b13b", size = 626243, upload-time = "2025-06-15T19:06:16.232Z" }, - { url = "https://files.pythonhosted.org/packages/e6/65/6e12c042f1a68c556802a84d54bb06d35577c81e29fba14019562479159c/watchfiles-1.1.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:12fe8eaffaf0faa7906895b4f8bb88264035b3f0243275e0bf24af0436b27259", size = 623073, upload-time = "2025-06-15T19:06:17.457Z" }, - { url = "https://files.pythonhosted.org/packages/89/ab/7f79d9bf57329e7cbb0a6fd4c7bd7d0cee1e4a8ef0041459f5409da3506c/watchfiles-1.1.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bfe3c517c283e484843cb2e357dd57ba009cff351edf45fb455b5fbd1f45b15f", size = 400872, upload-time = "2025-06-15T19:06:18.57Z" }, - { url = "https://files.pythonhosted.org/packages/df/d5/3f7bf9912798e9e6c516094db6b8932df53b223660c781ee37607030b6d3/watchfiles-1.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a9ccbf1f129480ed3044f540c0fdbc4ee556f7175e5ab40fe077ff6baf286d4e", size = 392877, upload-time = "2025-06-15T19:06:19.55Z" }, - { url = "https://files.pythonhosted.org/packages/0d/c5/54ec7601a2798604e01c75294770dbee8150e81c6e471445d7601610b495/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba0e3255b0396cac3cc7bbace76404dd72b5438bf0d8e7cefa2f79a7f3649caa", size = 449645, upload-time = "2025-06-15T19:06:20.66Z" }, - { url = "https://files.pythonhosted.org/packages/0a/04/c2f44afc3b2fce21ca0b7802cbd37ed90a29874f96069ed30a36dfe57c2b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4281cd9fce9fc0a9dbf0fc1217f39bf9cf2b4d315d9626ef1d4e87b84699e7e8", size = 457424, upload-time = "2025-06-15T19:06:21.712Z" }, - { url = "https://files.pythonhosted.org/packages/9f/b0/eec32cb6c14d248095261a04f290636da3df3119d4040ef91a4a50b29fa5/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d2404af8db1329f9a3c9b79ff63e0ae7131986446901582067d9304ae8aaf7f", size = 481584, upload-time = "2025-06-15T19:06:22.777Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e2/ca4bb71c68a937d7145aa25709e4f5d68eb7698a25ce266e84b55d591bbd/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e78b6ed8165996013165eeabd875c5dfc19d41b54f94b40e9fff0eb3193e5e8e", size = 596675, upload-time = "2025-06-15T19:06:24.226Z" }, - { url = "https://files.pythonhosted.org/packages/a1/dd/b0e4b7fb5acf783816bc950180a6cd7c6c1d2cf7e9372c0ea634e722712b/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:249590eb75ccc117f488e2fabd1bfa33c580e24b96f00658ad88e38844a040bb", size = 477363, upload-time = "2025-06-15T19:06:25.42Z" }, - { url = "https://files.pythonhosted.org/packages/69/c4/088825b75489cb5b6a761a4542645718893d395d8c530b38734f19da44d2/watchfiles-1.1.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05686b5487cfa2e2c28ff1aa370ea3e6c5accfe6435944ddea1e10d93872147", size = 452240, upload-time = "2025-06-15T19:06:26.552Z" }, - { url = "https://files.pythonhosted.org/packages/10/8c/22b074814970eeef43b7c44df98c3e9667c1f7bf5b83e0ff0201b0bd43f9/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d0e10e6f8f6dc5762adee7dece33b722282e1f59aa6a55da5d493a97282fedd8", size = 625607, upload-time = "2025-06-15T19:06:27.606Z" }, - { url = "https://files.pythonhosted.org/packages/32/fa/a4f5c2046385492b2273213ef815bf71a0d4c1943b784fb904e184e30201/watchfiles-1.1.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:af06c863f152005c7592df1d6a7009c836a247c9d8adb78fef8575a5a98699db", size = 623315, upload-time = "2025-06-15T19:06:29.076Z" }, - { url = "https://files.pythonhosted.org/packages/be/7c/a3d7c55cfa377c2f62c4ae3c6502b997186bc5e38156bafcb9b653de9a6d/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a6fd40bbb50d24976eb275ccb55cd1951dfb63dbc27cae3066a6ca5f4beabd5", size = 406748, upload-time = "2025-06-15T19:06:44.2Z" }, - { url = "https://files.pythonhosted.org/packages/38/d0/c46f1b2c0ca47f3667b144de6f0515f6d1c670d72f2ca29861cac78abaa1/watchfiles-1.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9f811079d2f9795b5d48b55a37aa7773680a5659afe34b54cc1d86590a51507d", size = 398801, upload-time = "2025-06-15T19:06:45.774Z" }, - { url = "https://files.pythonhosted.org/packages/70/9c/9a6a42e97f92eeed77c3485a43ea96723900aefa3ac739a8c73f4bff2cd7/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2726d7bfd9f76158c84c10a409b77a320426540df8c35be172444394b17f7ea", size = 451528, upload-time = "2025-06-15T19:06:46.791Z" }, - { url = "https://files.pythonhosted.org/packages/51/7b/98c7f4f7ce7ff03023cf971cd84a3ee3b790021ae7584ffffa0eb2554b96/watchfiles-1.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df32d59cb9780f66d165a9a7a26f19df2c7d24e3bd58713108b41d0ff4f929c6", size = 454095, upload-time = "2025-06-15T19:06:48.211Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6b/686dcf5d3525ad17b384fd94708e95193529b460a1b7bf40851f1328ec6e/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0ece16b563b17ab26eaa2d52230c9a7ae46cf01759621f4fbbca280e438267b3", size = 406910, upload-time = "2025-06-15T19:06:49.335Z" }, - { url = "https://files.pythonhosted.org/packages/f3/d3/71c2dcf81dc1edcf8af9f4d8d63b1316fb0a2dd90cbfd427e8d9dd584a90/watchfiles-1.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:51b81e55d40c4b4aa8658427a3ee7ea847c591ae9e8b81ef94a90b668999353c", size = 398816, upload-time = "2025-06-15T19:06:50.433Z" }, - { url = "https://files.pythonhosted.org/packages/b8/fa/12269467b2fc006f8fce4cd6c3acfa77491dd0777d2a747415f28ccc8c60/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2bcdc54ea267fe72bfc7d83c041e4eb58d7d8dc6f578dfddb52f037ce62f432", size = 451584, upload-time = "2025-06-15T19:06:51.834Z" }, - { url = "https://files.pythonhosted.org/packages/bd/d3/254cea30f918f489db09d6a8435a7de7047f8cb68584477a515f160541d6/watchfiles-1.1.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:923fec6e5461c42bd7e3fd5ec37492c6f3468be0499bc0707b4bbbc16ac21792", size = 454009, upload-time = "2025-06-15T19:06:52.896Z" }, -] - -[[package]] -name = "wcwidth" -version = "0.2.13" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, -] - [[package]] name = "websockets" version = "15.0.1" @@ -4388,6 +3502,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, ] +[[package]] +name = "wheel" +version = "0.45.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz", hash = "sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", size = 107545, upload-time = "2024-11-23T00:18:23.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494, upload-time = "2024-11-23T00:18:21.207Z" }, +] + [[package]] name = "wrapt" version = "1.17.3"