fix(core): pin AMP's proxy and CA first thing in import crewai

A crew run in its own process (`uv run run_crew`) never imports the CLI, so
`import crewai` is where the pin happens there. It already preceded the
project's .env, loaded by crewai.llm on import, but only by import order. The
pin is now the first import in crewai/__init__.py, and a test runs a fresh
interpreter in a project whose .env names a proxy and CA: the .env loads, and
the pin still holds only what the machine set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Joao MouraandClaude Opus 5.5 committed 2026-10-19 00:10:54 -07:00
1 parent add3bc3329
commit 7213ae4574
2 files changed
+50

No files matched your search

+5
View File
@@ -3,6 +3,11 @@ import sys
from typing import TYPE_CHECKING, Annotated, Any
import warnings
# Pin the machine's proxy and CA for AMP requests first: importing crewai.llm and
# crewai.project loads the project's .env, which must not choose where the saved
# login travels. A crew run in its own process (`uv run run_crew`) never imports
# the CLI, so this import is the pin there.
import crewai_core.plus_api # noqa: F401
from pydantic import Field, PydanticUserError
from crewai.agent.core import Agent
+45
View File
@@ -0,0 +1,45 @@
"""`import crewai` pins AMP's proxy and CA before it loads a project's .env.
A classic crew runs in its own process (`uv run run_crew`), which never imports the
CLI. There, `import crewai` is the first thing to read the project's `.env`, so the
machine's transport settings have to be captured before that happens.
"""
import json
import os
from pathlib import Path
import subprocess
import sys
from crewai_core import plus_api
def test_import_crewai_pins_the_machines_proxy_before_the_project_env_loads(
tmp_path: Path,
) -> None:
(tmp_path / ".env").write_text(
"HTTPS_PROXY=http://project-proxy.test:8080\nSSL_CERT_FILE=/project/ca.pem\n"
)
env = {key: value for key, value in os.environ.items() if not plus_api._sets_transport(key)}
probe = (
"import json, os\n"
"import crewai\n"
"from crewai_core import plus_api\n"
"print(json.dumps({'loaded': os.environ.get('HTTPS_PROXY'),"
" 'pinned': plus_api._MACHINE_TRANSPORT_ENV}))\n"
)
result = subprocess.run(
[sys.executable, "-c", probe],
cwd=tmp_path,
env=env,
capture_output=True,
text=True,
check=True,
)
seen = json.loads(result.stdout.strip().splitlines()[-1])
# crewai loaded the project's .env (so the test means something) ...
assert seen["loaded"] == "http://project-proxy.test:8080"
# ... after the pin, which holds only what the machine set: nothing.
assert seen["pinned"] == {}