dm-aioaiagent 0.3.4__tar.gz → 0.3.5__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dm-aioaiagent
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: This is my custom aioaiagent client
5
5
  Home-page: https://pypi.org/project/dm-aioaiagent
6
6
  Author: dimka4621
@@ -141,7 +141,8 @@ if __name__ == "__main__":
141
141
  ### Image vision
142
142
 
143
143
  ```python
144
- from dm_aioaiagent import DMAIAgent, ImageMessageContentBuilder
144
+ from dm_aioaiagent import DMAIAgent, OpenAIImageMessageContent
145
+
145
146
 
146
147
  def main():
147
148
  # create an agent
@@ -149,8 +150,8 @@ def main():
149
150
 
150
151
  # create an image message content
151
152
  # NOTE: text argument is optional
152
- img_content = ImageMessageContentBuilder(image_url="https://your.domain/image",
153
- text="Hello, what is shown in the photo?")
153
+ img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
154
+ text="Hello, what is shown in the photo?")
154
155
 
155
156
  # define the conversation message
156
157
  messages = [
@@ -163,7 +164,7 @@ def main():
163
164
 
164
165
 
165
166
  if __name__ == "__main__":
166
- main()
167
+ main()
167
168
  ```
168
169
 
169
170
  ### Set custom logger
@@ -117,7 +117,8 @@ if __name__ == "__main__":
117
117
  ### Image vision
118
118
 
119
119
  ```python
120
- from dm_aioaiagent import DMAIAgent, ImageMessageContentBuilder
120
+ from dm_aioaiagent import DMAIAgent, OpenAIImageMessageContent
121
+
121
122
 
122
123
  def main():
123
124
  # create an agent
@@ -125,8 +126,8 @@ def main():
125
126
 
126
127
  # create an image message content
127
128
  # NOTE: text argument is optional
128
- img_content = ImageMessageContentBuilder(image_url="https://your.domain/image",
129
- text="Hello, what is shown in the photo?")
129
+ img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
130
+ text="Hello, what is shown in the photo?")
130
131
 
131
132
  # define the conversation message
132
133
  messages = [
@@ -139,7 +140,7 @@ def main():
139
140
 
140
141
 
141
142
  if __name__ == "__main__":
142
- main()
143
+ main()
143
144
  ```
144
145
 
145
146
  ### Set custom logger
@@ -2,5 +2,5 @@ from dotenv import load_dotenv
2
2
  load_dotenv()
3
3
  from .ai_agent import DMAIAgent
4
4
  from .async_ai_agent import DMAioAIAgent
5
- from .image_message_content_builder import ImageMessageContentBuilder
5
+ from .openai_image_message_content import OpenAIImageMessageContent
6
6
  from .types import Message
@@ -2,7 +2,6 @@ import os
2
2
  from pydantic import SecretStr
3
3
  from itertools import dropwhile
4
4
  from threading import Thread
5
- from langchain_openai import ChatOpenAI
6
5
  from langchain_core.tools import BaseTool
7
6
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
8
7
  from langchain_core.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage
@@ -15,11 +14,11 @@ __all__ = ["DMAIAgent"]
15
14
 
16
15
 
17
16
  class DMAIAgent:
18
- agent_name = "AIAgent"
19
- _allowed_roles = ("user", "ai")
20
- _response_if_request_fail = "I can't provide a response right now. Please try again later."
21
- _response_if_invalid_image = "The image is unavailable or the link is incorrect."
17
+ AGENT_NAME = "AIAgent"
22
18
  MAX_MEMORY_MESSAGES = 20 # Only INT greater than 0
19
+ RESPONSE_IF_REQUEST_FAIL = "I can't provide a response right now. Please try again later."
20
+ RESPONSE_IF_INVALID_IMAGE = "The image is unavailable or the link is incorrect."
21
+ _ALLOWED_ROLES = ("user", "ai")
23
22
 
24
23
  def __init__(
25
24
  self,
@@ -33,47 +32,28 @@ class DMAIAgent:
33
32
  is_memory_enabled: bool = True,
34
33
  save_tools_responses_in_memory: bool = True,
35
34
  max_memory_messages: int = None,
35
+ llm_provider_api_key: str = "",
36
36
  response_if_request_fail: str = None,
37
- response_if_invalid_image: str = None,
38
- openai_api_key: str = None
37
+ response_if_invalid_image: str = None
39
38
  ):
