mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into feature-foundry-agents
This commit is contained in:
@@ -6,16 +6,64 @@
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<!--
|
||||
Disable central package management for this project.
|
||||
This project requires explicit package references with versions specified inline rather than
|
||||
inheriting them from Directory.Packages.props. This is necessary because a Docker image will
|
||||
be created from this project, and the Docker build process only has access to this folder
|
||||
and cannot access parent folders where Directory.Packages.props resides.
|
||||
-->
|
||||
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Remove analyzer PackageReference items inherited from Directory.Packages.props.
|
||||
Note: ManagePackageVersionsCentrally only controls PackageVersion items, not PackageReference items.
|
||||
Directory.Packages.props contains both PackageVersion and PackageReference entries for analyzers,
|
||||
and the PackageReference items are always inherited through MSBuild imports regardless of the
|
||||
ManagePackageVersionsCentrally setting. We must explicitly remove them before adding our own versions.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.OpenAI" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
|
||||
<PackageReference Remove="Microsoft.CodeAnalysis.NetAnalyzers" />
|
||||
<PackageReference Remove="Microsoft.VisualStudio.Threading.Analyzers" />
|
||||
<PackageReference Remove="xunit.analyzers" />
|
||||
<PackageReference Remove="Moq.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.CodeAnalysis.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.Formatting.Analyzers" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
|
||||
<PackageReference Include="Azure.AI.AgentServer.AgentFramework" Version="1.0.0-beta.4" />
|
||||
<PackageReference Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
|
||||
<PackageReference Include="Azure.Identity" Version="1.17.0" />
|
||||
<PackageReference Include="Microsoft.Agents.AI.OpenAI" Version="1.0.0-preview.251110.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.10.2-preview.1.25552.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Add analyzers with compatible versions -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Build the application
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy files from the current directory on the host to the working directory in the container
|
||||
COPY . .
|
||||
|
||||
RUN dotnet restore
|
||||
RUN dotnet build -c Release --no-restore
|
||||
RUN dotnet publish -c Release --no-build -o /app
|
||||
|
||||
# Run the application
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final
|
||||
WORKDIR /app
|
||||
|
||||
# Copy everything needed to run the app from the "build" stage.
|
||||
COPY --from=build /app .
|
||||
|
||||
EXPOSE 8088
|
||||
ENTRYPOINT ["dotnet", "AgentWithTextSearchRag.dll"]
|
||||
@@ -4,6 +4,7 @@
|
||||
// capabilities to an AI agent. The provider runs a search against an external knowledge base
|
||||
// before each model invocation and injects the results into the model context.
|
||||
|
||||
using Azure.AI.AgentServer.AgentFramework.Extensions;
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
@@ -23,7 +24,7 @@ TextSearchProviderOptions textSearchOptions = new()
|
||||
|
||||
AIAgent agent = new AzureOpenAIClient(
|
||||
new Uri(endpoint),
|
||||
new AzureCliCredential())
|
||||
new DefaultAzureCredential())
|
||||
.GetChatClient(deploymentName)
|
||||
.CreateAIAgent(new ChatClientAgentOptions
|
||||
{
|
||||
@@ -31,16 +32,7 @@ AIAgent agent = new AzureOpenAIClient(
|
||||
AIContextProviderFactory = ctx => new TextSearchProvider(MockSearchAsync, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)
|
||||
});
|
||||
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
|
||||
Console.WriteLine(">> Asking about returns\n");
|
||||
Console.WriteLine(await agent.RunAsync("Hi! I need help understanding the return policy.", thread));
|
||||
|
||||
Console.WriteLine("\n>> Asking about shipping\n");
|
||||
Console.WriteLine(await agent.RunAsync("How long does standard shipping usually take?", thread));
|
||||
|
||||
Console.WriteLine("\n>> Asking about product care\n");
|
||||
Console.WriteLine(await agent.RunAsync("What is the best way to maintain the TrailRunner tent fabric?", thread));
|
||||
await agent.RunAIAgentAsync();
|
||||
|
||||
static Task<IEnumerable<TextSearchProvider.TextSearchResult>> MockSearchAsync(string query, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
name: AgentWithTextSearchRag
|
||||
displayName: "Text Search RAG Agent"
|
||||
description: >
|
||||
An AI agent that uses TextSearchProvider for retrieval augmented generation (RAG) capabilities.
|
||||
The agent runs searches against an external knowledge base before each model invocation and
|
||||
injects the results into the model context. It can answer questions about Contoso Outdoors
|
||||
policies and products, including return policies, refunds, shipping options, and product care
|
||||
instructions such as tent maintenance.
|
||||
metadata:
|
||||
authors:
|
||||
- Microsoft Agent Framework Team
|
||||
tags:
|
||||
- example
|
||||
- Agent Framework
|
||||
template:
|
||||
kind: hosted
|
||||
name: AgentWithTextSearchRag
|
||||
protocols:
|
||||
- protocol: responses
|
||||
version: v1
|
||||
environment_variables:
|
||||
- name: AZURE_OPENAI_ENDPOINT
|
||||
value: ${AZURE_OPENAI_ENDPOINT}
|
||||
- name: AZURE_OPENAI_DEPLOYMENT_NAME
|
||||
value: gpt-4o-mini
|
||||
resources:
|
||||
- name: "gpt-4o-mini"
|
||||
kind: model
|
||||
id: gpt-4o-mini
|
||||
@@ -0,0 +1,30 @@
|
||||
@host = http://localhost:8088
|
||||
@endpoint = {{host}}/responses
|
||||
|
||||
### Health Check
|
||||
GET {{host}}/readiness
|
||||
|
||||
### Simple string input
|
||||
POST {{endpoint}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"input": "Hi! I need help understanding the return policy."
|
||||
}
|
||||
|
||||
### Explicit input
|
||||
POST {{endpoint}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"input": [
|
||||
{
|
||||
"type": "message",
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "input_text",
|
||||
"text": "How long does standard shipping usually take?"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,18 +6,64 @@
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<!--
|
||||
Disable central package management for this project.
|
||||
This project requires explicit package references with versions specified inline rather than
|
||||
inheriting them from Directory.Packages.props. This is necessary because a Docker image will
|
||||
be created from this project, and the Docker build process only has access to this folder
|
||||
and cannot access parent folders where Directory.Packages.props resides.
|
||||
-->
|
||||
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--
|
||||
Remove analyzer PackageReference items inherited from Directory.Packages.props.
|
||||
Note: ManagePackageVersionsCentrally only controls PackageVersion items, not PackageReference items.
|
||||
Directory.Packages.props contains both PackageVersion and PackageReference entries for analyzers,
|
||||
and the PackageReference items are always inherited through MSBuild imports regardless of the
|
||||
ManagePackageVersionsCentrally setting. We must explicitly remove them before adding our own versions.
|
||||
-->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.OpenAI" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
|
||||
<PackageReference Remove="Microsoft.CodeAnalysis.NetAnalyzers" />
|
||||
<PackageReference Remove="Microsoft.VisualStudio.Threading.Analyzers" />
|
||||
<PackageReference Remove="xunit.analyzers" />
|
||||
<PackageReference Remove="Moq.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.CodeAnalysis.Analyzers" />
|
||||
<PackageReference Remove="Roslynator.Formatting.Analyzers" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Workflows\Microsoft.Agents.AI.Workflows.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.AzureAI.Persistent\Microsoft.Agents.AI.AzureAI.Persistent.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI\Microsoft.Agents.AI.csproj" />
|
||||
<PackageReference Include="Azure.AI.AgentServer.AgentFramework" Version="1.0.0-beta.4" />
|
||||
<PackageReference Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
|
||||
<PackageReference Include="Azure.Identity" Version="1.17.0" />
|
||||
<PackageReference Include="Microsoft.Agents.AI.Workflows" Version="1.0.0-preview.251110.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.10.2-preview.1.25552.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Add analyzers with compatible versions -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.12.9">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Build the application
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy files from the current directory on the host to the working directory in the container
|
||||
COPY . .
|
||||
|
||||
RUN dotnet restore
|
||||
RUN dotnet build -c Release --no-restore
|
||||
RUN dotnet publish -c Release --no-build -o /app
|
||||
|
||||
# Run the application
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final
|
||||
WORKDIR /app
|
||||
|
||||
# Copy everything needed to run the app from the "build" stage.
|
||||
COPY --from=build /app .
|
||||
|
||||
EXPOSE 8088
|
||||
ENTRYPOINT ["dotnet", "AgentsInWorkflows.dll"]
|
||||
@@ -4,6 +4,7 @@
|
||||
// Three translation agents are connected sequentially to create a translation chain:
|
||||
// English → French → Spanish → English, showing how agents can be composed as workflow executors.
|
||||
|
||||
using Azure.AI.AgentServer.AgentFramework.Extensions;
|
||||
using Azure.AI.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
@@ -14,7 +15,7 @@ using Microsoft.Extensions.AI;
|
||||
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";
|
||||
|
||||
IChatClient chatClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
|
||||
IChatClient chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
|
||||
.GetChatClient(deploymentName)
|
||||
.AsIChatClient();
|
||||
|
||||
@@ -23,26 +24,14 @@ AIAgent frenchAgent = GetTranslationAgent("French", chatClient);
|
||||
AIAgent spanishAgent = GetTranslationAgent("Spanish", chatClient);
|
||||
AIAgent englishAgent = GetTranslationAgent("English", chatClient);
|
||||
|
||||
// Build the workflow by adding executors and connecting them
|
||||
Workflow workflow = new WorkflowBuilder(frenchAgent)
|
||||
// Build the workflow and turn it into an agent
|
||||
AIAgent agent = new WorkflowBuilder(frenchAgent)
|
||||
.AddEdge(frenchAgent, spanishAgent)
|
||||
.AddEdge(spanishAgent, englishAgent)
|
||||
.Build();
|
||||
.Build()
|
||||
.AsAgent();
|
||||
|
||||
// Execute the workflow
|
||||
await using StreamingRun run = await InProcessExecution.StreamAsync(workflow, new ChatMessage(ChatRole.User, "Hello World!"));
|
||||
|
||||
// Must send the turn token to trigger the agents.
|
||||
// The agents are wrapped as executors. When they receive messages,
|
||||
// they will cache the messages and only start processing when they receive a TurnToken.
|
||||
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
|
||||
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
|
||||
{
|
||||
if (evt is AgentRunUpdateEvent executorComplete)
|
||||
{
|
||||
Console.WriteLine($"{executorComplete.ExecutorId}: {executorComplete.Data}");
|
||||
}
|
||||
}
|
||||
await agent.RunAIAgentAsync();
|
||||
|
||||
static ChatClientAgent GetTranslationAgent(string targetLanguage, IChatClient chatClient) =>
|
||||
new(chatClient, $"You are a translation assistant that translates the provided text to {targetLanguage}.");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
name: AgentsInWorkflows
|
||||
displayName: "Translation Chain Workflow Agent"
|
||||
description: >
|
||||
A workflow agent that performs sequential translation through multiple languages.
|
||||
The agent translates text from English to French, then to Spanish, and finally back
|
||||
to English, leveraging AI-powered translation capabilities in a pipeline workflow.
|
||||
metadata:
|
||||
authors:
|
||||
- Agent Framework Team
|
||||
tags:
|
||||
- example
|
||||
- Microsoft Agent Framework Team
|
||||
- workflows
|
||||
template:
|
||||
kind: hosted
|
||||
name: AgentsInWorkflows
|
||||
protocols:
|
||||
- protocol: responses
|
||||
version: v1
|
||||
environment_variables:
|
||||
- name: AZURE_OPENAI_ENDPOINT
|
||||
value: ${AZURE_OPENAI_ENDPOINT}
|
||||
- name: AZURE_OPENAI_DEPLOYMENT_NAME
|
||||
value: gpt-4o-mini
|
||||
resources:
|
||||
- name: "gpt-4o-mini"
|
||||
kind: model
|
||||
id: gpt-4o-mini
|
||||
@@ -0,0 +1,30 @@
|
||||
@host = http://localhost:8088
|
||||
@endpoint = {{host}}/responses
|
||||
|
||||
### Health Check
|
||||
GET {{host}}/readiness
|
||||
|
||||
### Simple string input
|
||||
POST {{endpoint}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"input": "Hello, how are you today?"
|
||||
}
|
||||
|
||||
### Explicit input
|
||||
POST {{endpoint}}
|
||||
Content-Type: application/json
|
||||
{
|
||||
"input": [
|
||||
{
|
||||
"type": "message",
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "input_text",
|
||||
"text": "Hello, how are you today?"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -330,11 +330,19 @@ class AnthropicClient(BaseChatClient):
|
||||
if content.has_top_level_media_type("image"):
|
||||
a_content.append({
|
||||
"type": "image",
|
||||
"source": {"data": content.uri, "media_type": content.media_type},
|
||||
"source": {
|
||||
"data": content.get_data_bytes_as_str(),
|
||||
"media_type": content.media_type,
|
||||
"type": "base64",
|
||||
},
|
||||
})
|
||||
else:
|
||||
logger.debug(f"Ignoring unsupported data content media type: {content.media_type} for now")
|
||||
case "uri":
|
||||
if content.has_top_level_media_type("image"):
|
||||
a_content.append({"type": "image", "source": {"type": "url", "url": content.uri}})
|
||||
else:
|
||||
logger.debug(f"Ignoring unsupported data content media type: {content.media_type} for now")
|
||||
case "function_call":
|
||||
a_content.append({
|
||||
"type": "tool_use",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
@@ -1,5 +1,6 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Annotated
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
@@ -9,6 +10,7 @@ from agent_framework import (
|
||||
ChatMessage,
|
||||
ChatOptions,
|
||||
ChatResponseUpdate,
|
||||
DataContent,
|
||||
FinishReason,
|
||||
FunctionCallContent,
|
||||
FunctionResultContent,
|
||||
@@ -775,3 +777,31 @@ async def test_anthropic_client_integration_ordering() -> None:
|
||||
|
||||
assert response is not None
|
||||
assert response.messages[0].text is not None
|
||||
|
||||
|
||||
@pytest.mark.flaky
|
||||
@skip_if_anthropic_integration_tests_disabled
|
||||
async def test_anthropic_client_integration_images() -> None:
|
||||
"""Integration test with images."""
|
||||
client = AnthropicClient()
|
||||
|
||||
# get a image from the assets folder
|
||||
image_path = Path(__file__).parent / "assets" / "sample_image.jpg"
|
||||
with open(image_path, "rb") as img_file: # noqa [ASYNC230]
|
||||
image_bytes = img_file.read()
|
||||
|
||||
messages = [
|
||||
ChatMessage(
|
||||
role=Role.USER,
|
||||
contents=[
|
||||
TextContent(text="Describe this image"),
|
||||
DataContent(media_type="image/jpeg", data=image_bytes),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
response = await client.get_response(messages=messages)
|
||||
|
||||
assert response is not None
|
||||
assert response.messages[0].text is not None
|
||||
assert "house" in response.messages[0].text.lower()
|
||||
|
||||
@@ -897,6 +897,9 @@ class TextReasoningContent(BaseContent):
|
||||
return self
|
||||
|
||||
|
||||
TDataContent = TypeVar("TDataContent", bound="DataContent")
|
||||
|
||||
|
||||
class DataContent(BaseContent):
|
||||
"""Represents binary data content with an associated media type (also known as a MIME type).
|
||||
|
||||
@@ -1079,8 +1082,8 @@ class DataContent(BaseContent):
|
||||
except Exception:
|
||||
return "png" # Fallback if decoding fails
|
||||
|
||||
@classmethod
|
||||
def create_data_uri_from_base64(cls, image_base64: str) -> tuple[str, str]:
|
||||
@staticmethod
|
||||
def create_data_uri_from_base64(image_base64: str) -> tuple[str, str]:
|
||||
"""Create a data URI and media type from base64 image data.
|
||||
|
||||
Args:
|
||||
@@ -1089,11 +1092,31 @@ class DataContent(BaseContent):
|
||||
Returns:
|
||||
Tuple of (data_uri, media_type)
|
||||
"""
|
||||
format_type = cls.detect_image_format_from_base64(image_base64)
|
||||
format_type = DataContent.detect_image_format_from_base64(image_base64)
|
||||
uri = f"data:image/{format_type};base64,{image_base64}"
|
||||
media_type = f"image/{format_type}"
|
||||
return uri, media_type
|
||||
|
||||
def get_data_bytes_as_str(self) -> str:
|
||||
"""Extracts and returns the base64-encoded data from the data URI.
|
||||
|
||||
Returns:
|
||||
The binary data as str.
|
||||
"""
|
||||
match = URI_PATTERN.match(self.uri)
|
||||
if not match:
|
||||
raise ValueError(f"Invalid data URI format: {self.uri}")
|
||||
return match.group("base64_data")
|
||||
|
||||
def get_data_bytes(self) -> bytes:
|
||||
"""Extracts and returns the binary data from the data URI.
|
||||
|
||||
Returns:
|
||||
The binary data as bytes.
|
||||
"""
|
||||
base64_data = self.get_data_bytes_as_str()
|
||||
return base64.b64decode(base64_data)
|
||||
|
||||
|
||||
class UriContent(BaseContent):
|
||||
"""Represents a URI content.
|
||||
|
||||
@@ -56,7 +56,7 @@ math = [
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"uv>=0.8.2,<0.9.0",
|
||||
"uv",
|
||||
"pre-commit >= 3.7",
|
||||
"ruff>=0.11.8",
|
||||
"pytest>=8.4.1",
|
||||
|
||||
@@ -39,7 +39,7 @@ dependencies = [
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"uv>=0.8.2,<0.10.0",
|
||||
"uv>=0.9,<1.0.0",
|
||||
"flit>=3.12.0",
|
||||
"pre-commit >= 3.7",
|
||||
"ruff>=0.11.8",
|
||||
|
||||
Generated
+339
-329
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user