ag2 0.4b1__py3-none-any.whl → 0.4.2b1__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.
- ag2-0.4.2b1.dist-info/METADATA +19 -0
- ag2-0.4.2b1.dist-info/RECORD +6 -0
- ag2-0.4.2b1.dist-info/top_level.txt +1 -0
- ag2-0.4b1.dist-info/METADATA +0 -496
- ag2-0.4b1.dist-info/RECORD +0 -115
- ag2-0.4b1.dist-info/top_level.txt +0 -1
- autogen/__init__.py +0 -17
- autogen/_pydantic.py +0 -116
- autogen/agentchat/__init__.py +0 -42
- autogen/agentchat/agent.py +0 -142
- autogen/agentchat/assistant_agent.py +0 -85
- autogen/agentchat/chat.py +0 -306
- autogen/agentchat/contrib/__init__.py +0 -0
- autogen/agentchat/contrib/agent_builder.py +0 -787
- autogen/agentchat/contrib/agent_optimizer.py +0 -450
- autogen/agentchat/contrib/capabilities/__init__.py +0 -0
- autogen/agentchat/contrib/capabilities/agent_capability.py +0 -21
- autogen/agentchat/contrib/capabilities/generate_images.py +0 -297
- autogen/agentchat/contrib/capabilities/teachability.py +0 -406
- autogen/agentchat/contrib/capabilities/text_compressors.py +0 -72
- autogen/agentchat/contrib/capabilities/transform_messages.py +0 -92
- autogen/agentchat/contrib/capabilities/transforms.py +0 -565
- autogen/agentchat/contrib/capabilities/transforms_util.py +0 -120
- autogen/agentchat/contrib/capabilities/vision_capability.py +0 -217
- autogen/agentchat/contrib/captainagent.py +0 -487
- autogen/agentchat/contrib/gpt_assistant_agent.py +0 -545
- autogen/agentchat/contrib/graph_rag/__init__.py +0 -0
- autogen/agentchat/contrib/graph_rag/document.py +0 -24
- autogen/agentchat/contrib/graph_rag/falkor_graph_query_engine.py +0 -76
- autogen/agentchat/contrib/graph_rag/graph_query_engine.py +0 -50
- autogen/agentchat/contrib/graph_rag/graph_rag_capability.py +0 -56
- autogen/agentchat/contrib/img_utils.py +0 -390
- autogen/agentchat/contrib/llamaindex_conversable_agent.py +0 -123
- autogen/agentchat/contrib/llava_agent.py +0 -176
- autogen/agentchat/contrib/math_user_proxy_agent.py +0 -471
- autogen/agentchat/contrib/multimodal_conversable_agent.py +0 -128
- autogen/agentchat/contrib/qdrant_retrieve_user_proxy_agent.py +0 -325
- autogen/agentchat/contrib/retrieve_assistant_agent.py +0 -56
- autogen/agentchat/contrib/retrieve_user_proxy_agent.py +0 -701
- autogen/agentchat/contrib/society_of_mind_agent.py +0 -203
- autogen/agentchat/contrib/swarm_agent.py +0 -414
- autogen/agentchat/contrib/text_analyzer_agent.py +0 -76
- autogen/agentchat/contrib/tool_retriever.py +0 -114
- autogen/agentchat/contrib/vectordb/__init__.py +0 -0
- autogen/agentchat/contrib/vectordb/base.py +0 -243
- autogen/agentchat/contrib/vectordb/chromadb.py +0 -326
- autogen/agentchat/contrib/vectordb/mongodb.py +0 -559
- autogen/agentchat/contrib/vectordb/pgvectordb.py +0 -958
- autogen/agentchat/contrib/vectordb/qdrant.py +0 -334
- autogen/agentchat/contrib/vectordb/utils.py +0 -126
- autogen/agentchat/contrib/web_surfer.py +0 -305
- autogen/agentchat/conversable_agent.py +0 -2908
- autogen/agentchat/groupchat.py +0 -1668
- autogen/agentchat/user_proxy_agent.py +0 -109
- autogen/agentchat/utils.py +0 -207
- autogen/browser_utils.py +0 -291
- autogen/cache/__init__.py +0 -10
- autogen/cache/abstract_cache_base.py +0 -78
- autogen/cache/cache.py +0 -182
- autogen/cache/cache_factory.py +0 -85
- autogen/cache/cosmos_db_cache.py +0 -150
- autogen/cache/disk_cache.py +0 -109
- autogen/cache/in_memory_cache.py +0 -61
- autogen/cache/redis_cache.py +0 -128
- autogen/code_utils.py +0 -745
- autogen/coding/__init__.py +0 -22
- autogen/coding/base.py +0 -113
- autogen/coding/docker_commandline_code_executor.py +0 -262
- autogen/coding/factory.py +0 -45
- autogen/coding/func_with_reqs.py +0 -203
- autogen/coding/jupyter/__init__.py +0 -22
- autogen/coding/jupyter/base.py +0 -32
- autogen/coding/jupyter/docker_jupyter_server.py +0 -164
- autogen/coding/jupyter/embedded_ipython_code_executor.py +0 -182
- autogen/coding/jupyter/jupyter_client.py +0 -224
- autogen/coding/jupyter/jupyter_code_executor.py +0 -161
- autogen/coding/jupyter/local_jupyter_server.py +0 -168
- autogen/coding/local_commandline_code_executor.py +0 -410
- autogen/coding/markdown_code_extractor.py +0 -44
- autogen/coding/utils.py +0 -57
- autogen/exception_utils.py +0 -46
- autogen/extensions/__init__.py +0 -0
- autogen/formatting_utils.py +0 -76
- autogen/function_utils.py +0 -362
- autogen/graph_utils.py +0 -148
- autogen/io/__init__.py +0 -15
- autogen/io/base.py +0 -105
- autogen/io/console.py +0 -43
- autogen/io/websockets.py +0 -213
- autogen/logger/__init__.py +0 -11
- autogen/logger/base_logger.py +0 -140
- autogen/logger/file_logger.py +0 -287
- autogen/logger/logger_factory.py +0 -29
- autogen/logger/logger_utils.py +0 -42
- autogen/logger/sqlite_logger.py +0 -459
- autogen/math_utils.py +0 -356
- autogen/oai/__init__.py +0 -33
- autogen/oai/anthropic.py +0 -428
- autogen/oai/bedrock.py +0 -600
- autogen/oai/cerebras.py +0 -264
- autogen/oai/client.py +0 -1148
- autogen/oai/client_utils.py +0 -167
- autogen/oai/cohere.py +0 -453
- autogen/oai/completion.py +0 -1216
- autogen/oai/gemini.py +0 -469
- autogen/oai/groq.py +0 -281
- autogen/oai/mistral.py +0 -279
- autogen/oai/ollama.py +0 -576
- autogen/oai/openai_utils.py +0 -810
- autogen/oai/together.py +0 -343
- autogen/retrieve_utils.py +0 -487
- autogen/runtime_logging.py +0 -163
- autogen/token_count_utils.py +0 -257
- autogen/types.py +0 -20
- autogen/version.py +0 -7
- {ag2-0.4b1.dist-info → ag2-0.4.2b1.dist-info}/LICENSE +0 -0
- {ag2-0.4b1.dist-info → ag2-0.4.2b1.dist-info}/NOTICE.md +0 -0
- {ag2-0.4b1.dist-info → ag2-0.4.2b1.dist-info}/WHEEL +0 -0
autogen/io/websockets.py
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2023 - 2024, Owners of https://github.com/ag2ai
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
#
|
|
5
|
-
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
-
# SPDX-License-Identifier: MIT
|
|
7
|
-
import logging
|
|
8
|
-
import ssl
|
|
9
|
-
import threading
|
|
10
|
-
from contextlib import contextmanager
|
|
11
|
-
from functools import partial
|
|
12
|
-
from time import sleep
|
|
13
|
-
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, Optional, Protocol, Union
|
|
14
|
-
|
|
15
|
-
from .base import IOStream
|
|
16
|
-
|
|
17
|
-
# Check if the websockets module is available
|
|
18
|
-
try:
|
|
19
|
-
from websockets.sync.server import serve as ws_serve
|
|
20
|
-
except ImportError as e:
|
|
21
|
-
_import_error: Optional[ImportError] = e
|
|
22
|
-
else:
|
|
23
|
-
_import_error = None
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
__all__ = ("IOWebsockets",)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
logger = logging.getLogger(__name__)
|
|
30
|
-
logger.setLevel(logging.INFO)
|
|
31
|
-
|
|
32
|
-
# The following type and protocols are used to define the ServerConnection and WebSocketServer classes
|
|
33
|
-
# if websockets is not installed, they would be untyped
|
|
34
|
-
Data = Union[str, bytes]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class ServerConnection(Protocol):
|
|
38
|
-
def send(self, message: Union[Data, Iterable[Data]]) -> None:
|
|
39
|
-
"""Send a message to the client.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
message (Union[Data, Iterable[Data]]): The message to send.
|
|
43
|
-
|
|
44
|
-
"""
|
|
45
|
-
... # pragma: no cover
|
|
46
|
-
|
|
47
|
-
def recv(self, timeout: Optional[float] = None) -> Data:
|
|
48
|
-
"""Receive a message from the client.
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
timeout (Optional[float], optional): The timeout for the receive operation. Defaults to None.
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
Data: The message received from the client.
|
|
55
|
-
|
|
56
|
-
"""
|
|
57
|
-
... # pragma: no cover
|
|
58
|
-
|
|
59
|
-
def close(self) -> None:
|
|
60
|
-
"""Close the connection."""
|
|
61
|
-
...
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class WebSocketServer(Protocol):
|
|
65
|
-
def serve_forever(self) -> None:
|
|
66
|
-
"""Run the server forever."""
|
|
67
|
-
... # pragma: no cover
|
|
68
|
-
|
|
69
|
-
def shutdown(self) -> None:
|
|
70
|
-
"""Shutdown the server."""
|
|
71
|
-
... # pragma: no cover
|
|
72
|
-
|
|
73
|
-
def __enter__(self) -> "WebSocketServer":
|
|
74
|
-
"""Enter the server context."""
|
|
75
|
-
... # pragma: no cover
|
|
76
|
-
|
|
77
|
-
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
|
|
78
|
-
"""Exit the server context."""
|
|
79
|
-
... # pragma: no cover
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class IOWebsockets(IOStream):
|
|
83
|
-
"""A websocket input/output stream."""
|
|
84
|
-
|
|
85
|
-
def __init__(self, websocket: ServerConnection) -> None:
|
|
86
|
-
"""Initialize the websocket input/output stream.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
websocket (ServerConnection): The websocket server.
|
|
90
|
-
|
|
91
|
-
Raises:
|
|
92
|
-
ImportError: If the websockets module is not available.
|
|
93
|
-
"""
|
|
94
|
-
if _import_error is not None:
|
|
95
|
-
raise _import_error # pragma: no cover
|
|
96
|
-
|
|
97
|
-
self._websocket = websocket
|
|
98
|
-
|
|
99
|
-
@staticmethod
|
|
100
|
-
def _handler(websocket: ServerConnection, on_connect: Callable[["IOWebsockets"], None]) -> None:
|
|
101
|
-
"""The handler function for the websocket server."""
|
|
102
|
-
logger.info(f" - IOWebsockets._handler(): Client connected on {websocket}")
|
|
103
|
-
# create a new IOWebsockets instance using the websocket that is create when a client connects
|
|
104
|
-
try:
|
|
105
|
-
iowebsocket = IOWebsockets(websocket)
|
|
106
|
-
with IOStream.set_default(iowebsocket):
|
|
107
|
-
# call the on_connect function
|
|
108
|
-
try:
|
|
109
|
-
on_connect(iowebsocket)
|
|
110
|
-
except Exception as e:
|
|
111
|
-
logger.warning(f" - IOWebsockets._handler(): Error in on_connect: {e}")
|
|
112
|
-
except Exception as e:
|
|
113
|
-
logger.error(f" - IOWebsockets._handler(): Unexpected error in IOWebsockets: {e}")
|
|
114
|
-
|
|
115
|
-
@staticmethod
|
|
116
|
-
@contextmanager
|
|
117
|
-
def run_server_in_thread(
|
|
118
|
-
*,
|
|
119
|
-
host: str = "127.0.0.1",
|
|
120
|
-
port: int = 8765,
|
|
121
|
-
on_connect: Callable[["IOWebsockets"], None],
|
|
122
|
-
ssl_context: Optional[ssl.SSLContext] = None,
|
|
123
|
-
**kwargs: Any,
|
|
124
|
-
) -> Iterator[str]:
|
|
125
|
-
"""Factory function to create a websocket input/output stream.
|
|
126
|
-
|
|
127
|
-
Args:
|
|
128
|
-
host (str, optional): The host to bind the server to. Defaults to "127.0.0.1".
|
|
129
|
-
port (int, optional): The port to bind the server to. Defaults to 8765.
|
|
130
|
-
on_connect (Callable[[IOWebsockets], None]): The function to be executed on client connection. Typically creates agents and initiate chat.
|
|
131
|
-
ssl_context (Optional[ssl.SSLContext], optional): The SSL context to use for secure connections. Defaults to None.
|
|
132
|
-
kwargs (Any): Additional keyword arguments to pass to the websocket server.
|
|
133
|
-
|
|
134
|
-
Yields:
|
|
135
|
-
str: The URI of the websocket server.
|
|
136
|
-
"""
|
|
137
|
-
server_dict: Dict[str, WebSocketServer] = {}
|
|
138
|
-
|
|
139
|
-
def _run_server() -> None:
|
|
140
|
-
if _import_error is not None:
|
|
141
|
-
raise _import_error
|
|
142
|
-
|
|
143
|
-
# print(f" - _run_server(): starting server on ws://{host}:{port}", flush=True)
|
|
144
|
-
with ws_serve(
|
|
145
|
-
handler=partial(IOWebsockets._handler, on_connect=on_connect),
|
|
146
|
-
host=host,
|
|
147
|
-
port=port,
|
|
148
|
-
ssl_context=ssl_context,
|
|
149
|
-
**kwargs,
|
|
150
|
-
) as server:
|
|
151
|
-
# print(f" - _run_server(): server {server} started on ws://{host}:{port}", flush=True)
|
|
152
|
-
|
|
153
|
-
server_dict["server"] = server
|
|
154
|
-
|
|
155
|
-
# runs until the server is shutdown
|
|
156
|
-
server.serve_forever()
|
|
157
|
-
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
# start server in a separate thread
|
|
161
|
-
thread = threading.Thread(target=_run_server)
|
|
162
|
-
thread.start()
|
|
163
|
-
try:
|
|
164
|
-
while "server" not in server_dict:
|
|
165
|
-
sleep(0.1)
|
|
166
|
-
|
|
167
|
-
yield f"ws://{host}:{port}"
|
|
168
|
-
|
|
169
|
-
finally:
|
|
170
|
-
# print(f" - run_server_in_thread(): shutting down server on ws://{host}:{port}", flush=True)
|
|
171
|
-
# gracefully stop server
|
|
172
|
-
if "server" in server_dict:
|
|
173
|
-
# print(f" - run_server_in_thread(): shutting down server {server_dict['server']}", flush=True)
|
|
174
|
-
server_dict["server"].shutdown()
|
|
175
|
-
|
|
176
|
-
# wait for the thread to stop
|
|
177
|
-
if thread:
|
|
178
|
-
thread.join()
|
|
179
|
-
|
|
180
|
-
@property
|
|
181
|
-
def websocket(self) -> "ServerConnection":
|
|
182
|
-
"""The URI of the websocket server."""
|
|
183
|
-
return self._websocket
|
|
184
|
-
|
|
185
|
-
def print(self, *objects: Any, sep: str = " ", end: str = "\n", flush: bool = False) -> None:
|
|
186
|
-
"""Print data to the output stream.
|
|
187
|
-
|
|
188
|
-
Args:
|
|
189
|
-
objects (any): The data to print.
|
|
190
|
-
sep (str, optional): The separator between objects. Defaults to " ".
|
|
191
|
-
end (str, optional): The end of the output. Defaults to "\n".
|
|
192
|
-
flush (bool, optional): Whether to flush the output. Defaults to False.
|
|
193
|
-
"""
|
|
194
|
-
xs = sep.join(map(str, objects)) + end
|
|
195
|
-
self._websocket.send(xs)
|
|
196
|
-
|
|
197
|
-
def input(self, prompt: str = "", *, password: bool = False) -> str:
|
|
198
|
-
"""Read a line from the input stream.
|
|
199
|
-
|
|
200
|
-
Args:
|
|
201
|
-
prompt (str, optional): The prompt to display. Defaults to "".
|
|
202
|
-
password (bool, optional): Whether to read a password. Defaults to False.
|
|
203
|
-
|
|
204
|
-
Returns:
|
|
205
|
-
str: The line read from the input stream.
|
|
206
|
-
|
|
207
|
-
"""
|
|
208
|
-
if prompt != "":
|
|
209
|
-
self._websocket.send(prompt)
|
|
210
|
-
|
|
211
|
-
msg = self._websocket.recv()
|
|
212
|
-
|
|
213
|
-
return msg.decode("utf-8") if isinstance(msg, bytes) else msg
|
autogen/logger/__init__.py
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2023 - 2024, Owners of https://github.com/ag2ai
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
#
|
|
5
|
-
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
-
# SPDX-License-Identifier: MIT
|
|
7
|
-
from .file_logger import FileLogger
|
|
8
|
-
from .logger_factory import LoggerFactory
|
|
9
|
-
from .sqlite_logger import SqliteLogger
|
|
10
|
-
|
|
11
|
-
__all__ = ("LoggerFactory", "SqliteLogger", "FileLogger")
|
autogen/logger/base_logger.py
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2023 - 2024, Owners of https://github.com/ag2ai
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
#
|
|
5
|
-
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
-
# SPDX-License-Identifier: MIT
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import sqlite3
|
|
10
|
-
import uuid
|
|
11
|
-
from abc import ABC, abstractmethod
|
|
12
|
-
from typing import TYPE_CHECKING, Any, Callable, Dict, List, TypeVar, Union
|
|
13
|
-
|
|
14
|
-
from openai import AzureOpenAI, OpenAI
|
|
15
|
-
from openai.types.chat import ChatCompletion
|
|
16
|
-
|
|
17
|
-
if TYPE_CHECKING:
|
|
18
|
-
from autogen import Agent, ConversableAgent, OpenAIWrapper
|
|
19
|
-
|
|
20
|
-
F = TypeVar("F", bound=Callable[..., Any])
|
|
21
|
-
ConfigItem = Dict[str, Union[str, List[str]]]
|
|
22
|
-
LLMConfig = Dict[str, Union[None, float, int, ConfigItem, List[ConfigItem]]]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class BaseLogger(ABC):
|
|
26
|
-
@abstractmethod
|
|
27
|
-
def start(self) -> str:
|
|
28
|
-
"""
|
|
29
|
-
Open a connection to the logging database, and start recording.
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
session_id (str): a unique id for the logging session
|
|
33
|
-
"""
|
|
34
|
-
...
|
|
35
|
-
|
|
36
|
-
@abstractmethod
|
|
37
|
-
def log_chat_completion(
|
|
38
|
-
self,
|
|
39
|
-
invocation_id: uuid.UUID,
|
|
40
|
-
client_id: int,
|
|
41
|
-
wrapper_id: int,
|
|
42
|
-
source: Union[str, Agent],
|
|
43
|
-
request: Dict[str, Union[float, str, List[Dict[str, str]]]],
|
|
44
|
-
response: Union[str, ChatCompletion],
|
|
45
|
-
is_cached: int,
|
|
46
|
-
cost: float,
|
|
47
|
-
start_time: str,
|
|
48
|
-
) -> None:
|
|
49
|
-
"""
|
|
50
|
-
Log a chat completion to database.
|
|
51
|
-
|
|
52
|
-
In AutoGen, chat completions are somewhat complicated because they are handled by the `autogen.oai.OpenAIWrapper` class.
|
|
53
|
-
One invocation to `create` can lead to multiple underlying OpenAI calls, depending on the llm_config list used, and
|
|
54
|
-
any errors or retries.
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
invocation_id (uuid): A unique identifier for the invocation to the OpenAIWrapper.create method call
|
|
58
|
-
client_id (int): A unique identifier for the underlying OpenAI client instance
|
|
59
|
-
wrapper_id (int): A unique identifier for the OpenAIWrapper instance
|
|
60
|
-
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
61
|
-
request (dict): A dictionary representing the request or call to the OpenAI client endpoint
|
|
62
|
-
response (str or ChatCompletion): The response from OpenAI
|
|
63
|
-
is_cached (int): 1 if the response was a cache hit, 0 otherwise
|
|
64
|
-
cost(float): The cost for OpenAI response
|
|
65
|
-
start_time (str): A string representing the moment the request was initiated
|
|
66
|
-
"""
|
|
67
|
-
...
|
|
68
|
-
|
|
69
|
-
@abstractmethod
|
|
70
|
-
def log_new_agent(self, agent: ConversableAgent, init_args: Dict[str, Any]) -> None:
|
|
71
|
-
"""
|
|
72
|
-
Log the birth of a new agent.
|
|
73
|
-
|
|
74
|
-
Args:
|
|
75
|
-
agent (ConversableAgent): The agent to log.
|
|
76
|
-
init_args (dict): The arguments passed to the construct the conversable agent
|
|
77
|
-
"""
|
|
78
|
-
...
|
|
79
|
-
|
|
80
|
-
@abstractmethod
|
|
81
|
-
def log_event(self, source: Union[str, Agent], name: str, **kwargs: Dict[str, Any]) -> None:
|
|
82
|
-
"""
|
|
83
|
-
Log an event for an agent.
|
|
84
|
-
|
|
85
|
-
Args:
|
|
86
|
-
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
87
|
-
name (str): The name of the event
|
|
88
|
-
kwargs (dict): The event information to log
|
|
89
|
-
"""
|
|
90
|
-
...
|
|
91
|
-
|
|
92
|
-
@abstractmethod
|
|
93
|
-
def log_new_wrapper(self, wrapper: OpenAIWrapper, init_args: Dict[str, Union[LLMConfig, List[LLMConfig]]]) -> None:
|
|
94
|
-
"""
|
|
95
|
-
Log the birth of a new OpenAIWrapper.
|
|
96
|
-
|
|
97
|
-
Args:
|
|
98
|
-
wrapper (OpenAIWrapper): The wrapper to log.
|
|
99
|
-
init_args (dict): The arguments passed to the construct the wrapper
|
|
100
|
-
"""
|
|
101
|
-
...
|
|
102
|
-
|
|
103
|
-
@abstractmethod
|
|
104
|
-
def log_new_client(
|
|
105
|
-
self, client: Union[AzureOpenAI, OpenAI], wrapper: OpenAIWrapper, init_args: Dict[str, Any]
|
|
106
|
-
) -> None:
|
|
107
|
-
"""
|
|
108
|
-
Log the birth of a new OpenAIWrapper.
|
|
109
|
-
|
|
110
|
-
Args:
|
|
111
|
-
wrapper (OpenAI): The OpenAI client to log.
|
|
112
|
-
init_args (dict): The arguments passed to the construct the client
|
|
113
|
-
"""
|
|
114
|
-
...
|
|
115
|
-
|
|
116
|
-
@abstractmethod
|
|
117
|
-
def log_function_use(self, source: Union[str, Agent], function: F, args: Dict[str, Any], returns: Any) -> None:
|
|
118
|
-
"""
|
|
119
|
-
Log the use of a registered function (could be a tool)
|
|
120
|
-
|
|
121
|
-
Args:
|
|
122
|
-
source (str or Agent): The source/creator of the event as a string name or an Agent instance
|
|
123
|
-
function (F): The function information
|
|
124
|
-
args (dict): The function args to log
|
|
125
|
-
returns (any): The return
|
|
126
|
-
"""
|
|
127
|
-
|
|
128
|
-
@abstractmethod
|
|
129
|
-
def stop(self) -> None:
|
|
130
|
-
"""
|
|
131
|
-
Close the connection to the logging database, and stop logging.
|
|
132
|
-
"""
|
|
133
|
-
...
|
|
134
|
-
|
|
135
|
-
@abstractmethod
|
|
136
|
-
def get_connection(self) -> Union[None, sqlite3.Connection]:
|
|
137
|
-
"""
|
|
138
|
-
Return a connection to the logging database.
|
|
139
|
-
"""
|
|
140
|
-
...
|
autogen/logger/file_logger.py
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2023 - 2024, Owners of https://github.com/ag2ai
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
#
|
|
5
|
-
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
-
# SPDX-License-Identifier: MIT
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import logging
|
|
11
|
-
import os
|
|
12
|
-
import threading
|
|
13
|
-
import uuid
|
|
14
|
-
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
|
15
|
-
|
|
16
|
-
from openai import AzureOpenAI, OpenAI
|
|
17
|
-
from openai.types.chat import ChatCompletion
|
|
18
|
-
|
|
19
|
-
from autogen.logger.base_logger import BaseLogger
|
|
20
|
-
from autogen.logger.logger_utils import get_current_ts, to_dict
|
|
21
|
-
|
|
22
|
-
from .base_logger import LLMConfig
|
|
23
|
-
|
|
24
|
-
if TYPE_CHECKING:
|
|
25
|
-
from autogen import Agent, ConversableAgent, OpenAIWrapper
|
|
26
|
-
from autogen.oai.anthropic import AnthropicClient
|
|
27
|
-
from autogen.oai.bedrock import BedrockClient
|
|
28
|
-
from autogen.oai.cerebras import CerebrasClient
|
|
29
|
-
from autogen.oai.cohere import CohereClient
|
|
30
|
-
from autogen.oai.gemini import GeminiClient
|
|
31
|
-
from autogen.oai.groq import GroqClient
|
|
32
|
-
from autogen.oai.mistral import MistralAIClient
|
|
33
|
-
from autogen.oai.ollama import OllamaClient
|
|
34
|
-
from autogen.oai.together import TogetherClient
|
|
35
|
-
|
|
36
|
-
logger = logging.getLogger(__name__)
|
|
37
|
-
|
|
38
|
-
F = TypeVar("F", bound=Callable[..., Any])
|
|
39
|
-
|
|
40
|
-
__all__ = ("FileLogger",)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def safe_serialize(obj: Any) -> str:
|
|
44
|
-
def default(o: Any) -> str:
|
|
45
|
-
if hasattr(o, "to_json"):
|
|
46
|
-
return str(o.to_json())
|
|
47
|
-
else:
|
|
48
|
-
return f"<<non-serializable: {type(o).__qualname__}>>"
|
|
49
|
-
|
|
50
|
-
return json.dumps(obj, default=default)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class FileLogger(BaseLogger):
|
|
54
|
-
def __init__(self, config: Dict[str, Any]):
|
|
55
|
-
self.config = config
|
|
56
|
-
self.session_id = str(uuid.uuid4())
|
|
57
|
-
|
|
58
|
-
curr_dir = os.getcwd()
|
|
59
|
-
self.log_dir = os.path.join(curr_dir, "autogen_logs")
|
|
60
|
-
os.makedirs(self.log_dir, exist_ok=True)
|
|
61
|
-
|
|
62
|
-
self.log_file = os.path.join(self.log_dir, self.config.get("filename", "runtime.log"))
|
|
63
|
-
try:
|
|
64
|
-
with open(self.log_file, "a"):
|
|
65
|
-
pass
|
|
66
|
-
except Exception as e:
|
|
67
|
-
logger.error(f"[file_logger] Failed to create logging file: {e}")
|
|
68
|
-
|
|
69
|
-
self.logger = logging.getLogger(__name__)
|
|
70
|
-
self.logger.setLevel(logging.INFO)
|
|
71
|
-
file_handler = logging.FileHandler(self.log_file)
|
|
72
|
-
self.logger.addHandler(file_handler)
|
|
73
|
-
|
|
74
|
-
def start(self) -> str:
|
|
75
|
-
"""Start the logger and return the session_id."""
|
|
76
|
-
try:
|
|
77
|
-
self.logger.info(f"Started new session with Session ID: {self.session_id}")
|
|
78
|
-
except Exception as e:
|
|
79
|
-
logger.error(f"[file_logger] Failed to create logging file: {e}")
|
|
80
|
-
finally:
|
|
81
|
-
return self.session_id
|
|
82
|
-
|
|
83
|
-
def log_chat_completion(
|
|
84
|
-
self,
|
|
85
|
-
invocation_id: uuid.UUID,
|
|
86
|
-
client_id: int,
|
|
87
|
-
wrapper_id: int,
|
|
88
|
-
source: Union[str, Agent],
|
|
89
|
-
request: Dict[str, Union[float, str, List[Dict[str, str]]]],
|
|
90
|
-
response: Union[str, ChatCompletion],
|
|
91
|
-
is_cached: int,
|
|
92
|
-
cost: float,
|
|
93
|
-
start_time: str,
|
|
94
|
-
) -> None:
|
|
95
|
-
"""
|
|
96
|
-
Log a chat completion.
|
|
97
|
-
"""
|
|
98
|
-
thread_id = threading.get_ident()
|
|
99
|
-
source_name = None
|
|
100
|
-
if isinstance(source, str):
|
|
101
|
-
source_name = source
|
|
102
|
-
else:
|
|
103
|
-
source_name = source.name
|
|
104
|
-
try:
|
|
105
|
-
log_data = json.dumps(
|
|
106
|
-
{
|
|
107
|
-
"invocation_id": str(invocation_id),
|
|
108
|
-
"client_id": client_id,
|
|
109
|
-
"wrapper_id": wrapper_id,
|
|
110
|
-
"request": to_dict(request),
|
|
111
|
-
"response": str(response),
|
|
112
|
-
"is_cached": is_cached,
|
|
113
|
-
"cost": cost,
|
|
114
|
-
"start_time": start_time,
|
|
115
|
-
"end_time": get_current_ts(),
|
|
116
|
-
"thread_id": thread_id,
|
|
117
|
-
"source_name": source_name,
|
|
118
|
-
}
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
self.logger.info(log_data)
|
|
122
|
-
except Exception as e:
|
|
123
|
-
self.logger.error(f"[file_logger] Failed to log chat completion: {e}")
|
|
124
|
-
|
|
125
|
-
def log_new_agent(self, agent: ConversableAgent, init_args: Dict[str, Any] = {}) -> None:
|
|
126
|
-
"""
|
|
127
|
-
Log a new agent instance.
|
|
128
|
-
"""
|
|
129
|
-
thread_id = threading.get_ident()
|
|
130
|
-
|
|
131
|
-
try:
|
|
132
|
-
log_data = json.dumps(
|
|
133
|
-
{
|
|
134
|
-
"id": id(agent),
|
|
135
|
-
"agent_name": agent.name if hasattr(agent, "name") and agent.name is not None else "",
|
|
136
|
-
"wrapper_id": to_dict(
|
|
137
|
-
agent.client.wrapper_id if hasattr(agent, "client") and agent.client is not None else ""
|
|
138
|
-
),
|
|
139
|
-
"session_id": self.session_id,
|
|
140
|
-
"current_time": get_current_ts(),
|
|
141
|
-
"agent_type": type(agent).__name__,
|
|
142
|
-
"args": to_dict(init_args),
|
|
143
|
-
"thread_id": thread_id,
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
self.logger.info(log_data)
|
|
147
|
-
except Exception as e:
|
|
148
|
-
self.logger.error(f"[file_logger] Failed to log new agent: {e}")
|
|
149
|
-
|
|
150
|
-
def log_event(self, source: Union[str, Agent], name: str, **kwargs: Dict[str, Any]) -> None:
|
|
151
|
-
"""
|
|
152
|
-
Log an event from an agent or a string source.
|
|
153
|
-
"""
|
|
154
|
-
from autogen import Agent
|
|
155
|
-
|
|
156
|
-
# This takes an object o as input and returns a string. If the object o cannot be serialized, instead of raising an error,
|
|
157
|
-
# it returns a string indicating that the object is non-serializable, along with its type's qualified name obtained using __qualname__.
|
|
158
|
-
json_args = json.dumps(kwargs, default=lambda o: f"<<non-serializable: {type(o).__qualname__}>>")
|
|
159
|
-
thread_id = threading.get_ident()
|
|
160
|
-
|
|
161
|
-
if isinstance(source, Agent):
|
|
162
|
-
try:
|
|
163
|
-
log_data = json.dumps(
|
|
164
|
-
{
|
|
165
|
-
"source_id": id(source),
|
|
166
|
-
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
167
|
-
"event_name": name,
|
|
168
|
-
"agent_module": source.__module__,
|
|
169
|
-
"agent_class": source.__class__.__name__,
|
|
170
|
-
"json_state": json_args,
|
|
171
|
-
"timestamp": get_current_ts(),
|
|
172
|
-
"thread_id": thread_id,
|
|
173
|
-
}
|
|
174
|
-
)
|
|
175
|
-
self.logger.info(log_data)
|
|
176
|
-
except Exception as e:
|
|
177
|
-
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
178
|
-
else:
|
|
179
|
-
try:
|
|
180
|
-
log_data = json.dumps(
|
|
181
|
-
{
|
|
182
|
-
"source_id": id(source),
|
|
183
|
-
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
184
|
-
"event_name": name,
|
|
185
|
-
"json_state": json_args,
|
|
186
|
-
"timestamp": get_current_ts(),
|
|
187
|
-
"thread_id": thread_id,
|
|
188
|
-
}
|
|
189
|
-
)
|
|
190
|
-
self.logger.info(log_data)
|
|
191
|
-
except Exception as e:
|
|
192
|
-
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
193
|
-
|
|
194
|
-
def log_new_wrapper(
|
|
195
|
-
self, wrapper: OpenAIWrapper, init_args: Dict[str, Union[LLMConfig, List[LLMConfig]]] = {}
|
|
196
|
-
) -> None:
|
|
197
|
-
"""
|
|
198
|
-
Log a new wrapper instance.
|
|
199
|
-
"""
|
|
200
|
-
thread_id = threading.get_ident()
|
|
201
|
-
|
|
202
|
-
try:
|
|
203
|
-
log_data = json.dumps(
|
|
204
|
-
{
|
|
205
|
-
"wrapper_id": id(wrapper),
|
|
206
|
-
"session_id": self.session_id,
|
|
207
|
-
"json_state": json.dumps(init_args),
|
|
208
|
-
"timestamp": get_current_ts(),
|
|
209
|
-
"thread_id": thread_id,
|
|
210
|
-
}
|
|
211
|
-
)
|
|
212
|
-
self.logger.info(log_data)
|
|
213
|
-
except Exception as e:
|
|
214
|
-
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
215
|
-
|
|
216
|
-
def log_new_client(
|
|
217
|
-
self,
|
|
218
|
-
client: (
|
|
219
|
-
AzureOpenAI
|
|
220
|
-
| OpenAI
|
|
221
|
-
| CerebrasClient
|
|
222
|
-
| GeminiClient
|
|
223
|
-
| AnthropicClient
|
|
224
|
-
| MistralAIClient
|
|
225
|
-
| TogetherClient
|
|
226
|
-
| GroqClient
|
|
227
|
-
| CohereClient
|
|
228
|
-
| OllamaClient
|
|
229
|
-
| BedrockClient
|
|
230
|
-
),
|
|
231
|
-
wrapper: OpenAIWrapper,
|
|
232
|
-
init_args: Dict[str, Any],
|
|
233
|
-
) -> None:
|
|
234
|
-
"""
|
|
235
|
-
Log a new client instance.
|
|
236
|
-
"""
|
|
237
|
-
thread_id = threading.get_ident()
|
|
238
|
-
|
|
239
|
-
try:
|
|
240
|
-
log_data = json.dumps(
|
|
241
|
-
{
|
|
242
|
-
"client_id": id(client),
|
|
243
|
-
"wrapper_id": id(wrapper),
|
|
244
|
-
"session_id": self.session_id,
|
|
245
|
-
"class": type(client).__name__,
|
|
246
|
-
"json_state": json.dumps(init_args),
|
|
247
|
-
"timestamp": get_current_ts(),
|
|
248
|
-
"thread_id": thread_id,
|
|
249
|
-
}
|
|
250
|
-
)
|
|
251
|
-
self.logger.info(log_data)
|
|
252
|
-
except Exception as e:
|
|
253
|
-
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
254
|
-
|
|
255
|
-
def log_function_use(self, source: Union[str, Agent], function: F, args: Dict[str, Any], returns: Any) -> None:
|
|
256
|
-
"""
|
|
257
|
-
Log a registered function(can be a tool) use from an agent or a string source.
|
|
258
|
-
"""
|
|
259
|
-
thread_id = threading.get_ident()
|
|
260
|
-
|
|
261
|
-
try:
|
|
262
|
-
log_data = json.dumps(
|
|
263
|
-
{
|
|
264
|
-
"source_id": id(source),
|
|
265
|
-
"source_name": str(source.name) if hasattr(source, "name") else source,
|
|
266
|
-
"agent_module": source.__module__,
|
|
267
|
-
"agent_class": source.__class__.__name__,
|
|
268
|
-
"timestamp": get_current_ts(),
|
|
269
|
-
"thread_id": thread_id,
|
|
270
|
-
"input_args": safe_serialize(args),
|
|
271
|
-
"returns": safe_serialize(returns),
|
|
272
|
-
}
|
|
273
|
-
)
|
|
274
|
-
self.logger.info(log_data)
|
|
275
|
-
except Exception as e:
|
|
276
|
-
self.logger.error(f"[file_logger] Failed to log event {e}")
|
|
277
|
-
|
|
278
|
-
def get_connection(self) -> None:
|
|
279
|
-
"""Method is intentionally left blank because there is no specific connection needed for the FileLogger."""
|
|
280
|
-
pass
|
|
281
|
-
|
|
282
|
-
def stop(self) -> None:
|
|
283
|
-
"""Close the file handler and remove it from the logger."""
|
|
284
|
-
for handler in self.logger.handlers:
|
|
285
|
-
if isinstance(handler, logging.FileHandler):
|
|
286
|
-
handler.close()
|
|
287
|
-
self.logger.removeHandler(handler)
|
autogen/logger/logger_factory.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2023 - 2024, Owners of https://github.com/ag2ai
|
|
2
|
-
#
|
|
3
|
-
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
#
|
|
5
|
-
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
|
6
|
-
# SPDX-License-Identifier: MIT
|
|
7
|
-
from typing import Any, Dict, Literal, Optional
|
|
8
|
-
|
|
9
|
-
from autogen.logger.base_logger import BaseLogger
|
|
10
|
-
from autogen.logger.file_logger import FileLogger
|
|
11
|
-
from autogen.logger.sqlite_logger import SqliteLogger
|
|
12
|
-
|
|
13
|
-
__all__ = ("LoggerFactory",)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class LoggerFactory:
|
|
17
|
-
@staticmethod
|
|
18
|
-
def get_logger(
|
|
19
|
-
logger_type: Literal["sqlite", "file"] = "sqlite", config: Optional[Dict[str, Any]] = None
|
|
20
|
-
) -> BaseLogger:
|
|
21
|
-
if config is None:
|
|
22
|
-
config = {}
|
|
23
|
-
|
|
24
|
-
if logger_type == "sqlite":
|
|
25
|
-
return SqliteLogger(config)
|
|
26
|
-
elif logger_type == "file":
|
|
27
|
-
return FileLogger(config)
|
|
28
|
-
else:
|
|
29
|
-
raise ValueError(f"[logger_factory] Unknown logger type: {logger_type}")
|