40
- if openai_api_key is None and not os.getenv("OPENAI_API_KEY"):
41
- raise EnvironmentError("'OPENAI_API_KEY' environment variable is not set!")
39
+ self._logger = DMLogger(agent_name or self.AGENT_NAME)
40
+ self._input_output_logging = bool(input_output_logging)
42
41
 
43
- self._logger = DMLogger(agent_name or self.agent_name)
42
+ self._system_message = str(system_message)
43
+ self._tools = tools or []
44
44
  self._is_tools_exists = bool(tools)
45
- self._input_output_logging = bool(input_output_logging)
45
+ self._model = str(model)
46
+ self._temperature = int(temperature)
47
+ self._llm_provider_api_key = str(llm_provider_api_key)
48
+
46
49
  self._is_memory_enabled = bool(is_memory_enabled)
47
50
  self._save_tools_responses_in_memory = bool(save_tools_responses_in_memory)
48
51
  self._max_memory_messages = self._validate_max_memory_messages(max_memory_messages)
49
- self._response_if_request_fail = str(response_if_request_fail or self._response_if_request_fail)
50
- self._response_if_invalid_image = str(response_if_invalid_image or self._response_if_invalid_image)
52
+ self._response_if_request_fail = str(response_if_request_fail or self.RESPONSE_IF_REQUEST_FAIL)
53
+ self._response_if_invalid_image = str(response_if_invalid_image or self.RESPONSE_IF_INVALID_IMAGE)
51
54
 
52
- prompt = ChatPromptTemplate.from_messages([SystemMessage(content=system_message),
53
- MessagesPlaceholder(variable_name="messages")])
54
- if openai_api_key:
55
- openai_api_key = SecretStr(openai_api_key)
56
- llm = ChatOpenAI(model_name=str(model), temperature=int(temperature), openai_api_key=openai_api_key)
57
- if self._is_tools_exists:
58
- self._tool_map = {t.name: t for t in tools}
59
- llm = llm.bind_tools(tools)
60
- self._agent = prompt | llm
61
- self._memory = {}
62
-
63
- workflow = StateGraph(State)
64
- workflow.add_node("Prepare messages", self._prepare_messages_node)
65
- workflow.add_node("Invoke LLM", self._invoke_llm_node)
66
- workflow.add_node("Execute tool", self._execute_tool_node)
67
- workflow.add_node("Exit", self._exit_node)
68
-
69
- workflow.add_edge("Prepare messages", "Invoke LLM")
70
- workflow.add_conditional_edges(source="Invoke LLM",
71
- path=self._messages_router,
72
- path_map={"execute_tool": "Execute tool", "exit": "Exit"})
73
- workflow.add_edge("Execute tool", "Invoke LLM")
74
- workflow.set_entry_point("Prepare messages")
75
- workflow.set_finish_point("Exit")
76
- self._graph = workflow.compile()
55
+ self._init_agent()
56
+ self._init_graph()
77
57
 
78
58
  def run(self, input_messages: InputMessagesType, memory_id: str = None) -> ResponseType:
79
59
  state = self._graph.invoke({"input_messages": input_messages, "memory_id": memory_id})
@@ -102,7 +82,7 @@ class DMAIAgent:
102
82
  if isinstance(item, dict):
103
83
  role = item.get("role")
104
84
  content = item.get("content")
105
- if not role or role not in self._allowed_roles or not content:
85
+ if not role or role not in self._ALLOWED_ROLES or not content:
106
86
  continue
107
87
  if role == "ai":
108
88
  MessageClass = AIMessage
@@ -195,6 +175,49 @@ class DMAIAgent:
195
175
  route = "exit"
196
176
  return route
197
177
 
