Compare commits

...

6 Commits

Author SHA1 Message Date
Alex (CrewAI)
6082003fa0 fix: update existing test for DefaultAzureCredential fallback
test_azure_raises_error_when_api_key_missing now accounts for
azure-identity being installed — DefaultAzureCredential is used as
fallback instead of raising ValueError.
2026-04-15 07:57:58 -07:00
Alex (CrewAI)
5a40d97819 fix: test failures — use non-Azure-OpenAI endpoint, assert_any_call for multi-build
- Use generic endpoint to avoid _validate_and_fix_endpoint auto-suffixing
- Use assert_any_call instead of assert_called_once_with (init builds clients too)
- 340 passed, 3 fixed
2026-04-15 06:41:38 -07:00
Alex (CrewAI)
95c6e2ec2e fix: address CI lint failures and Bugbot review feedback
- Run ruff format on completion.py
- Remove unused 'import os' from test_azure_credentials.py
- Catch ImportError in _init_clients for deferred-build path
2026-04-15 06:30:05 -07:00
Alex (CrewAI)
cbcc3a900d docs: update changelog and version for v1.14.2a4 2026-04-15 06:17:15 -07:00
Greyson LaLonde
ad5e66d1d0 feat: bump versions to 1.14.2a4 2026-04-15 02:29:06 +08:00
Greyson LaLonde
94e7d86df1 fix: stop forwarding strict mode to Bedrock Converse API
Forwarding strict and sanitizing tool schemas for strict mode causes
Bedrock Converse requests to hang until timeout. Drop strict forwarding
and schema sanitization from the Bedrock provider.
2026-04-15 02:22:50 +08:00
18 changed files with 506 additions and 38 deletions

View File

@@ -4,6 +4,30 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
icon: "clock"
mode: "wide"
---
<Update label="15 أبريل 2026">
## v1.14.2a4
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.2a4)
## ما الذي تغير
### الميزات
- إضافة تلميحات استئناف إلى إصدار أدوات المطورين عند الفشل
### إصلاحات الأخطاء
- إصلاح توجيه وضع الصرامة إلى واجهة برمجة تطبيقات Bedrock Converse
- إصلاح إصدار pytest إلى 9.0.3 لثغرة الأمان GHSA-6w46-j5rx-g56g
- رفع الحد الأدنى لـ OpenAI إلى >=2.0.0
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.14.2a3
## المساهمون
@greysonlalonde
</Update>
<Update label="13 أبريل 2026">
## v1.14.2a3

View File

@@ -4,6 +4,30 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="Apr 15, 2026">
## v1.14.2a4
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.2a4)
## What's Changed
### Features
- Add resume hints to devtools release on failure
### Bug Fixes
- Fix strict mode forwarding to Bedrock Converse API
- Fix pytest version to 9.0.3 for security vulnerability GHSA-6w46-j5rx-g56g
- Bump OpenAI lower bound to >=2.0.0
### Documentation
- Update changelog and version for v1.14.2a3
## Contributors
@greysonlalonde
</Update>
<Update label="Apr 13, 2026">
## v1.14.2a3

View File

@@ -4,6 +4,30 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
icon: "clock"
mode: "wide"
---
<Update label="2026년 4월 15일">
## v1.14.2a4
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.2a4)
## 변경 사항
### 기능
- 실패 시 devtools 릴리스에 이력서 힌트 추가
### 버그 수정
- Bedrock Converse API로의 엄격 모드 포워딩 수정
- 보안 취약점 GHSA-6w46-j5rx-g56g에 대해 pytest 버전을 9.0.3으로 수정
- OpenAI 하한을 >=2.0.0으로 상향 조정
### 문서
- v1.14.2a3에 대한 변경 로그 및 버전 업데이트
## 기여자
@greysonlalonde
</Update>
<Update label="2026년 4월 13일">
## v1.14.2a3

View File

