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.
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/PKG-INFO +6 -5
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/README.md +5 -4
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent/__init__.py +1 -1
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent/ai_agent.py +62 -39
- dm_aioaiagent-0.3.4/dm_aioaiagent/image_message_content_builder.py → dm_aioaiagent-0.3.5/dm_aioaiagent/openai_image_message_content.py +1 -1
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent.egg-info/PKG-INFO +6 -5
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent.egg-info/SOURCES.txt +1 -1
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/setup.py +1 -1
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent/async_ai_agent.py +0 -0
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent/types.py +0 -0
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent.egg-info/dependency_links.txt +0 -0
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent.egg-info/requires.txt +0 -0
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/dm_aioaiagent.egg-info/top_level.txt +0 -0
- {dm_aioaiagent-0.3.4 → dm_aioaiagent-0.3.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dm-aioaiagent
|
|
3
|
-
Version: 0.3.
|
|
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,
|
|
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 =
|
|
153
|
-
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
129
|
-
|
|
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
|
-
|
|
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 .
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
39
|
+
self._logger = DMLogger(agent_name or self.AGENT_NAME)
|
|
40
|
+
self._input_output_logging = bool(input_output_logging)
|
|
42
41
|
|
|
43
|
-
self.
|
|
42
|
+
self._system_message = str(system_message)
|
|
43
|
+
self._tools = tools or []
|
|
44
44
|
self._is_tools_exists = bool(tools)
|
|
45
|
-
self.
|
|
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.
|
|
50
|
-
self._response_if_invalid_image = str(response_if_invalid_image or self.
|
|
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
|
-
|
|
53
|
-
|
|
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.
|
|
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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dm-aioaiagent
|
|
3
|
-
Version: 0.3.
|
|
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,
|
|
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 =
|
|
153
|
-
|
|
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
|
-
|
|
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/
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|