ag2 0.9.9__py3-none-any.whl → 0.9.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ag2 might be problematic. Click here for more details.

Files changed (88) hide show
  1. {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/METADATA +232 -210
  2. {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/RECORD +88 -80
  3. autogen/_website/generate_mkdocs.py +3 -3
  4. autogen/_website/notebook_processor.py +1 -1
  5. autogen/_website/utils.py +1 -1
  6. autogen/agentchat/assistant_agent.py +15 -15
  7. autogen/agentchat/chat.py +52 -40
  8. autogen/agentchat/contrib/agent_eval/criterion.py +1 -1
  9. autogen/agentchat/contrib/capabilities/text_compressors.py +5 -5
  10. autogen/agentchat/contrib/capabilities/tools_capability.py +1 -1
  11. autogen/agentchat/contrib/capabilities/transforms.py +1 -1
  12. autogen/agentchat/contrib/captainagent/agent_builder.py +1 -1
  13. autogen/agentchat/contrib/captainagent/captainagent.py +20 -19
  14. autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +2 -5
  15. autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +5 -5
  16. autogen/agentchat/contrib/graph_rag/neo4j_graph_query_engine.py +18 -17
  17. autogen/agentchat/contrib/rag/mongodb_query_engine.py +2 -2
  18. autogen/agentchat/contrib/rag/query_engine.py +11 -11
  19. autogen/agentchat/contrib/retrieve_assistant_agent.py +3 -0
  20. autogen/agentchat/contrib/swarm_agent.py +3 -2
  21. autogen/agentchat/contrib/vectordb/couchbase.py +1 -1
  22. autogen/agentchat/contrib/vectordb/mongodb.py +1 -1
  23. autogen/agentchat/contrib/web_surfer.py +1 -1
  24. autogen/agentchat/conversable_agent.py +184 -80
  25. autogen/agentchat/group/context_expression.py +21 -21
  26. autogen/agentchat/group/handoffs.py +11 -11
  27. autogen/agentchat/group/multi_agent_chat.py +3 -2
  28. autogen/agentchat/group/on_condition.py +11 -11
  29. autogen/agentchat/group/safeguards/__init__.py +21 -0
  30. autogen/agentchat/group/safeguards/api.py +224 -0
  31. autogen/agentchat/group/safeguards/enforcer.py +1064 -0
  32. autogen/agentchat/group/safeguards/events.py +119 -0
  33. autogen/agentchat/group/safeguards/validator.py +435 -0
  34. autogen/agentchat/groupchat.py +58 -17
  35. autogen/agentchat/realtime/experimental/clients/realtime_client.py +2 -2
  36. autogen/agentchat/realtime/experimental/function_observer.py +2 -3
  37. autogen/agentchat/realtime/experimental/realtime_agent.py +2 -3
  38. autogen/agentchat/realtime/experimental/realtime_swarm.py +21 -10
  39. autogen/agentchat/user_proxy_agent.py +55 -53
  40. autogen/agents/experimental/document_agent/document_agent.py +1 -10
  41. autogen/agents/experimental/document_agent/parser_utils.py +5 -1
  42. autogen/browser_utils.py +4 -4
  43. autogen/cache/abstract_cache_base.py +2 -6
  44. autogen/cache/disk_cache.py +1 -6
  45. autogen/cache/in_memory_cache.py +2 -6
  46. autogen/cache/redis_cache.py +1 -5
  47. autogen/coding/__init__.py +10 -2
  48. autogen/coding/base.py +2 -1
  49. autogen/coding/docker_commandline_code_executor.py +1 -6
  50. autogen/coding/factory.py +9 -0
  51. autogen/coding/jupyter/docker_jupyter_server.py +1 -7
  52. autogen/coding/jupyter/jupyter_client.py +2 -9
  53. autogen/coding/jupyter/jupyter_code_executor.py +2 -7
  54. autogen/coding/jupyter/local_jupyter_server.py +2 -6
  55. autogen/coding/local_commandline_code_executor.py +0 -65
  56. autogen/coding/yepcode_code_executor.py +197 -0
  57. autogen/environments/docker_python_environment.py +3 -3
  58. autogen/environments/system_python_environment.py +5 -5
  59. autogen/environments/venv_python_environment.py +5 -5
  60. autogen/events/agent_events.py +1 -1
  61. autogen/events/client_events.py +1 -1
  62. autogen/fast_depends/utils.py +10 -0
  63. autogen/graph_utils.py +5 -7
  64. autogen/import_utils.py +3 -1
  65. autogen/interop/pydantic_ai/pydantic_ai.py +8 -5
  66. autogen/io/processors/console_event_processor.py +8 -3
  67. autogen/llm_config/config.py +168 -91
  68. autogen/llm_config/entry.py +38 -26
  69. autogen/llm_config/types.py +35 -0
  70. autogen/llm_config/utils.py +223 -0
  71. autogen/mcp/mcp_proxy/operation_grouping.py +48 -39
  72. autogen/messages/agent_messages.py +1 -1
  73. autogen/messages/client_messages.py +1 -1
  74. autogen/oai/__init__.py +8 -1
  75. autogen/oai/client.py +10 -3
  76. autogen/oai/client_utils.py +1 -1
  77. autogen/oai/cohere.py +4 -4
  78. autogen/oai/gemini.py +4 -6
  79. autogen/oai/gemini_types.py +1 -0
  80. autogen/oai/openai_utils.py +44 -115
  81. autogen/tools/dependency_injection.py +4 -8
  82. autogen/tools/experimental/reliable/reliable.py +3 -2
  83. autogen/tools/experimental/web_search_preview/web_search_preview.py +1 -1
  84. autogen/tools/function_utils.py +2 -1
  85. autogen/version.py +1 -1
  86. {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/WHEEL +0 -0
  87. {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/licenses/LICENSE +0 -0
  88. {ag2-0.9.9.dist-info → ag2-0.9.10.dist-info}/licenses/NOTICE.md +0 -0
@@ -7,7 +7,6 @@
7
7
 
8
8
  import importlib
9
9
  import importlib.metadata
10
- import inspect
11
10
  import json
12
11
  import logging
13
12
  import os
@@ -22,6 +21,10 @@ from typing import TYPE_CHECKING, Any, Union
22
21
  from dotenv import find_dotenv, load_dotenv
23
22
  from packaging.version import parse
24
23
  from pydantic_core import to_jsonable_python
24
+ from typing_extensions import deprecated
25
+
26
+ from ..llm_config.utils import config_list_from_json as latest_config_list_from_json
27
+ from ..llm_config.utils import filter_config as latest_filter
25
28
 
26
29
  if TYPE_CHECKING:
27
30
  from openai import OpenAI
@@ -472,6 +475,11 @@ def config_list_gpt4_gpt35(
472
475
 
473
476
 
474
477
  @export_module("autogen")
478
+ @deprecated(
479
+ "`autogen.filter_config(...)` is deprecated. "
480
+ 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST").where(model="gpt-4o")" method instead. '
481
+ "Scheduled for removal in 0.11.0 version."
482
+ )
475
483
  def filter_config(
476
484
  config_list: list[dict[str, Any]],
477
485
  filter_dict: dict[str, list[str | None] | set[str | None]] | None,
@@ -489,7 +497,9 @@ def filter_config(
489
497
 
490
498
  filter_dict (dict, optional): A dictionary specifying filter criteria where:
491
499
  - Keys are field names to check in each configuration dictionary
492
- - Values are lists/sets of acceptable values for that field
500
+ - Values can be:
501
+ * a single string value (e.g., {"model": "gpt-4o"})
502
+ * a list or set of acceptable values for that field (e.g., {"model": ["gpt-4o", "gpt-4o-mini"]})
493
503
  - A configuration matches if ALL filter keys are satisfied AND for each key,
494
504
  the config's field value matches at least one acceptable value
495
505
  - If a filter value includes None, configurations missing that field will match
@@ -517,22 +527,27 @@ def filter_config(
517
527
  {"model": "gpt-4", "tags": ["premium", "latest"]},
518
528
  ]
519
529
 
520
- # Example 1: Single criterion - matches any model in the list
530
+ # Example 1: Single criterion with single string
531
+ filter_dict = {"model": "gpt-4o"}
532
+ result = filter_config(configs, filter_dict)
533
+ # Returns: [{"model": "gpt-4o", "api_type": "openai"}] if present
534
+
535
+ # Example 2: Single criterion - matches any model in the list
521
536
  filter_dict = {"model": ["gpt-4", "gpt-4o"]}
522
537
  result = filter_config(configs, filter_dict)
523
538
  # Returns: [{"model": "gpt-4", "api_type": "openai"}, {"model": "gpt-4", "tags": ["premium", "latest"]}]
524
539
 
525
- # Example 2: Multiple criteria - must satisfy ALL conditions
540
+ # Example 3: Multiple criteria - must satisfy ALL the conditions
526
541
  filter_dict = {"model": ["gpt-3.5-turbo"], "api_type": ["azure"]}
527
542
  result = filter_config(configs, filter_dict)
528
543
  # Returns: [{"model": "gpt-3.5-turbo", "api_type": "azure", "api_version": "2024-02-01"}]
529
544
 
530
- # Example 3: Tag filtering with list intersection
545
+ # Example 4: Tag filtering with list intersection
531
546
  filter_dict = {"tags": ["premium"]}
532
547
  result = filter_config(configs, filter_dict)
533
548
  # Returns: [{"model": "gpt-4", "tags": ["premium", "latest"]}]
534
549
 
535
- # Example 4: Exclude matching configurations
550
+ # Example 5: Exclude matching configurations
536
551
  filter_dict = {"api_type": ["openai"]}
537
552
  result = filter_config(configs, filter_dict, exclude=True)
538
553
  # Returns configs that do NOT have api_type="openai"
@@ -543,92 +558,22 @@ def filter_config(
543
558
  it is considered a non-match and is excluded from the result.
544
559
 
545
560
  """
546
- if inspect.stack()[1].function != "where":
547
- warnings.warn(
548
- "filter_config is deprecated and will be removed in a future release. "
549
- 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST").where(model="gpt-4o")" method instead.',
550
- DeprecationWarning,
551
- )
552
-
553
- if filter_dict:
554
- return [
555
- item
556
- for item in config_list
557
- if all(_satisfies_criteria(item.get(key), values) != exclude for key, values in filter_dict.items())
558
- ]
559
- return config_list
560
-
561
-
562
- def _satisfies_criteria(config_value: Any, criteria_values: Any) -> bool:
563
- """Check if a configuration field value satisfies the filter criteria.
564
-
565
- This helper function implements the matching logic between a single configuration
566
- field value and the acceptable values specified in the filter criteria. It handles
567
- both scalar and list-type configuration values with appropriate matching strategies.
568
-
569
- Args:
570
- config_value (Any): The value from a configuration dictionary field.
571
- Can be None, a scalar value, or a list of values.
572
- criteria_values (Any): The acceptable values from the filter dictionary.
573
- Can be a single value or a list/set of acceptable values.
574
-
575
- Returns:
576
- bool: True if the config_value satisfies the criteria, False otherwise.
577
-
578
- Matching Logic:
579
- - **None config values**: Always return False (missing fields don't match)
580
- - **List config values**:
581
- - If criteria is a list: Match if there's any intersection (set overlap)
582
- - If criteria is scalar: Match if the scalar is contained in the config list
583
- - **Scalar config values**:
584
- - If criteria is a list: Match if the config value is in the criteria list
585
- - If criteria is scalar: Match if the values are exactly equal
586
-
587
- Examples:
588
- ```python
589
- # List config value with list criteria (intersection matching)
590
- _satisfies_criteria(["gpt-4", "gpt-3.5"], ["gpt-4", "claude"]) # True (gpt-4 intersects)
591
- _satisfies_criteria(["tag1", "tag2"], ["tag3", "tag4"]) # False (no intersection)
592
-
593
- # List config value with scalar criteria (containment matching)
594
- _satisfies_criteria(["premium", "latest"], "premium") # True (premium is in list)
595
- _satisfies_criteria(["tag1", "tag2"], "tag3") # False (tag3 not in list)
596
-
597
- # Scalar config value with list criteria (membership matching)
598
- _satisfies_criteria("gpt-4", ["gpt-4", "gpt-3.5"]) # True (gpt-4 in criteria)
599
- _satisfies_criteria("claude", ["gpt-4", "gpt-3.5"]) # False (claude not in criteria)
600
-
601
- # Scalar config value with scalar criteria (equality matching)
602
- _satisfies_criteria("openai", "openai") # True (exact match)
603
- _satisfies_criteria("openai", "azure") # False (different values)
604
-
605
- # None config values (missing fields)
606
- _satisfies_criteria(None, ["gpt-4"]) # False (missing field)
607
- _satisfies_criteria(None, "gpt-4") # False (missing field)
608
- ```
561
+ warnings.warn(
562
+ "`autogen.filter_config(...)` is deprecated. "
563
+ 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST").where(model="gpt-4o")" method instead. '
564
+ "Scheduled for removal in 0.11.0 version.",
565
+ DeprecationWarning,
566
+ )
609
567
 
610
- Note:
611
- This is an internal helper function used by `filter_config()`. The function
612
- assumes that both parameters can be of various types and handles type
613
- checking internally to determine the appropriate matching strategy.
614
- """
615
- if config_value is None:
616
- return False
617
-
618
- if isinstance(config_value, list):
619
- if isinstance(criteria_values, list):
620
- return bool(set(config_value) & set(criteria_values)) # Non-empty intersection
621
- else:
622
- return criteria_values in config_value
623
- else:
624
- # In filter_dict, filter could be either a list of values or a single value.
625
- # For example, filter_dict = {"model": ["gpt-3.5-turbo"]} or {"model": "gpt-3.5-turbo"}
626
- if isinstance(criteria_values, list):
627
- return config_value in criteria_values
628
- return bool(config_value == criteria_values)
568
+ return latest_filter(config_list=config_list, filter_dict=filter_dict, exclude=exclude)
629
569
 
630
570
 
631
571
  @export_module("autogen")
572
+ @deprecated(
573
+ "`autogen.config_list_from_json(...)` is deprecated. "
574
+ 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST")" method instead. '
575
+ "Scheduled for removal in 0.11.0 version."
576
+ )
632
577
  def config_list_from_json(
633
578
  env_or_file: str,
634
579
  file_location: str | None = "",
@@ -669,34 +614,18 @@ def config_list_from_json(
669
614
  Raises:
670
615
  FileNotFoundError: if env_or_file is neither found as an environment variable nor a file
671
616
  """
672
- if inspect.stack()[1].function != "from_json":
673
- warnings.warn(
674
- "config_list_from_json is deprecated and will be removed in a future release. "
675
- 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST")" method instead.',
676
- DeprecationWarning,
677
- )
678
-
679
- env_str = os.environ.get(env_or_file)
680
-
681
- if env_str:
682
- # The environment variable exists. We should use information from it.
683
- if os.path.exists(env_str):
684
- # It is a file location, and we need to load the json from the file.
685
- with open(env_str) as file:
686
- json_str = file.read()
687
- else:
688
- # Else, it should be a JSON string by itself.
689
- json_str = env_str
690
- config_list = json.loads(json_str)
691
- else:
692
- # The environment variable does not exist.
693
- # So, `env_or_file` is a filename. We should use the file location.
694
- config_list_path = os.path.join(file_location, env_or_file) if file_location is not None else env_or_file
695
-
696
- with open(config_list_path) as json_file:
697
- config_list = json.load(json_file)
617
+ warnings.warn(
618
+ "`autogen.config_list_from_json(...)` is deprecated. "
619
+ 'Please use the "autogen.LLMConfig.from_json(path="OAI_CONFIG_LIST")" method instead. '
620
+ "Scheduled for removal in 0.11.0 version.",
621
+ DeprecationWarning,
622
+ )
698
623
 
699
- return filter_config(config_list, filter_dict)
624
+ return latest_config_list_from_json(
625
+ env_or_file=env_or_file,
626
+ file_location=file_location,
627
+ filter_dict=filter_dict,
628
+ )
700
629
 
701
630
 
702
631
  def get_config(
@@ -15,6 +15,7 @@ from ..doc_utils import export_module
15
15
  from ..fast_depends import Depends as FastDepends
16
16
  from ..fast_depends import inject
17
17
  from ..fast_depends.dependencies import model
18
+ from ..fast_depends.utils import is_coroutine_callable
18
19
 
19
20
  if TYPE_CHECKING:
20
21
  from ..agentchat.conversable_agent import ConversableAgent
@@ -140,10 +141,7 @@ def remove_params(func: Callable[..., Any], sig: inspect.Signature, params: Iter
140
141
 
141
142
 
142
143
  def _remove_injected_params_from_signature(func: Callable[..., Any]) -> Callable[..., Any]:
143
- # This is a workaround for Python 3.9+ where staticmethod.__func__ is accessible
144
- if sys.version_info >= (3, 9) and isinstance(func, staticmethod) and hasattr(func, "__func__"):
145
- func = _fix_staticmethod(func)
146
-
144
+ func = _fix_staticmethod(func)
147
145
  sig = inspect.signature(func)
148
146
  params_to_remove = [p.name for p in sig.parameters.values() if _is_context_param(p) or _is_depends_param(p)]
149
147
  remove_params(func, sig, params_to_remove)
@@ -205,7 +203,7 @@ def _fix_staticmethod(f: Callable[..., Any]) -> Callable[..., Any]:
205
203
 
206
204
 
207
205
  def _set_return_annotation_to_any(f: Callable[..., Any]) -> Callable[..., Any]:
208
- if inspect.iscoroutinefunction(f):
206
+ if is_coroutine_callable(f):
209
207
 
210
208
  @functools.wraps(f)
211
209
  async def _a_wrapped_func(*args: Any, **kwargs: Any) -> Any:
@@ -242,9 +240,7 @@ def inject_params(f: Callable[..., Any]) -> Callable[..., Any]:
242
240
  The modified function with injected dependencies and updated signature.
243
241
  """
244
242
  # This is a workaround for Python 3.9+ where staticmethod.__func__ is accessible
245
- if sys.version_info >= (3, 9) and isinstance(f, staticmethod) and hasattr(f, "__func__"):
246
- f = _fix_staticmethod(f)
247
-
243
+ f = _fix_staticmethod(f)
248
244
  f = _string_metadata_to_description_field(f)
249
245
  f = _set_return_annotation_to_any(f)
250
246
  f = inject(f)
@@ -26,6 +26,7 @@ from ....agentchat.group import AgentTarget, ReplyResult, TerminateTarget
26
26
  from ....agentchat.group.context_variables import ContextVariables
27
27
  from ....agentchat.group.patterns import DefaultPattern
28
28
  from ....doc_utils import export_module
29
+ from ....fast_depends.utils import is_coroutine_callable
29
30
  from ....llm_config import LLMConfig
30
31
  from ....tools.dependency_injection import Field as AG2Field
31
32
  from ....tools.tool import Tool
@@ -375,7 +376,7 @@ def reliable_function_wrapper(
375
376
  Adds 'hypothesis' and 'context_variables' keyword-only arguments.
376
377
  Returns a ReplyResult targeting the validator.
377
378
  """
378
- is_original_func_async = inspect.iscoroutinefunction(tool_function)
379
+ is_original_func_async = is_coroutine_callable(tool_function)
379
380
  tool_sig = inspect.signature(tool_function)
380
381
  wrapper_func: Callable[..., Any] # Declare type for wrapper_func
381
382
 
@@ -653,7 +654,7 @@ class ReliableTool(Tool):
653
654
  Example: `ground_truth=["The API rate limit is 10 requests per minute.", "User preference: only show results from the last 7 days."]`
654
655
  """
655
656
  self._original_func, original_name, original_description = self._extract_func_details(func_or_tool)
656
- self._is_original_func_async = inspect.iscoroutinefunction(self._original_func)
657
+ self._is_original_func_async = is_coroutine_callable(self._original_func)
657
658
 
658
659
  self._runner_llm_config = ConversableAgent._validate_llm_config(runner_llm_config)
659
660
  if self._runner_llm_config is False:
@@ -49,7 +49,7 @@ class WebSearchPreviewTool(Tool):
49
49
  The default is `None`, which means the text will be returned as a string.
50
50
  """
51
51
  self.web_search_tool_param = WebSearchToolParam(
52
- type="web_search_preview",
52
+ type="web_search",
53
53
  search_context_size=search_context_size,
54
54
  user_location=UserLocation(**user_location) if user_location else None, # type: ignore[typeddict-item]
55
55
  )
@@ -17,6 +17,7 @@ from pydantic import __version__ as pydantic_version
17
17
  from pydantic.json_schema import JsonSchemaValue
18
18
 
19
19
  from ..doc_utils import export_module
20
+ from ..fast_depends.utils import is_coroutine_callable
20
21
  from .dependency_injection import Field as AG2Field
21
22
 
22
23
  if parse(pydantic_version) < parse("2.10.2"):
@@ -381,7 +382,7 @@ def load_basemodels_if_needed(func: Callable[..., Any]) -> Callable[..., Any]:
381
382
  # call the original function
382
383
  return await func(*args, **kwargs)
383
384
 
384
- if inspect.iscoroutinefunction(func):
385
+ if is_coroutine_callable(func):
385
386
  return _a_load_parameters_if_needed
386
387
  else:
387
388
  return _load_parameters_if_needed
autogen/version.py CHANGED
@@ -4,4 +4,4 @@
4
4
 
5
5
  __all__ = ["__version__"]
6
6
 
7
- __version__ = "0.9.9"
7
+ __version__ = "0.9.10"
File without changes