@@ -4,6 +4,30 @@ description: "Atualizações de produto, melhorias e correções do CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="15 abr 2026">
## v1.14.2a4
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.2a4)
## O que Mudou
### Recursos
- Adicionar dicas de retomar ao release do devtools em caso de falha
### Correções de Bugs
- Corrigir o encaminhamento do modo estrito para a API Bedrock Converse
- Corrigir a versão do pytest para 9.0.3 devido à vulnerabilidade de segurança GHSA-6w46-j5rx-g56g
- Aumentar o limite inferior do OpenAI para >=2.0.0
### Documentação
- Atualizar o changelog e a versão para v1.14.2a3
## Contribuidores
@greysonlalonde
</Update>
<Update label="13 abr 2026">
## v1.14.2a3

View File

@@ -152,4 +152,4 @@ __all__ = [
"wrap_file_source",
]
__version__ = "1.14.2a3"
__version__ = "1.14.2a4"

View File

@@ -10,7 +10,7 @@ requires-python = ">=3.10, <3.14"
dependencies = [
"pytube~=15.0.0",
"requests>=2.33.0,<3",
"crewai==1.14.2a3",
"crewai==1.14.2a4",
"tiktoken~=0.8.0",
"beautifulsoup4~=4.13.4",
"python-docx~=1.2.0",

View File

@@ -305,4 +305,4 @@ __all__ = [
"ZapierActionTools",
]
__version__ = "1.14.2a3"
__version__ = "1.14.2a4"

View File

@@ -55,7 +55,7 @@ Repository = "https://github.com/crewAIInc/crewAI"
[project.optional-dependencies]
tools = [
"crewai-tools==1.14.2a3",
"crewai-tools==1.14.2a4",
]
embeddings = [
"tiktoken~=0.8.0"
@@ -94,6 +94,7 @@ google-genai = [
]
azure-ai-inference = [
"azure-ai-inference~=1.0.0b9",
"azure-identity>=1.17.0,<2",
]
anthropic = [
"anthropic~=0.73.0",

View File

@@ -46,7 +46,7 @@ def _suppress_pydantic_deprecation_warnings() -> None:
_suppress_pydantic_deprecation_warnings()
__version__ = "1.14.2a3"
__version__ = "1.14.2a4"
_telemetry_submitted = False

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]==1.14.2a3"
"crewai[tools]==1.14.2a4"
]
[project.scripts]

View File

@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]==1.14.2a3"
"crewai[tools]==1.14.2a4"
]
[project.scripts]

View File

@@ -5,7 +5,7 @@ description = "Power up your crews with {{folder_name}}"
readme = "README.md"
requires-python = ">=3.10,<3.14"
dependencies = [
"crewai[tools]==1.14.2a3"
"crewai[tools]==1.14.2a4"
]
[tool.crewai]

View File