178
+ def _init_agent(self) -> None:
179
+ if self._llm_provider_api_key:
180
+ self._llm_provider_api_key = SecretStr(self._llm_provider_api_key)
181
+
182
+ if self._model.startswith("gpt"):
183
+ from langchain_openai import ChatOpenAI
184
+
185
+ api_key = SecretStr(self._llm_provider_api_key or os.getenv("OPENAI_API_KEY"))
186
+ llm = ChatOpenAI(model_name=self._model, temperature=self._temperature, openai_api_key=api_key)
187
+ elif self._model.startswith("claude"):
188
+ from langchain_anthropic import ChatAnthropic
189
+
190
+ api_key = SecretStr(self._llm_provider_api_key or os.getenv("ANTHROPIC_API_KEY"))
191
+ llm = ChatAnthropic(model=self._model, temperature=self._temperature, anthropic_api_key=api_key)
192
+ else:
193
+ raise ValueError(f"{self.__class__.__name__} not support this model: '{self._model}'")
194
+
195
+ if self._is_tools_exists:
196
+ self._tool_map = {t.name: t for t in self._tools}
197
+ llm = llm.bind_tools(self._tools)
198
+
199
+ prompt = ChatPromptTemplate.from_messages([SystemMessage(content=self._system_message),
200
+ MessagesPlaceholder(variable_name="messages")])
201
+
202
+ self._agent = prompt | llm
203
+ self._memory = {}
204
+
205
+ def _init_graph(self) -> None:
206
+ workflow = StateGraph(State)
207
+ workflow.add_node("Prepare messages", self._prepare_messages_node)
208
+ workflow.add_node("Invoke LLM", self._invoke_llm_node)
209
+ workflow.add_node("Execute tool", self._execute_tool_node)
210
+ workflow.add_node("Exit", self._exit_node)
211
+
212
+ workflow.add_edge("Prepare messages", "Invoke LLM")
213
+ workflow.add_conditional_edges(source="Invoke LLM",
214
+ path=self._messages_router,
215
+ path_map={"execute_tool": "Execute tool", "exit": "Exit"})
216
+ workflow.add_edge("Execute tool", "Invoke LLM")
217
+ workflow.set_entry_point("Prepare messages")
218
+ workflow.set_finish_point("Exit")
219
+ self._graph = workflow.compile()
220
+
198
221
  @staticmethod
199
222
  def _validate_memory_id(memory_id: Union[str, None]) -> Union[str, int]:
200
223
  return str(memory_id) if memory_id else 0
@@ -1,4 +1,4 @@
1
- class ImageMessageContentBuilder(list):
1
+ class OpenAIImageMessageContent(list):
2
2
  def __init__(self, image_url: str, text: str = None):
3
3
  content = []
4
4
  if isinstance(text, str):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dm-aioaiagent
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: This is my custom aioaiagent client
5
5
  Home-page: https://pypi.org/project/dm-aioaiagent
6
6
  Author: dimka4621
@@ -141,7 +141,8 @@ if __name__ == "__main__":
141
141
  ### Image vision
142
142
 
143
143
  ```python
144
- from dm_aioaiagent import DMAIAgent, ImageMessageContentBuilder
144
+ from dm_aioaiagent import DMAIAgent, OpenAIImageMessageContent
145
+
145
146
 
146
147
  def main():
147
148
  # create an agent
@@ -149,8 +150,8 @@ def main():
149
150
 
150
151
  # create an image message content
151
152
  # NOTE: text argument is optional
152
- img_content = ImageMessageContentBuilder(image_url="https://your.domain/image",
153
- text="Hello, what is shown in the photo?")
153
+ img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
154
+ text="Hello, what is shown in the photo?")
154
155
 
155
156
  # define the conversation message
156
157
  messages = [
@@ -163,7 +164,7 @@ def main():
163
164
 
164
165
 
165
166
  if __name__ == "__main__":
166
- main()
167
+ main()
167
168
  ```
168
169
 
169
170
  ### Set custom logger
@@ -4,7 +4,7 @@ setup.py
4
4
  dm_aioaiagent/__init__.py
5
5
  dm_aioaiagent/ai_agent.py
6
6
  dm_aioaiagent/async_ai_agent.py
7
- dm_aioaiagent/image_message_content_builder.py
7
+ dm_aioaiagent/openai_image_message_content.py
8
8
  dm_aioaiagent/types.py
9
9
  dm_aioaiagent.egg-info/PKG-INFO
10
10
  dm_aioaiagent.egg-info/SOURCES.txt
@@ -8,7 +8,7 @@ def readme():
8
8
 
9
9
  setup(
10
10
  name='dm-aioaiagent',
11
- version='v0.3.4',
11
+ version='v0.3.5',
12
12
  author='dimka4621',
13
13
  author_email='mismartconfig@gmail.com',
14
14
  description='This is my custom aioaiagent client',
File without changes