mirror of https://github.com/microsoft/autogen.git
Lspinheiro/chore/migrate azure executor autogen ext (#3652)
* migrate code executor and tests * update extras * update dependencies and examples * fix imports * fix uv lock * add code_executor to toctree --------- Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com> Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
parent
ffb16d560a
commit
53e5951474
|
@ -8,7 +8,7 @@ See [`autogen-core`](./packages/autogen-core/) package for main functionality.
|
|||
**TL;DR**, run all checks with:
|
||||
|
||||
```sh
|
||||
uv sync
|
||||
uv sync --all-extras
|
||||
source .venv/bin/activate
|
||||
poe check
|
||||
```
|
||||
|
@ -24,7 +24,7 @@ in the current directory,
|
|||
run:
|
||||
|
||||
```sh
|
||||
uv sync
|
||||
uv sync --all-extras
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"\n",
|
||||
"## AzureContainerCodeExecutor\n",
|
||||
"\n",
|
||||
"The {py:class}`~autogen_core.components.code_executor.AzureContainerCodeExecutor` class is a python code executor that creates and executes arbitrary python code on a default Serverless code interpreter session. Its interface is as follows\n",
|
||||
"The {py:class}`~autogen_ext.code_executor.aca_dynamic_sessions.AzureContainerCodeExecutor` class is a python code executor that creates and executes arbitrary python code on a default Serverless code interpreter session. Its interface is as follows\n",
|
||||
"\n",
|
||||
"### Initialization\n",
|
||||
"\n",
|
||||
|
@ -65,7 +65,8 @@
|
|||
"\n",
|
||||
"from anyio import open_file\n",
|
||||
"from autogen_core.base import CancellationToken\n",
|
||||
"from autogen_core.components.code_executor import AzureContainerCodeExecutor, CodeBlock\n",
|
||||
"from autogen_core.components.code_executor import CodeBlock\n",
|
||||
"from autogen_ext.code_executor.aca_dynamic_sessions import AzureContainerCodeExecutor\n",
|
||||
"from azure.identity import DefaultAzureCredential"
|
||||
]
|
||||
},
|
||||
|
|
|
@ -40,6 +40,7 @@ python/autogen_core/autogen_core
|
|||
|
||||
python/autogen_ext/autogen_ext
|
||||
python/autogen_ext/autogen_ext.tools
|
||||
python/autogen_ext/autogen_ext.code_executor
|
||||
```
|
||||
|
||||
::::{grid} 1 2 2 3
|
||||
|
|
|
@ -22,7 +22,6 @@ dependencies = [
|
|||
"grpcio~=1.62.0",
|
||||
"protobuf~=4.25.1",
|
||||
"tiktoken",
|
||||
"azure-core",
|
||||
"docker~=7.0",
|
||||
"opentelemetry-api~=1.27.0",
|
||||
"asyncio_atexit"
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
from ._base import CodeBlock, CodeExecutor, CodeResult
|
||||
from ._func_with_reqs import Alias, FunctionWithRequirements, Import, ImportFromModule, with_requirements
|
||||
from ._impl.azure_container_code_executor import AzureContainerCodeExecutor
|
||||
from ._func_with_reqs import (
|
||||
Alias,
|
||||
FunctionWithRequirements,
|
||||
FunctionWithRequirementsStr,
|
||||
Import,
|
||||
ImportFromModule,
|
||||
build_python_functions_file,
|
||||
to_stub,
|
||||
with_requirements,
|
||||
)
|
||||
from ._impl.command_line_code_result import CommandLineCodeResult
|
||||
from ._impl.docker_command_line_code_executor import DockerCommandLineCodeExecutor
|
||||
from ._impl.local_commandline_code_executor import LocalCommandLineCodeExecutor
|
||||
from ._impl.utils import get_required_packages, lang_to_cmd
|
||||
from ._utils import extract_markdown_code_blocks
|
||||
|
||||
__all__ = [
|
||||
"AzureContainerCodeExecutor",
|
||||
"LocalCommandLineCodeExecutor",
|
||||
"CommandLineCodeResult",
|
||||
"CodeBlock",
|
||||
"CodeResult",
|
||||
"CodeExecutor",
|
||||
"CodeResult",
|
||||
"Alias",
|
||||
"ImportFromModule",
|
||||
"Import",
|
||||
"FunctionWithRequirements",
|
||||
"FunctionWithRequirementsStr",
|
||||
"with_requirements",
|
||||
"to_stub",
|
||||
"extract_markdown_code_blocks",
|
||||
"get_required_packages",
|
||||
"build_python_functions_file",
|
||||
"DockerCommandLineCodeExecutor",
|
||||
"get_required_packages",
|
||||
"lang_to_cmd",
|
||||
]
|
||||
|
|
|
@ -8,13 +8,11 @@ import polars
|
|||
import pytest
|
||||
from autogen_core.base import CancellationToken
|
||||
from autogen_core.components.code_executor import (
|
||||
AzureContainerCodeExecutor,
|
||||
CodeBlock,
|
||||
FunctionWithRequirements,
|
||||
LocalCommandLineCodeExecutor,
|
||||
with_requirements,
|
||||
)
|
||||
from azure.identity import DefaultAzureCredential
|
||||
|
||||
ENVIRON_KEY_AZURE_POOL_ENDPOINT = "AZURE_POOL_ENDPOINT"
|
||||
|
||||
|
@ -78,32 +76,35 @@ print(data['name'][0])"""
|
|||
assert result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[load_data]
|
||||
)
|
||||
# AzureContainerCodeExecutor doesn't use the functions module import
|
||||
code = """import polars
|
||||
def test_local_formatted_prompt() -> None:
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir, functions=[add_two_numbers])
|
||||
|
||||
# Get first row's name
|
||||
data = load_data()
|
||||
print(data['name'][0])"""
|
||||
result = executor.format_functions_for_prompt()
|
||||
assert assert_str in result
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
|
||||
def test_local_formatted_prompt_str_func() -> None:
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
assert azure_result.output == "John\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir, functions=[func])
|
||||
|
||||
result = executor.format_functions_for_prompt()
|
||||
assert assert_str in result
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -124,31 +125,6 @@ print(add_two_numbers(1, 2))"""
|
|||
assert result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_function() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[add_two_numbers]
|
||||
)
|
||||
# AzureContainerCodeExecutor doesn't use the functions module import
|
||||
code = """print(add_two_numbers(1, 2))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
assert azure_result.output == "3\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fails_for_function_incorrect_import() -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
|
@ -166,30 +142,6 @@ function_incorrect_import()"""
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_fails_for_function_incorrect_import() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT,
|
||||
credential=DefaultAzureCredential(),
|
||||
functions=[function_incorrect_import],
|
||||
)
|
||||
code = """function_incorrect_import()"""
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fails_for_function_incorrect_dep() -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
|
@ -207,73 +159,6 @@ function_incorrect_dep()"""
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_fails_for_function_incorrect_dep() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[function_incorrect_dep]
|
||||
)
|
||||
code = """function_incorrect_dep()"""
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
|
||||
|
||||
def test_formatted_prompt() -> None:
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir, functions=[add_two_numbers])
|
||||
|
||||
result = executor.format_functions_for_prompt()
|
||||
assert assert_str in result
|
||||
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=DUMMY_POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[add_two_numbers]
|
||||
)
|
||||
|
||||
azure_result = azure_executor.format_functions_for_prompt()
|
||||
assert assert_str in azure_result
|
||||
|
||||
|
||||
def test_formatted_prompt_str_func() -> None:
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir, functions=[func])
|
||||
|
||||
result = executor.format_functions_for_prompt()
|
||||
assert assert_str in result
|
||||
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=DUMMY_POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
|
||||
azure_result = azure_executor.format_functions_for_prompt()
|
||||
assert assert_str in azure_result
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_can_load_str_function_with_reqs() -> None:
|
||||
func = FunctionWithRequirements.from_str(
|
||||
|
@ -300,36 +185,6 @@ print(add_two_numbers(1, 2))"""
|
|||
assert result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_str_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
code = """print(add_two_numbers(1, 2))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
assert azure_result.output == "3\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
|
||||
def test_cant_load_broken_str_function_with_reqs() -> None:
|
||||
with pytest.raises(ValueError):
|
||||
_ = FunctionWithRequirements.from_str(
|
||||
|
@ -365,35 +220,3 @@ print(add_two_numbers(object(), False))"""
|
|||
)
|
||||
assert "TypeError: unsupported operand type(s) for +:" in result.output
|
||||
assert result.exit_code == 1
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_cant_run_broken_str_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
code = """print(add_two_numbers(object(), False))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
# result.output = result.output.encode().decode('unicode_escape')
|
||||
assert "TypeError: unsupported operand type(s) for +:" in azure_result.output
|
||||
assert azure_result.exit_code == 1
|
||||
|
|
|
@ -19,7 +19,8 @@ dependencies = [
|
|||
|
||||
|
||||
[project.optional-dependencies]
|
||||
langchain = ["langchain >= 0.3.1"]
|
||||
langchain-tools = ["langchain >= 0.3.1"]
|
||||
azure-code-executor = ["azure-core"]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/autogen_ext"]
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
from ._azure_container_code_executor import AzureContainerCodeExecutor
|
||||
|
||||
__all__ = [
|
||||
"AzureContainerCodeExecutor",
|
||||
]
|
|
@ -11,20 +11,21 @@ import aiohttp
|
|||
|
||||
# async functions shouldn't use open()
|
||||
from anyio import open_file
|
||||
from azure.core.credentials import AccessToken
|
||||
|
||||
# from azure.mgmt.appcontainers import ContainerAppsAPIClient
|
||||
from typing_extensions import ParamSpec
|
||||
|
||||
from ....base import CancellationToken
|
||||
from .._base import CodeBlock, CodeExecutor, CodeResult
|
||||
from .._func_with_reqs import (
|
||||
from autogen_core.base import CancellationToken
|
||||
from autogen_core.components.code_executor import (
|
||||
CodeBlock,
|
||||
CodeExecutor,
|
||||
CodeResult,
|
||||
FunctionWithRequirements,
|
||||
FunctionWithRequirementsStr,
|
||||
build_python_functions_file,
|
||||
get_required_packages,
|
||||
to_stub,
|
||||
)
|
||||
from .utils import PYTHON_VARIANTS, get_required_packages, lang_to_cmd # type: ignore
|
||||
from azure.core.credentials import AccessToken
|
||||
from typing_extensions import ParamSpec
|
||||
|
||||
PYTHON_VARIANTS = ["python", "Python", "py"]
|
||||
|
||||
__all__ = ("AzureContainerCodeExecutor", "TokenProvider")
|
||||
|
||||
|
@ -37,25 +38,6 @@ class TokenProvider(Protocol):
|
|||
) -> AccessToken: ...
|
||||
|
||||
|
||||
# class FileInfo:
|
||||
# def __init__(self, filename: str, filesize: int, last_modified: str):
|
||||
# self._filename = filename
|
||||
# self._filesize = filesize
|
||||
# self._last_modified = datetime.fromisoformat(last_modified)
|
||||
# @property
|
||||
# def filename(self) -> str:
|
||||
# return self._filename
|
||||
# @property
|
||||
# def filesize(self) -> int:
|
||||
# return self._filesize
|
||||
# @property
|
||||
# def last_modified(self) -> datetime:
|
||||
# return self._last_modified
|
||||
#
|
||||
# def __str__(self):
|
||||
# return f"{self._filename}; {self._filesize} bytes; {self._last_modified}"
|
||||
|
||||
|
||||
class AzureContainerCodeExecutor(CodeExecutor):
|
||||
SUPPORTED_LANGUAGES: ClassVar[List[str]] = [
|
||||
"python",
|
|
@ -9,7 +9,8 @@ import tempfile
|
|||
import pytest
|
||||
from anyio import open_file
|
||||
from autogen_core.base import CancellationToken
|
||||
from autogen_core.components.code_executor import AzureContainerCodeExecutor, CodeBlock
|
||||
from autogen_core.components.code_executor import CodeBlock
|
||||
from autogen_ext.code_executor.aca_dynamic_sessions import AzureContainerCodeExecutor
|
||||
from azure.identity import DefaultAzureCredential
|
||||
|
||||
UNIX_SHELLS = ["bash", "sh", "shell"]
|
|
@ -0,0 +1,244 @@
|
|||
# File based from: https://github.com/microsoft/autogen/blob/main/test/coding/test_user_defined_functions.py
|
||||
# Credit to original authors
|
||||
|
||||
import os
|
||||
|
||||
import polars
|
||||
import pytest
|
||||
from autogen_core.base import CancellationToken
|
||||
from autogen_core.components.code_executor import (
|
||||
CodeBlock,
|
||||
FunctionWithRequirements,
|
||||
with_requirements,
|
||||
)
|
||||
from autogen_ext.code_executor.aca_dynamic_sessions import AzureContainerCodeExecutor
|
||||
from azure.identity import DefaultAzureCredential
|
||||
|
||||
ENVIRON_KEY_AZURE_POOL_ENDPOINT = "AZURE_POOL_ENDPOINT"
|
||||
|
||||
DUMMY_POOL_ENDPOINT = "DUMMY_POOL_ENDPOINT"
|
||||
POOL_ENDPOINT = os.getenv(ENVIRON_KEY_AZURE_POOL_ENDPOINT)
|
||||
|
||||
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
|
||||
|
||||
@with_requirements(python_packages=["polars"], global_imports=["polars"])
|
||||
def load_data() -> polars.DataFrame:
|
||||
"""Load some sample data.
|
||||
|
||||
Returns:
|
||||
polars.DataFrame: A DataFrame with the following columns: name(str), location(str), age(int)
|
||||
"""
|
||||
data = {
|
||||
"name": ["John", "Anna", "Peter", "Linda"],
|
||||
"location": ["New York", "Paris", "Berlin", "London"],
|
||||
"age": [24, 13, 53, 33],
|
||||
}
|
||||
return polars.DataFrame(data)
|
||||
|
||||
|
||||
@with_requirements(global_imports=["NOT_A_REAL_PACKAGE"])
|
||||
def function_incorrect_import() -> "polars.DataFrame":
|
||||
return polars.DataFrame()
|
||||
|
||||
|
||||
@with_requirements(python_packages=["NOT_A_REAL_PACKAGE"])
|
||||
def function_incorrect_dep() -> "polars.DataFrame":
|
||||
return polars.DataFrame()
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[load_data]
|
||||
)
|
||||
# AzureContainerCodeExecutor doesn't use the functions module import
|
||||
code = """import polars
|
||||
|
||||
# Get first row's name
|
||||
data = load_data()
|
||||
print(data['name'][0])"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
assert azure_result.output == "John\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_function() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[add_two_numbers]
|
||||
)
|
||||
# AzureContainerCodeExecutor doesn't use the functions module import
|
||||
code = """print(add_two_numbers(1, 2))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
assert azure_result.output == "3\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_fails_for_function_incorrect_import() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT,
|
||||
credential=DefaultAzureCredential(),
|
||||
functions=[function_incorrect_import],
|
||||
)
|
||||
code = """function_incorrect_import()"""
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_fails_for_function_incorrect_dep() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[function_incorrect_dep]
|
||||
)
|
||||
code = """function_incorrect_dep()"""
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
|
||||
|
||||
def test_azure_formatted_prompt() -> None:
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=DUMMY_POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[add_two_numbers]
|
||||
)
|
||||
|
||||
azure_result = azure_executor.format_functions_for_prompt()
|
||||
assert assert_str in azure_result
|
||||
|
||||
|
||||
def test_azure_formatted_prompt_str_func() -> None:
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
|
||||
assert_str = '''def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
'''
|
||||
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=DUMMY_POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
|
||||
azure_result = azure_executor.format_functions_for_prompt()
|
||||
assert assert_str in azure_result
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_can_load_str_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
code = """print(add_two_numbers(1, 2))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
assert azure_result.output == "3\n"
|
||||
assert azure_result.exit_code == 0
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not POOL_ENDPOINT,
|
||||
reason="do not run if pool endpoint is not defined",
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_cant_run_broken_str_function_with_reqs() -> None:
|
||||
assert POOL_ENDPOINT is not None
|
||||
cancellation_token = CancellationToken()
|
||||
func = FunctionWithRequirements.from_str(
|
||||
'''
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
'''
|
||||
)
|
||||
|
||||
azure_executor = AzureContainerCodeExecutor(
|
||||
pool_management_endpoint=POOL_ENDPOINT, credential=DefaultAzureCredential(), functions=[func]
|
||||
)
|
||||
code = """print(add_two_numbers(object(), False))"""
|
||||
|
||||
azure_result = await azure_executor.execute_code_blocks(
|
||||
code_blocks=[
|
||||
CodeBlock(language="python", code=code),
|
||||
],
|
||||
cancellation_token=cancellation_token,
|
||||
)
|
||||
# result.output = result.output.encode().decode('unicode_escape')
|
||||
assert "TypeError: unsupported operand type(s) for +:" in azure_result.output
|
||||
assert azure_result.exit_code == 1
|
|
@ -360,7 +360,6 @@ source = { editable = "packages/autogen-core" }
|
|||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
{ name = "asyncio-atexit" },
|
||||
{ name = "azure-core" },
|
||||
{ name = "docker" },
|
||||
{ name = "grpcio" },
|
||||
{ name = "openai" },
|
||||
|
@ -417,7 +416,6 @@ dev = [
|
|||
requires-dist = [
|
||||
{ name = "aiohttp" },
|
||||
{ name = "asyncio-atexit" },
|
||||
{ name = "azure-core" },
|
||||
{ name = "docker", specifier = "~=7.0" },
|
||||
{ name = "grpcio", specifier = "~=1.62.0" },
|
||||
{ name = "openai", specifier = ">=1.3" },
|
||||
|
@ -479,14 +477,18 @@ dependencies = [
|
|||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
langchain = [
|
||||
azure-code-executor = [
|
||||
{ name = "azure-core" },
|
||||
]
|
||||
langchain-tools = [
|
||||
{ name = "langchain" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "autogen-core", editable = "packages/autogen-core" },
|
||||
{ name = "langchain", marker = "extra == 'langchain'", specifier = ">=0.3.1" },
|
||||
{ name = "azure-core", marker = "extra == 'azure-code-executor'" },
|
||||
{ name = "langchain", marker = "extra == 'langchain-tools'", specifier = ">=0.3.1" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
Loading…
Reference in New Issue