@@ -35,6 +35,7 @@ try:
)
from azure.core.credentials import (
AzureKeyCredential,
TokenCredential,
)
from azure.core.exceptions import (
HttpResponseError,
@@ -88,6 +89,8 @@ class AzureCompletion(BaseLLM):
response_format: type[BaseModel] | None = None
is_openai_model: bool = False
is_azure_openai_endpoint: bool = False
azure_tenant_id: str | None = None
azure_client_id: str | None = None
_client: Any = PrivateAttr(default=None)
_async_client: Any = PrivateAttr(default=None)
@@ -115,6 +118,12 @@ class AzureCompletion(BaseLLM):
data["api_version"] = (
data.get("api_version") or os.getenv("AZURE_API_VERSION") or "2024-06-01"
)
data["azure_tenant_id"] = data.get("azure_tenant_id") or os.getenv(
"AZURE_TENANT_ID"
)
data["azure_client_id"] = data.get("azure_client_id") or os.getenv(
"AZURE_CLIENT_ID"
)
# Credentials and endpoint are validated lazily in `_init_clients`
# so the LLM can be constructed before deployment env vars are set.
@@ -149,7 +158,7 @@ class AzureCompletion(BaseLLM):
try:
self._client = self._build_sync_client()
self._async_client = self._build_async_client()
except ValueError:
except (ValueError, ImportError):
pass
return self
@@ -183,24 +192,89 @@ class AzureCompletion(BaseLLM):
AzureCompletion._is_azure_openai_endpoint(self.endpoint)
)
if not self.api_key:
raise ValueError(
"Azure API key is required. Set AZURE_API_KEY environment "
"variable or pass api_key parameter."
)
# Re-read identity env vars for deferred builds
if not self.azure_tenant_id:
self.azure_tenant_id = os.getenv("AZURE_TENANT_ID")
if not self.azure_client_id:
self.azure_client_id = os.getenv("AZURE_CLIENT_ID")
if not self.endpoint:
raise ValueError(
"Azure endpoint is required. Set AZURE_ENDPOINT environment "
"variable or pass endpoint parameter."
)
credential = self._resolve_credential()
client_kwargs: dict[str, Any] = {
"endpoint": self.endpoint,
"credential": AzureKeyCredential(self.api_key),
"credential": credential,
}
if self.api_version:
client_kwargs["api_version"] = self.api_version
return client_kwargs
def _resolve_credential(self) -> AzureKeyCredential | TokenCredential:
"""Resolve the Azure credential using a priority chain.
1. OIDC federation (WorkloadIdentityCredential) — auto-discovered
from AZURE_FEDERATED_TOKEN_FILE + AZURE_TENANT_ID + AZURE_CLIENT_ID
2. Client secret (ClientSecretCredential) — explicit SP credentials
3. Default chain (DefaultAzureCredential) — Managed Identity et al.
4. API key fallback (AzureKeyCredential) — existing path
"""
federated_token_file = os.getenv("AZURE_FEDERATED_TOKEN_FILE")
client_secret = os.getenv("AZURE_CLIENT_SECRET")
# Path 1: OIDC Workload Identity Federation
if federated_token_file and self.azure_tenant_id and self.azure_client_id:
try:
from azure.identity import WorkloadIdentityCredential
return WorkloadIdentityCredential(
tenant_id=self.azure_tenant_id,
client_id=self.azure_client_id,
token_file_path=federated_token_file,
)
except ImportError:
raise ImportError(
"azure-identity is required for workload identity federation. "
'Install with: uv add "crewai[azure-ai-inference]"'
) from None
# Path 2: Client Secret (Service Principal)
if client_secret and self.azure_tenant_id and self.azure_client_id:
try:
from azure.identity import ClientSecretCredential
return ClientSecretCredential(
tenant_id=self.azure_tenant_id,
client_id=self.azure_client_id,
client_secret=client_secret,
)
except ImportError:
raise ImportError(
"azure-identity is required for service principal authentication. "
'Install with: uv add "crewai[azure-ai-inference]"'
) from None
# Path 3: DefaultAzureCredential (Managed Identity, Azure CLI, etc.)
# Only attempt if azure-identity is installed and no API key is available
if not self.api_key:
try:
from azure.identity import DefaultAzureCredential
return DefaultAzureCredential()
except ImportError:
raise ValueError(
"Azure API key is required when azure-identity is not installed. "
"Set AZURE_API_KEY environment variable, pass api_key parameter, "
'or install azure-identity: uv add "crewai[azure-ai-inference]"'
) from None
# Path 4: API Key (existing path)
return AzureKeyCredential(self.api_key)
def _get_sync_client(self) -> Any:
if self._client is None:
self._client = self._build_sync_client()

View File

