diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a92044f15b..0bd7ee3d57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.8" diff --git a/.github/workflows/contrib-openai.yml b/.github/workflows/contrib-openai.yml index 9a99caec96..5d74c59022 100644 --- a/.github/workflows/contrib-openai.yml +++ b/.github/workflows/contrib-openai.yml @@ -273,7 +273,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.12"] + python-version: ["3.13"] runs-on: ${{ matrix.os }} environment: openai1 steps: diff --git a/.github/workflows/contrib-tests.yml b/.github/workflows/contrib-tests.yml index 9411222f87..9e93490ea7 100644 --- a/.github/workflows/contrib-tests.yml +++ b/.github/workflows/contrib-tests.yml @@ -29,7 +29,7 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-latest, windows-2019] + os: [macos-latest, windows-latest] python-version: ["3.9", "3.10", "3.11"] exclude: - os: macos-latest @@ -168,7 +168,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.10"] steps: - uses: actions/checkout@v4 @@ -203,7 +203,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.11"] steps: - uses: actions/checkout@v4 @@ -238,8 +238,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.13"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -273,8 +273,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.13"] steps: - uses: actions/checkout@v4 with: @@ -300,7 +300,7 @@ jobs: run: | pytest test/agentchat/contrib/test_img_utils.py test/agentchat/contrib/test_lmm.py test/agentchat/contrib/test_llava.py test/agentchat/contrib/capabilities/test_vision_capability.py --skip-openai - name: Image Gen Coverage - if: ${{ matrix.os != 'windows-2019' && matrix.python-version != '3.12' }} + if: ${{ matrix.os != 'windows-latest' && matrix.python-version != '3.13' }} run: | pytest test/agentchat/contrib/capabilities/test_image_generation_capability.py --skip-openai - name: Upload coverage to Codecov @@ -314,8 +314,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -354,7 +354,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.11"] steps: - uses: actions/checkout@v4 @@ -389,7 +389,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.11"] steps: - uses: actions/checkout@v4 @@ -421,7 +421,7 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -462,8 +462,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -502,8 +502,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -542,8 +542,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -582,8 +582,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -622,7 +622,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 with: @@ -658,8 +658,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" @@ -698,8 +698,8 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-2019] - python-version: ["3.9", "3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] exclude: - os: macos-latest python-version: "3.9" diff --git a/.github/workflows/openai.yml b/.github/workflows/openai.yml index a9ab8e9e0c..7dcf3175ba 100644 --- a/.github/workflows/openai.yml +++ b/.github/workflows/openai.yml @@ -25,7 +25,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] runs-on: ${{ matrix.os }} environment: openai1 services: diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index c66fb6ad7b..617dbe634c 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: true matrix: - version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 396e669d1e..e2aa0dff71 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Find detailed instructions for users [here](https://ag2ai.github.io/ag2/docs/ins ### Option 2. Install AG2 Locally -AG2 requires **Python version >= 3.8, < 3.13**. It can be installed from pip: +AG2 requires **Python version >= 3.8, < 3.14**. It can be installed from pip: ```bash pip install ag2 diff --git a/autogen/agentchat/contrib/llamaindex_conversable_agent.py b/autogen/agentchat/contrib/llamaindex_conversable_agent.py index b5bc79dec1..e883e76714 100644 --- a/autogen/agentchat/contrib/llamaindex_conversable_agent.py +++ b/autogen/agentchat/contrib/llamaindex_conversable_agent.py @@ -16,6 +16,15 @@ from llama_index.core.agent.runner.base import AgentRunner from llama_index.core.base.llms.types import ChatMessage from llama_index.core.chat_engine.types import AgentChatResponse + from pydantic import BaseModel + + # Add Pydantic configuration to allow arbitrary types + # Added to mitigate PydanticSchemaGenerationError + class Config: + arbitrary_types_allowed = True + + BaseModel.model_config = Config + except ImportError as e: logger.fatal("Failed to import llama-index. Try running 'pip install llama-index'") raise e diff --git a/setup.py b/setup.py index 735a89f07d..435fa1a76c 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,8 @@ "termcolor", "flaml", # numpy is installed by flaml, but we want to pin the version to below 2.x (see https://github.com/microsoft/autogen/issues/1960) - "numpy>=1.17.0,<2", + "numpy>=2.1; python_version>='3.13'", # numpy 2.1+ required for Python 3.13 + "numpy>=1.24.0,<2.0.0; python_version<'3.13'", # numpy 1.24+ for older Python versions "python-dotenv", "tiktoken", # Disallowing 2.6.0 can be removed when this is fixed https://github.com/pydantic/pydantic/issues/8705 @@ -135,5 +136,5 @@ "Operating System :: OS Independent", ], license="Apache Software License 2.0", - python_requires=">=3.8,<3.13", + python_requires=">=3.8,<3.14", ) diff --git a/test/agentchat/contrib/graph_rag/test_falkor_graph_rag.py b/test/agentchat/contrib/graph_rag/test_falkor_graph_rag.py index 8814479da9..5b61454e9e 100644 --- a/test/agentchat/contrib/graph_rag/test_falkor_graph_rag.py +++ b/test/agentchat/contrib/graph_rag/test_falkor_graph_rag.py @@ -3,7 +3,7 @@ import pytest from conftest import reason, skip_openai # noqa: E402 from graphrag_sdk import KnowledgeGraph, Source -from graphrag_sdk.schema import Schema +from graphrag_sdk.ontology import Ontology try: from autogen.agentchat.contrib.graph_rag.document import ( @@ -34,7 +34,7 @@ def test_falkor_db_query_engine(): 3. Query it with a question and verify the result contains the critical information. """ # Arrange - test_schema = Schema() + test_schema = Ontology() actor = test_schema.add_entity("Actor").add_attribute("name", str, unique=True) movie = test_schema.add_entity("Movie").add_attribute("title", str, unique=True) test_schema.add_relation("ACTED", actor, movie) diff --git a/test/agentchat/test_function_and_tool_calling.py b/test/agentchat/test_function_and_tool_calling.py index cd7064cd7b..eaaea6a8a9 100644 --- a/test/agentchat/test_function_and_tool_calling.py +++ b/test/agentchat/test_function_and_tool_calling.py @@ -5,12 +5,16 @@ # Portions derived from https://github.com/microsoft/autogen are under the MIT License. # SPDX-License-Identifier: MIT import json +import sys from typing import Any, Callable, Dict, List import pytest from autogen.agentchat.conversable_agent import ConversableAgent +# Cater for Python version 3.13+ changes in json error messages +PYTHON131PLUS = sys.version_info >= (3, 13) + def _tool_func_1(arg1: str, arg2: str) -> str: return f"_tool_func_1: {arg1} {arg2}" @@ -107,6 +111,20 @@ async def _a_tool_func_error(arg1: str, arg2: str) -> str: "content": "Error: Expecting property name enclosed in double quotes: line 1 column 37 (char 36)\n The argument must be in JSON format.\n\n_tool_func_2: value3 value4", } +# Python 3.13+ has different json error messages +_tool_use_message_1_bad_json_expected_reply_313 = { + "role": "tool", + "tool_responses": [ + { + "tool_call_id": "1", + "role": "tool", + "content": "Error: Illegal trailing comma before end of object: line 1 column 36 (char 35)\n The argument must be in JSON format.", + }, + {"tool_call_id": "2", "role": "tool", "content": "_tool_func_2: value3 value4"}, + ], + "content": "Error: Illegal trailing comma before end of object: line 1 column 36 (char 35)\n The argument must be in JSON format.\n\n_tool_func_2: value3 value4", +} + _tool_use_message_1_error_expected_reply = { "role": "tool", "tool_responses": [ @@ -163,6 +181,13 @@ async def _a_tool_func_error(arg1: str, arg2: str) -> str: "content": "Error: Expecting property name enclosed in double quotes: line 1 column 37 (char 36)\n The argument must be in JSON format.", } +# Python 3.13+ has different json error messages +_function_use_message_1_bad_json_expected_reply_313 = { + "name": "_tool_func_1", + "role": "function", + "content": "Error: Illegal trailing comma before end of object: line 1 column 36 (char 35)\n The argument must be in JSON format.", +} + _function_use_message_1_error_expected_reply = { "name": "_tool_func_1", "role": "function", @@ -240,7 +265,14 @@ def test_generate_function_call_reply_on_function_call_message(is_function_async # bad JSON messages = [_function_use_message_1_bad_json] finished, retval = agent.generate_function_call_reply(messages) - assert (finished, retval) == (True, _function_use_message_1_bad_json_expected_reply) + assert (finished, retval) == ( + True, + ( + _function_use_message_1_bad_json_expected_reply_313 + if PYTHON131PLUS + else _function_use_message_1_bad_json_expected_reply + ), + ) # tool call messages = [_tool_use_message_1] @@ -282,7 +314,14 @@ async def test_a_generate_function_call_reply_on_function_call_message(is_functi # bad JSON messages = [_function_use_message_1_bad_json] finished, retval = await agent.a_generate_function_call_reply(messages) - assert (finished, retval) == (True, _function_use_message_1_bad_json_expected_reply) + assert (finished, retval) == ( + True, + ( + _function_use_message_1_bad_json_expected_reply_313 + if PYTHON131PLUS + else _function_use_message_1_bad_json_expected_reply + ), + ) # tool call messages = [_tool_use_message_1] @@ -323,7 +362,14 @@ def test_generate_tool_calls_reply_on_function_call_message(is_function_async: b # bad JSON messages = [_tool_use_message_1_bad_json] finished, retval = agent.generate_tool_calls_reply(messages) - assert (finished, retval) == (True, _tool_use_message_1_bad_json_expected_reply) + assert (finished, retval) == ( + True, + ( + _tool_use_message_1_bad_json_expected_reply_313 + if PYTHON131PLUS + else _tool_use_message_1_bad_json_expected_reply + ), + ) # function call messages = [_function_use_message_1] @@ -365,7 +411,14 @@ async def test_a_generate_tool_calls_reply_on_function_call_message(is_function_ # bad JSON messages = [_tool_use_message_1_bad_json] finished, retval = await agent.a_generate_tool_calls_reply(messages) - assert (finished, retval) == (True, _tool_use_message_1_bad_json_expected_reply) + assert (finished, retval) == ( + True, + ( + _tool_use_message_1_bad_json_expected_reply_313 + if PYTHON131PLUS + else _tool_use_message_1_bad_json_expected_reply + ), + ) # function call messages = [_function_use_message_1] diff --git a/test/test_notebook.py b/test/test_notebook.py index d6db43d711..fb746a2ecb 100755 --- a/test/test_notebook.py +++ b/test/test_notebook.py @@ -54,8 +54,8 @@ def run_notebook(input_nb, output_nb="executed_openai_notebook.ipynb", save=Fals @pytest.mark.skipif( - skip or not sys.version.startswith("3.10"), - reason="do not run if openai is not installed or py!=3.10", + skip or not sys.version.startswith("3.13"), + reason="do not run if openai is not installed or py!=3.13", ) def test_agentchat_auto_feedback_from_code(save=False): run_notebook("agentchat_auto_feedback_from_code_execution.ipynb", save=save) @@ -86,8 +86,8 @@ def test_agentchat_function_call_currency_calculator(save=False): @pytest.mark.skipif( - skip or not sys.version.startswith("3.11"), - reason="do not run if openai is not installed or py!=3.11", + skip or not sys.version.startswith("3.13"), + reason="do not run if openai is not installed or py!=3.13", ) def test_agentchat_function_call_async(save=False): run_notebook("agentchat_function_call_async.ipynb", save=save) @@ -118,8 +118,8 @@ def test_agentchat_groupchat_finite_state_machine(save=False): @pytest.mark.skipif( - skip or not sys.version.startswith("3.10"), - reason="do not run if openai is not installed or py!=3.10", + skip or not sys.version.startswith("3.11"), + reason="do not run if openai is not installed or py!=3.11", ) def test_agentchat_cost_token_tracking(save=False): run_notebook("agentchat_cost_token_tracking.ipynb", save=save) diff --git a/website/docs/installation/Installation.mdx b/website/docs/installation/Installation.mdx index 51f0e4cbbe..a74100fcd1 100644 --- a/website/docs/installation/Installation.mdx +++ b/website/docs/installation/Installation.mdx @@ -66,7 +66,7 @@ When installing AutoGen locally, we recommend using a virtual environment for th ## Install AutoGen -AutoGen requires **Python version >= 3.8, < 3.13**. It can be installed from pip: +AutoGen requires **Python version >= 3.8, < 3.14**. It can be installed from pip: ```bash pip install autogen