ag2 0.9.2__py3-none-any.whl → 0.9.4__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 (35) hide show
  1. {ag2-0.9.2.dist-info → ag2-0.9.4.dist-info}/METADATA +14 -10
  2. {ag2-0.9.2.dist-info → ag2-0.9.4.dist-info}/RECORD +35 -29
  3. autogen/agentchat/contrib/agent_optimizer.py +6 -3
  4. autogen/agentchat/contrib/capabilities/transforms.py +22 -9
  5. autogen/agentchat/conversable_agent.py +51 -5
  6. autogen/agentchat/group/group_utils.py +81 -27
  7. autogen/agentchat/group/guardrails.py +171 -0
  8. autogen/agentchat/group/handoffs.py +81 -5
  9. autogen/agentchat/group/on_context_condition.py +2 -2
  10. autogen/agentchat/group/patterns/pattern.py +7 -1
  11. autogen/agentchat/group/targets/transition_target.py +10 -0
  12. autogen/agentchat/groupchat.py +95 -8
  13. autogen/agentchat/realtime/experimental/realtime_swarm.py +12 -4
  14. autogen/agents/experimental/document_agent/document_agent.py +232 -40
  15. autogen/agents/experimental/websurfer/websurfer.py +9 -1
  16. autogen/events/agent_events.py +6 -0
  17. autogen/events/helpers.py +8 -0
  18. autogen/mcp/helpers.py +45 -0
  19. autogen/mcp/mcp_proxy/mcp_proxy.py +2 -3
  20. autogen/messages/agent_messages.py +1 -1
  21. autogen/oai/gemini.py +41 -17
  22. autogen/oai/gemini_types.py +2 -1
  23. autogen/oai/oai_models/chat_completion.py +1 -1
  24. autogen/tools/experimental/__init__.py +4 -0
  25. autogen/tools/experimental/browser_use/browser_use.py +4 -11
  26. autogen/tools/experimental/firecrawl/__init__.py +7 -0
  27. autogen/tools/experimental/firecrawl/firecrawl_tool.py +853 -0
  28. autogen/tools/experimental/searxng/__init__.py +7 -0
  29. autogen/tools/experimental/searxng/searxng_search.py +141 -0
  30. autogen/version.py +1 -1
  31. templates/client_template/main.jinja2 +5 -2
  32. templates/main.jinja2 +1 -1
  33. {ag2-0.9.2.dist-info → ag2-0.9.4.dist-info}/WHEEL +0 -0
  34. {ag2-0.9.2.dist-info → ag2-0.9.4.dist-info}/licenses/LICENSE +0 -0
  35. {ag2-0.9.2.dist-info → ag2-0.9.4.dist-info}/licenses/NOTICE.md +0 -0
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from .searxng_search import SearxngSearchTool
6
+
7
+ __all__ = ["SearxngSearchTool"]
@@ -0,0 +1,141 @@
1
+ # Copyright (c) 2023 - 2025, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ """
5
+ SearxNG Search Tool
6
+ A simple tool to perform web searches using a SearxNG instance.
7
+ """
8
+
9
+ import logging
10
+ from typing import Annotated, Any, List, Optional
11
+
12
+ import requests
13
+
14
+ from autogen.doc_utils import export_module
15
+ from autogen.tools import Tool
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def _execute_searxng_query(
21
+ query: str,
22
+ max_results: int = 5,
23
+ categories: Optional[List[str]] = None,
24
+ language: Optional[str] = None,
25
+ base_url: str = "https://searxng.site/search",
26
+ ) -> list[dict[str, Any]]:
27
+ """
28
+ Execute a search query using a SearxNG instance.
29
+ Args:
30
+ query (str): The search query string.
31
+ max_results (int, optional): The maximum number of results to return. Defaults to 5.
32
+ categories (Optional[List[str]]): List of categories to search in.
33
+ language (Optional[str]): Language code.
34
+ base_url (str): SearxNG instance URL.
35
+ Returns:
36
+ list[dict[str, Any]]: A list of search results from SearxNG.
37
+ """
38
+ params = {
39
+ "q": query,
40
+ "format": "json",
41
+ "language": language or "en-US",
42
+ "categories": ",".join(categories) if categories else None,
43
+ "count": max_results,
44
+ }
45
+ params = {k: v for k, v in params.items() if v is not None}
46
+ try:
47
+ response = requests.get(base_url, params=params, timeout=10)
48
+ response.raise_for_status()
49
+ data = response.json()
50
+ results = data.get("results", [])
51
+ if not isinstance(results, list):
52
+ return []
53
+ # Ensure each result is a dict before returning
54
+ typed_results: list[dict[str, Any]] = []
55
+ for item in results:
56
+ if isinstance(item, dict):
57
+ typed_results.append(item)
58
+ return typed_results
59
+ except Exception as e:
60
+ logger.error(f"SearxNG Search failed: {e}")
61
+ return []
62
+
63
+
64
+ def _searxng_search(
65
+ query: str,
66
+ max_results: int = 5,
67
+ categories: Optional[List[str]] = None,
68
+ language: Optional[str] = None,
69
+ base_url: str = "https://searxng.site/search",
70
+ ) -> list[dict[str, Any]]:
71
+ """
72
+ Perform a SearxNG search and format the results.
73
+ Args:
74
+ query (str): The search query string.
75
+ max_results (int, optional): The maximum number of results to return. Defaults to 5.
76
+ categories (Optional[List[str]]): List of categories to search in.
77
+ language (Optional[str]): Language code.
78
+ base_url (str): SearxNG instance URL.
79
+ Returns:
80
+ list[dict[str, Any]]: A list of dictionaries with 'title', 'link', and 'snippet'.
81
+ """
82
+ res = _execute_searxng_query(
83
+ query=query,
84
+ max_results=max_results,
85
+ categories=categories,
86
+ language=language,
87
+ base_url=base_url,
88
+ )
89
+ formatted_results: list[dict[str, Any]] = [
90
+ {"title": item.get("title", ""), "link": item.get("url", ""), "snippet": item.get("content", "")}
91
+ for item in res
92
+ ]
93
+ return formatted_results
94
+
95
+
96
+ @export_module("autogen.tools.experimental")
97
+ class SearxngSearchTool(Tool):
98
+ """
99
+ SearxngSearchTool is a tool that uses SearxNG to perform a search.
100
+
101
+ This tool allows agents to leverage the SearxNG search engine for information retrieval.
102
+ SearxNG does not require an API key by default, making it easy to use.
103
+ """
104
+
105
+ def __init__(self, base_url: str = "https://searxng.site/search") -> None:
106
+ """
107
+ Initializes the SearxngSearchTool.
108
+ Args:
109
+ base_url (str): The SearxNG instance URL.
110
+ """
111
+ self.base_url = base_url
112
+ super().__init__(
113
+ name="searxng_search",
114
+ description="Use the SearxNG API to perform a search.",
115
+ func_or_tool=self.searxng_search,
116
+ )
117
+
118
+ def searxng_search(
119
+ self,
120
+ query: Annotated[str, "The search query."],
121
+ max_results: Annotated[int, "The number of results to return."] = 5,
122
+ categories: Annotated[Optional[List[str]], "List of categories to search in."] = None,
123
+ language: Annotated[Optional[str], "Language code (e.g., 'en-US')."] = None,
124
+ ) -> list[dict[str, Any]]:
125
+ """
126
+ Performs a search using the SearxNG API and returns formatted results.
127
+ Args:
128
+ query: The search query string.
129
+ max_results: The maximum number of results to return. Defaults to 5.
130
+ categories: List of categories to search in.
131
+ language: Language code.
132
+ Returns:
133
+ A list of dictionaries, each containing 'title', 'link', and 'snippet' of a search result.
134
+ """
135
+ return _searxng_search(
136
+ query=query,
137
+ max_results=max_results,
138
+ categories=categories,
139
+ language=language,
140
+ base_url=self.base_url,
141
+ )
autogen/version.py CHANGED
@@ -4,4 +4,4 @@
4
4
 
5
5
  __all__ = ["__version__"]
6
6
 
7
- __version__ = "0.9.2"
7
+ __version__ = "0.9.4"
@@ -1,6 +1,7 @@
1
1
  {{imports}}
2
2
 
3
3
  import argparse
4
+ import json
4
5
  import os
5
6
  from typing import *
6
7
 
@@ -48,7 +49,7 @@ def {{operation.function_name}}({{operation.snake_case_arguments}}
48
49
 
49
50
  if __name__ == "__main__":
50
51
  parser = argparse.ArgumentParser(description="Math Server")
51
- parser.add_argument("transport", choices=["stdio", "sse"], help="Transport mode (stdio or sse)")
52
+ parser.add_argument("transport", choices=["stdio", "sse", "streamable-http"], help="Transport mode (stdio, sse or streamable-http)")
52
53
  args = parser.parse_args()
53
54
 
54
55
  if "CONFIG_PATH" in os.environ:
@@ -66,4 +67,6 @@ if __name__ == "__main__":
66
67
 
67
68
  app.set_security_params(security_params)
68
69
 
69
- app.mcp.run(transport=args.transport)
70
+ mcp_settings = json.loads(os.environ.get("MCP_SETTINGS", "{}"))
71
+
72
+ app.get_mcp(**mcp_settings).run(transport=args.transport)
templates/main.jinja2 CHANGED
@@ -48,7 +48,7 @@ def {{operation.function_name}}({{operation.snake_case_arguments}}
48
48
 
49
49
  if __name__ == "__main__":
50
50
  parser = argparse.ArgumentParser(description="Math Server")
51
- parser.add_argument("transport", choices=["stdio", "sse"], help="Transport mode (stdio or sse)")
51
+ parser.add_argument("transport", choices=["stdio", "sse", "streamable-http"], help="Transport mode (stdio, sse or streamable-http)")
52
52
  args = parser.parse_args()
53
53
 
54
54
  if "SECURITY" in os.environ:
File without changes