@@ -17,10 +17,7 @@ from crewai.utilities.agent_utils import is_context_length_exceeded
from crewai.utilities.exceptions.context_window_exceeding_exception import (
LLMContextLengthExceededError,
)
from crewai.utilities.pydantic_schema_utils import (
generate_model_description,
sanitize_tool_params_for_bedrock_strict,
)
from crewai.utilities.pydantic_schema_utils import generate_model_description
from crewai.utilities.types import LLMMessage
@@ -173,7 +170,6 @@ class ToolSpec(TypedDict, total=False):
name: Required[str]
description: Required[str]
inputSchema: ToolInputSchema
strict: bool
class ConverseToolTypeDef(TypedDict):
@@ -1988,21 +1984,10 @@ class BedrockCompletion(BaseLLM):
"description": description,
}
func_info = tool.get("function", {})
strict_enabled = bool(func_info.get("strict"))
if parameters and isinstance(parameters, dict):
schema_params = (
sanitize_tool_params_for_bedrock_strict(parameters)
if strict_enabled
else parameters
)
input_schema: ToolInputSchema = {"json": schema_params}
input_schema: ToolInputSchema = {"json": parameters}
tool_spec["inputSchema"] = input_schema
if strict_enabled:
tool_spec["strict"] = True
converse_tool: ConverseToolTypeDef = {"toolSpec": tool_spec}
converse_tools.append(converse_tool)

View File

@@ -390,16 +390,26 @@ def test_azure_raises_error_when_endpoint_missing():
def test_azure_raises_error_when_api_key_missing():
"""Credentials are validated lazily: construction succeeds, first
client build raises the descriptive error."""
"""When no API key AND azure-identity is not installed, credentials
are validated lazily: construction succeeds, first client build raises.
With azure-identity installed, DefaultAzureCredential is used instead."""
from crewai.llms.providers.azure.completion import AzureCompletion
with patch.dict(os.environ, {}, clear=True):
llm = AzureCompletion(
model="gpt-4", endpoint="https://test.openai.azure.com"
)
with pytest.raises(ValueError, match="Azure API key is required"):
llm._get_sync_client()
# With azure-identity installed, DefaultAzureCredential is used as
# fallback instead of raising. Only raises when azure-identity is
# not available.
try:
import azure.identity # noqa: F401
# azure-identity is installed — DefaultAzureCredential will be used
client = llm._get_sync_client()
assert client is not None
except ImportError:
with pytest.raises(ValueError, match="Azure API key is required"):
llm._get_sync_client()
@pytest.mark.asyncio

View File

@@ -0,0 +1,258 @@
"""Tests for Azure credential resolution chain in AzureCompletion.
Covers the four credential paths:
1. WorkloadIdentityCredential (OIDC federation)
2. ClientSecretCredential (Service Principal)
3. DefaultAzureCredential (Managed Identity / CLI fallback)
4. AzureKeyCredential (API key - existing path)
"""
from unittest.mock import patch, MagicMock
import pytest
# Use a non-Azure-OpenAI endpoint to avoid _validate_and_fix_endpoint suffixing
ENDPOINT = "https://test-ai.services.example.com"
@pytest.fixture
def _clear_azure_env(monkeypatch):
"""Remove all Azure env vars to start clean."""
for key in [
"AZURE_API_KEY", "AZURE_ENDPOINT", "AZURE_OPENAI_ENDPOINT",
"AZURE_API_BASE", "AZURE_API_VERSION", "AZURE_TENANT_ID",
"AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_FEDERATED_TOKEN_FILE",
]:
monkeypatch.delenv(key, raising=False)
@pytest.mark.usefixtures("_clear_azure_env")
class TestCredentialResolution:
"""Tests for AzureCompletion._resolve_credential."""
def test_api_key_credential_when_api_key_set(self):
"""Path 4: API key produces AzureKeyCredential."""
from crewai.llms.providers.azure.completion import AzureCompletion
from azure.core.credentials import AzureKeyCredential
completion = AzureCompletion(
model="gpt-4",
api_key="test-key",
endpoint=ENDPOINT,
)
cred = completion._resolve_credential()
assert isinstance(cred, AzureKeyCredential)
def test_api_key_from_env(self, monkeypatch):
"""Path 4: api_key picked up from AZURE_API_KEY env var."""
from crewai.llms.providers.azure.completion import AzureCompletion
from azure.core.credentials import AzureKeyCredential
monkeypatch.setenv("AZURE_API_KEY", "env-key")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
completion = AzureCompletion(model="gpt-4")
cred = completion._resolve_credential()
assert isinstance(cred, AzureKeyCredential)
def test_workload_identity_credential(self, monkeypatch, tmp_path):
"""Path 1: OIDC federation via WorkloadIdentityCredential."""
from crewai.llms.providers.azure.completion import AzureCompletion
token_file = tmp_path / "token.txt"
token_file.write_text("eyJhbGciOiJSUzI1NiJ9.test")
monkeypatch.setenv("AZURE_FEDERATED_TOKEN_FILE", str(token_file))
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_wi_cred = MagicMock()
with patch(
"azure.identity.WorkloadIdentityCredential",
return_value=mock_wi_cred,
) as mock_cls:
completion = AzureCompletion(
model="gpt-4",
azure_tenant_id="tenant-123",
azure_client_id="client-456",
)
cred = completion._resolve_credential()
assert cred is mock_wi_cred
# Called at least once with the right args (init may also call it)
mock_cls.assert_any_call(
tenant_id="tenant-123",
client_id="client-456",
token_file_path=str(token_file),
)
def test_workload_identity_from_env_vars(self, monkeypatch, tmp_path):
"""Path 1: All WI fields discovered from environment."""
from crewai.llms.providers.azure.completion import AzureCompletion
token_file = tmp_path / "token.txt"
token_file.write_text("eyJhbGciOiJSUzI1NiJ9.test")
monkeypatch.setenv("AZURE_FEDERATED_TOKEN_FILE", str(token_file))
monkeypatch.setenv("AZURE_TENANT_ID", "env-tenant")
monkeypatch.setenv("AZURE_CLIENT_ID", "env-client")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_wi_cred = MagicMock()
with patch(
"azure.identity.WorkloadIdentityCredential",
return_value=mock_wi_cred,
) as mock_cls:
completion = AzureCompletion(model="gpt-4")
cred = completion._resolve_credential()
assert cred is mock_wi_cred
mock_cls.assert_any_call(
tenant_id="env-tenant",
client_id="env-client",
token_file_path=str(token_file),
)
def test_client_secret_credential(self, monkeypatch):
"""Path 2: Service Principal with client secret."""
from crewai.llms.providers.azure.completion import AzureCompletion
monkeypatch.setenv("AZURE_CLIENT_SECRET", "sp-secret")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_cs_cred = MagicMock()
with patch(
"azure.identity.ClientSecretCredential",
return_value=mock_cs_cred,
) as mock_cls:
completion = AzureCompletion(
model="gpt-4",
azure_tenant_id="tenant-123",
azure_client_id="client-456",
)
cred = completion._resolve_credential()
assert cred is mock_cs_cred
mock_cls.assert_any_call(
tenant_id="tenant-123",
client_id="client-456",
client_secret="sp-secret",
)
def test_default_azure_credential_when_no_api_key(self, monkeypatch):
"""Path 3: DefaultAzureCredential when no api_key and no SP/WI vars."""
from crewai.llms.providers.azure.completion import AzureCompletion
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_default_cred = MagicMock()
with patch(
"azure.identity.DefaultAzureCredential",
return_value=mock_default_cred,
):
completion = AzureCompletion(model="gpt-4")
cred = completion._resolve_credential()
assert cred is mock_default_cred
def test_workload_identity_takes_priority_over_api_key(self, monkeypatch, tmp_path):
"""WI credential should take priority even when api_key is also set."""
from crewai.llms.providers.azure.completion import AzureCompletion
token_file = tmp_path / "token.txt"
token_file.write_text("eyJhbGciOiJSUzI1NiJ9.test")
monkeypatch.setenv("AZURE_FEDERATED_TOKEN_FILE", str(token_file))
monkeypatch.setenv("AZURE_API_KEY", "should-not-use-this")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_wi_cred = MagicMock()
with patch(
"azure.identity.WorkloadIdentityCredential",
return_value=mock_wi_cred,
):
completion = AzureCompletion(
model="gpt-4",
azure_tenant_id="tenant-123",
azure_client_id="client-456",
)
cred = completion._resolve_credential()
assert cred is mock_wi_cred
def test_client_secret_takes_priority_over_api_key(self, monkeypatch):
"""SP credential should take priority over API key."""
from crewai.llms.providers.azure.completion import AzureCompletion
monkeypatch.setenv("AZURE_CLIENT_SECRET", "sp-secret")
monkeypatch.setenv("AZURE_API_KEY", "should-not-use-this")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
mock_cs_cred = MagicMock()
with patch(
"azure.identity.ClientSecretCredential",
return_value=mock_cs_cred,
):
completion = AzureCompletion(
model="gpt-4",
azure_tenant_id="tenant-123",
azure_client_id="client-456",
)
cred = completion._resolve_credential()
assert cred is mock_cs_cred
def test_raises_when_no_api_key_and_no_azure_identity(self, monkeypatch):
"""ValueError when no api_key and azure-identity not installed."""
from crewai.llms.providers.azure.completion import AzureCompletion
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
with patch.dict("sys.modules", {"azure.identity": None}):
completion = AzureCompletion(model="gpt-4")
with pytest.raises(ValueError, match="Azure API key is required"):
completion._resolve_credential()
def test_endpoint_still_required(self, monkeypatch, tmp_path):
"""Endpoint is always required regardless of credential type."""
from crewai.llms.providers.azure.completion import AzureCompletion
token_file = tmp_path / "token.txt"
token_file.write_text("test-jwt")
monkeypatch.setenv("AZURE_FEDERATED_TOKEN_FILE", str(token_file))
monkeypatch.setenv("AZURE_TENANT_ID", "tenant-123")
monkeypatch.setenv("AZURE_CLIENT_ID", "client-456")
completion = AzureCompletion(model="gpt-4")
with pytest.raises(ValueError, match="Azure endpoint is required"):
completion._make_client_kwargs()
def test_deferred_build_picks_up_wi_env_vars(self, monkeypatch, tmp_path):
"""Env vars set after construction are picked up on deferred build."""
from crewai.llms.providers.azure.completion import AzureCompletion
# Construct with endpoint only — no credentials yet
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
completion = AzureCompletion(model="gpt-4")
# Now set WI env vars (simulating WI manager setting them before crew run)
token_file = tmp_path / "token.txt"
token_file.write_text("eyJhbGciOiJSUzI1NiJ9.deferred")
monkeypatch.setenv("AZURE_FEDERATED_TOKEN_FILE", str(token_file))
monkeypatch.setenv("AZURE_TENANT_ID", "deferred-tenant")
monkeypatch.setenv("AZURE_CLIENT_ID", "deferred-client")
mock_wi_cred = MagicMock()
with patch(
"azure.identity.WorkloadIdentityCredential",
return_value=mock_wi_cred,
):
kwargs = completion._make_client_kwargs()
assert kwargs["credential"] is mock_wi_cred
def test_make_client_kwargs_includes_api_version(self, monkeypatch):
"""api_version is included in client kwargs."""
from crewai.llms.providers.azure.completion import AzureCompletion
monkeypatch.setenv("AZURE_API_KEY", "test-key")
monkeypatch.setenv("AZURE_ENDPOINT", ENDPOINT)
completion = AzureCompletion(model="gpt-4", api_version="2025-01-01")
kwargs = completion._make_client_kwargs()
assert kwargs["api_version"] == "2025-01-01"
assert kwargs["endpoint"] == ENDPOINT

View File

@@ -1,3 +1,3 @@
"""CrewAI development tools."""
__version__ = "1.14.2a3"
__version__ = "1.14.2a4"

46
uv.lock generated
View File

@@ -13,7 +13,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2026-04-10T18:30:59.748668Z"
exclude-newer = "2026-04-12T13:29:14.108221482Z"
exclude-newer-span = "P3D"
[manifest]
@@ -495,6 +495,22 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7e/d6/8ebcd05b01a580f086ac9a97fb9fac65c09a4b012161cc97c21a336e880b/azure_core-1.39.0-py3-none-any.whl", hash = "sha256:4ac7b70fab5438c3f68770649a78daf97833caa83827f91df9c14e0e0ea7d34f", size = 218318, upload-time = "2026-03-19T01:31:31.25Z" },
]
[[package]]
name = "azure-identity"
version = "1.25.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "azure-core" },
{ name = "cryptography" },
{ name = "msal" },
{ name = "msal-extensions" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/0e/3a63efb48aa4a5ae2cfca61ee152fbcb668092134d3eb8bfda472dd5c617/azure_identity-1.25.3.tar.gz", hash = "sha256:ab23c0d63015f50b630ef6c6cf395e7262f439ce06e5d07a64e874c724f8d9e6", size = 286304, upload-time = "2026-03-13T01:12:20.892Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/49/9a/417b3a533e01953a7c618884df2cb05a71e7b68bdbce4fbdb62349d2a2e8/azure_identity-1.25.3-py3-none-any.whl", hash = "sha256:f4d0b956a8146f30333e071374171f3cfa7bdb8073adb8c3814b65567aa7447c", size = 192138, upload-time = "2026-03-13T01:12:22.951Z" },
]
[[package]]
name = "backoff"
version = "2.2.1"
@@ -1281,6 +1297,7 @@ aws = [
]
azure-ai-inference = [
{ name = "azure-ai-inference" },
{ name = "azure-identity" },
]
bedrock = [
{ name = "boto3" },
@@ -1335,6 +1352,7 @@ requires-dist = [
{ name = "anthropic", marker = "extra == 'anthropic'", specifier = "~=0.73.0" },
{ name = "appdirs", specifier = "~=1.4.4" },
{ name = "azure-ai-inference", marker = "extra == 'azure-ai-inference'", specifier = "~=1.0.0b9" },
{ name = "azure-identity", marker = "extra == 'azure-ai-inference'", specifier = ">=1.17.0,<2" },
{ name = "boto3", marker = "extra == 'aws'", specifier = "~=1.42.79" },
{ name = "boto3", marker = "extra == 'bedrock'", specifier = "~=1.42.79" },
{ name = "chromadb", specifier = "~=1.1.0" },
@@ -4304,6 +4322,32 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" },
]
[[package]]
name = "msal"
version = "1.36.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
{ name = "pyjwt", extra = ["crypto"] },
{ name = "requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/de/cb/b02b0f748ac668922364ccb3c3bff5b71628a05f5adfec2ba2a5c3031483/msal-1.36.0.tar.gz", hash = "sha256:3f6a4af2b036b476a4215111c4297b4e6e236ed186cd804faefba23e4990978b", size = 174217, upload-time = "2026-04-09T10:20:33.525Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/d3/414d1f0a5f6f4fe5313c2b002c54e78a3332970feb3f5fed14237aa17064/msal-1.36.0-py3-none-any.whl", hash = "sha256:36ecac30e2ff4322d956029aabce3c82301c29f0acb1ad89b94edcabb0e58ec4", size = 121547, upload-time = "2026-04-09T10:20:32.336Z" },
]
[[package]]
name = "msal-extensions"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "msal" },
]
sdist = { url = "https://files.pythonhosted.org/packages/01/99/5d239b6156eddf761a636bded1118414d161bd6b7b37a9335549ed159396/msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4", size = 23315, upload-time = "2025-03-14T23:51:03.902Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5e/75/bd9b7bb966668920f06b200e84454c8f3566b102183bc55c5473d96cb2b9/msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca", size = 20583, upload-time = "2025-03-14T23:51:03.016Z" },
]
[[package]]
name = "msgpack"
version = "1.1.2"