dm-aioaiagent 0.3.6__tar.gz → 0.4.0__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.6
3
+ Version: 0.4.0
4
4
  Summary: This is my custom aioaiagent client
5
5
  Home-page: https://pypi.org/project/dm-aioaiagent
6
6
  Author: dimka4621
@@ -35,7 +35,7 @@ Requires-Dist: langchain-openai~=0.2.0
35
35
 
36
36
  Analogue to `DMAioAIAgent` is the synchronous client `DMAIAgent`.
37
37
 
38
- ### Use agent *with* inner memory
38
+ ### Use agent *with* inner memory and run *single* message
39
39
 
40
40
  By default, agent use inner memory to store the conversation history.
41
41
 
@@ -61,35 +61,24 @@ async def main():
61
61
  # if you don't want to see the input and output messages from agent
62
62
  # you can set `input_output_logging=False` init argument
63
63
 
64
- # define the conversation message
65
- input_messages = [
66
- {"role": "user", "content": "Hello!"},
67
- ]
68
-
69
64
  # call an agent
70
- # specify `memory_id` argument to store the conversation history by your custom id
71
- answer = await ai_agent.run(input_messages)
72
-
73
- # define the next conversation message
74
- input_messages = [
75
- {"role": "user", "content": "I want to know the weather in Kyiv"}
76
- ]
65
+ answer = await ai_agent.run("Hello!")
77
66
 
78
67
  # call an agent
79
- answer = await ai_agent.run(input_messages)
68
+ answer = await ai_agent.run("I want to know the weather in Kyiv")
80
69
 
81
70
  # get full conversation history
82
- conversation_history = ai_agent.get_memory_messages()
71
+ conversation_history = ai_agent.memory_messages
83
72
 
84
73
  # clear conversation history
85
- ai_agent.clear_memory()
74
+ ai_agent.clear_memory_messages()
86
75
 
87
76
 
88
77
  if __name__ == "__main__":
89
78
  asyncio.run(main())
90
79
  ```
91
80
 
92
- ### Use agent *without* inner memory
81
+ ### Use agent *without* inner memory and run *multiple* messages
93
82
 
94
83
  If you want to control the memory of the agent, you can disable it by setting `is_memory_enabled=False`
95
84
 
@@ -114,13 +103,13 @@ async def main():
114
103
  # if you don't want to see the input and output messages from agent
115
104
  # you can set input_output_logging=False
116
105
 
117
- # define the conversation message
106
+ # define the conversation message(s)
118
107
  messages = [
119
108
  {"role": "user", "content": "Hello!"}
120
109
  ]
121
110
 
122
111
  # call an agent
123
- new_messages = await ai_agent.run(messages)
112
+ new_messages = await ai_agent.run_messages(messages)
124
113
 
125
114
  # add new_messages to messages
126
115
  messages.extend(new_messages)
@@ -131,7 +120,7 @@ async def main():
131
120
  )
132
121
 
133
122
  # call an agent
134
- new_messages = await ai_agent.run(messages)
123
+ new_messages = await ai_agent.run_messages(messages)
135
124
 
136
125
 
137
126
  if __name__ == "__main__":
@@ -153,14 +142,15 @@ def main():
153
142
  img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
154
143
  text="Hello, what is shown in the photo?")
155
144
 
156
- # define the conversation message
145
+ # define the conversation messages
157
146
  messages = [
158
147
  {"role": "user", "content": "Hello!"},
159
148
  {"role": "user", "content": img_content},
160
149
  ]
161
150
 
162
151
  # call an agent
163
- answer = ai_agent.run(messages)
152
+ new_messages = ai_agent.run_messages(messages)
153
+ answer = new_messages[-1].content
164
154
 
165
155
 
166
156
  if __name__ == "__main__":
@@ -11,7 +11,7 @@
11
11
 
12
12
  Analogue to `DMAioAIAgent` is the synchronous client `DMAIAgent`.
13
13
 
14
- ### Use agent *with* inner memory
14
+ ### Use agent *with* inner memory and run *single* message
15
15
 
16
16
  By default, agent use inner memory to store the conversation history.
17
17
 
@@ -37,35 +37,24 @@ async def main():
37
37
  # if you don't want to see the input and output messages from agent
38
38
  # you can set `input_output_logging=False` init argument
39
39
 
40
- # define the conversation message
41
- input_messages = [
42
- {"role": "user", "content": "Hello!"},
43
- ]
44
-
45
40
  # call an agent
46
- # specify `memory_id` argument to store the conversation history by your custom id
47
- answer = await ai_agent.run(input_messages)
48
-
49
- # define the next conversation message
50
- input_messages = [
51
- {"role": "user", "content": "I want to know the weather in Kyiv"}
52
- ]
41
+ answer = await ai_agent.run("Hello!")
53
42
 
54
43
  # call an agent
55
- answer = await ai_agent.run(input_messages)
44
+ answer = await ai_agent.run("I want to know the weather in Kyiv")
56
45
 
57
46
  # get full conversation history
58
- conversation_history = ai_agent.get_memory_messages()
47
+ conversation_history = ai_agent.memory_messages
59
48
 
60
49
  # clear conversation history
61
- ai_agent.clear_memory()
50
+ ai_agent.clear_memory_messages()
62
51
 
63
52
 
64
53
  if __name__ == "__main__":
65
54
  asyncio.run(main())
66
55
  ```
67
56
 
68
- ### Use agent *without* inner memory
57
+ ### Use agent *without* inner memory and run *multiple* messages
69
58
 
70
59
  If you want to control the memory of the agent, you can disable it by setting `is_memory_enabled=False`
71
60
 
@@ -90,13 +79,13 @@ async def main():
90
79
  # if you don't want to see the input and output messages from agent
91
80
  # you can set input_output_logging=False
92
81
 
93
- # define the conversation message
82
+ # define the conversation message(s)
94
83
  messages = [
95
84
  {"role": "user", "content": "Hello!"}
96
85
  ]
97
86
 
98
87
  # call an agent
99
- new_messages = await ai_agent.run(messages)
88
+ new_messages = await ai_agent.run_messages(messages)
100
89
 
101
90
  # add new_messages to messages
102
91
  messages.extend(new_messages)
@@ -107,7 +96,7 @@ async def main():
107
96
  )
108
97
 
109
98
  # call an agent
110
- new_messages = await ai_agent.run(messages)
99
+ new_messages = await ai_agent.run_messages(messages)
111
100
 
112
101
 
113
102
  if __name__ == "__main__":
@@ -129,14 +118,15 @@ def main():
129
118
  img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
130
119
  text="Hello, what is shown in the photo?")
131
120
 
132
- # define the conversation message
121
+ # define the conversation messages
133
122
  messages = [
134
123
  {"role": "user", "content": "Hello!"},
135
124
  {"role": "user", "content": img_content},
136
125
  ]
137
126
 
138
127
  # call an agent
139
- answer = ai_agent.run(messages)
128
+ new_messages = ai_agent.run_messages(messages)
129
+ answer = new_messages[-1].content
140
130
 
141
131
 
142
132
  if __name__ == "__main__":
@@ -3,4 +3,3 @@ load_dotenv()
3
3
  from .ai_agent import DMAIAgent
4
4
  from .async_ai_agent import DMAioAIAgent
5
5
  from .openai_image_message_content import OpenAIImageMessageContent
6
- from .types import Message
@@ -1,4 +1,6 @@
1
1
  import os
2
+ import uuid
3
+ from typing import Any
2
4
  from pydantic import SecretStr
3
5
  from itertools import dropwhile
4
6
  from threading import Thread
@@ -14,10 +16,7 @@ __all__ = ["DMAIAgent"]
14
16
 
15
17
 
16
18
  class DMAIAgent:
17
- AGENT_NAME = "AIAgent"
18
19
  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
20
  _ALLOWED_ROLES = ("user", "ai")
22
21
 
23
22
  def __init__(
@@ -28,16 +27,16 @@ class DMAIAgent:
28
27
  model: str = "gpt-4o-mini",
29
28
  temperature: int = 1,
30
29
  parallel_tool_calls: bool = True,
31
- agent_name: str = None,
30
+ agent_name: str = "AIAgent",
32
31
  input_output_logging: bool = True,
33
32
  is_memory_enabled: bool = True,
33
+ max_memory_messages: int = MAX_MEMORY_MESSAGES,
34
34
  save_tools_responses_in_memory: bool = True,
35
- max_memory_messages: int = None,
36
35
  llm_provider_api_key: str = "",
37
- response_if_request_fail: str = None,
38
- response_if_invalid_image: str = None
36
+ response_if_request_fail: str = "I can't provide a response right now. Please try again later.",
37
+ response_if_invalid_image: str = "The image is unavailable or the link is incorrect."
39
38
  ):
40
- self._logger = DMLogger(agent_name or self.AGENT_NAME)
39
+ self._logger = DMLogger(agent_name)
41
40
  self._input_output_logging = bool(input_output_logging)
42
41
 
43
42
  self._system_message = str(system_message)
@@ -48,39 +47,57 @@ class DMAIAgent:
48
47
  self._parallel_tool_calls = bool(parallel_tool_calls)
49
48
  self._llm_provider_api_key = str(llm_provider_api_key)
50
49
 
50
+ self._memory_messages = []
51
51
  self._is_memory_enabled = bool(is_memory_enabled)
52
52
  self._save_tools_responses_in_memory = bool(save_tools_responses_in_memory)
53
53
  self._max_memory_messages = self._validate_max_memory_messages(max_memory_messages)
54
- self._response_if_request_fail = str(response_if_request_fail or self.RESPONSE_IF_REQUEST_FAIL)
55
- self._response_if_invalid_image = str(response_if_invalid_image or self.RESPONSE_IF_INVALID_IMAGE)
54
+ self._response_if_request_fail = str(response_if_request_fail)
55
+ self._response_if_invalid_image = str(response_if_invalid_image)
56
56
 
57
+ self._check_langsmith_envs()
57
58
  self._init_agent()
58
59
  self._init_graph()
59
60
 
60
- def run(self, input_messages: InputMessagesType, memory_id: str = None) -> ResponseType:
61
- state = self._graph.invoke({"input_messages": input_messages, "memory_id": memory_id})
62
- return state["response"]
61
+ def run(self, query: str, **kwargs) -> str:
62
+ new_messages = self.run_messages(messages=[{"role": "user", "content": query}], **kwargs)
63
+ return new_messages[-1].content
63
64
 
64
- def get_memory_messages(
65
+ def run_messages(
65
66
  self,
66
- memory_id: str = None,
67
+ messages: InputMessagesType,
67
68
  *,
68
- without_tool_m: bool = False,
69
- return_str_m: bool = False
70
- ) -> Union[list[BaseMessage], list[str]]:
71
- messages = self._memory.get(self._validate_memory_id(memory_id), [])
72
- if without_tool_m:
73
- messages = [m for m in messages if not (m.type == "tool" or (m.type == "ai" and m.tool_calls))]
74
- if return_str_m:
75
- messages = [m.content for m in messages]
76
- return messages
77
-
78
- def clear_memory(self, memory_id: str = None) -> None:
79
- self._memory[self._validate_memory_id(memory_id)] = []
69
+ ls_metadata: dict[str, Any] = None,
70
+ ls_tags: list[str] = None,
71
+ ls_run_id: uuid.UUID = None,
72
+ ls_thread_id: uuid.UUID = None
73
+ ) -> list[BaseMessage]:
74
+ if ls_metadata is None:
75
+ ls_metadata = {}
76
+ if isinstance(ls_run_id, uuid.UUID):
77
+ ls_run_id = ls_run_id
78
+ if isinstance(ls_thread_id, uuid.UUID):
79
+ ls_metadata["thread_id"] = ls_thread_id
80
+
81
+ config_data = {
82
+ "metadata": ls_metadata,
83
+ "tags": ls_tags,
84
+ "run_id": ls_run_id
85
+ }
86
+ state = self._graph.invoke(input={"messages": messages, "new_messages": []},
87
+ config={k: v for k, v in config_data.items() if v})
88
+ return state["new_messages"]
89
+
90
+ @property
91
+ def memory_messages(self) -> list[BaseMessage]:
92
+ return self._memory_messages
93
+
94
+ def clear_memory_messages(self) -> None:
95
+ self._memory_messages.clear()
80
96
 
81
97
  def _prepare_messages_node(self, state: State) -> State:
82
- state.input_messages = state.input_messages or [{"role": "user", "content": ""}]
83
- for item in state.input_messages:
98
+ messages = state["messages"] or [{"role": "user", "content": ""}]
99
+ state["messages"] = []
100
+ for item in messages:
84
101
  if isinstance(item, dict):
85
102
  role = item.get("role")
86
103
  content = item.get("content")
@@ -90,35 +107,35 @@ class DMAIAgent:
90
107
  MessageClass = AIMessage
91
108
  else:
92
109
  MessageClass = HumanMessage
93
- state.messages.append(MessageClass(content))
110
+ state["messages"].append(MessageClass(content))
94
111
  elif isinstance(item, BaseMessage):
95
- state.messages.append(item)
112
+ state["messages"].append(item)
96
113
 
97
114
  if self._input_output_logging:
98
- log_kwargs = {} if state.memory_id is None else {"memory_id": state.memory_id}
99
- self._logger.debug(f"Query:\n{state.messages[-1].content}", **log_kwargs)
115
+ self._logger.debug(f'Query:\n{state["messages"][-1].content}')
100
116
  if self._is_memory_enabled:
101
- state.messages = self.get_memory_messages(state.memory_id) + state.messages
117
+ state["messages"] = self._memory_messages + state["messages"]
102
118
  return state
103
119
 
104
120
  def _invoke_llm_node(self, state: State, second_attempt: bool = False) -> State:
105
121
  self._logger.debug("Run node: Invoke LLM")
106
122
  try:
107
- ai_response = self._agent.invoke({"messages": state.messages})
123
+ ai_response = self._agent.invoke({"messages": state["messages"]})
108
124
  except Exception as e:
109
125
  self._logger.error(e)
110
126
  if second_attempt:
111
127
  response = self._response_if_invalid_image if "invalid_image_url" in str(e) else self._response_if_request_fail
112
- state.messages.append(AIMessage(content=response))
128
+ state["messages"].append(AIMessage(content=response))
113
129
  return state
114
130
  return self._invoke_llm_node(state, second_attempt=True)
115
- state.messages.append(ai_response)
131
+ state["messages"].append(ai_response)
132
+ state["new_messages"].append(ai_response)
116
133
  return state
117
134
 
118
135
  def _execute_tool_node(self, state: State) -> State:
119
136
  self._logger.debug("Run node: Execute tool")
120
137
  threads = []
121
- for tool_call in state.messages[-1].tool_calls:
138
+ for tool_call in state["messages"][-1].tool_calls:
122
139
  tool_id = tool_call["id"]
123
140
  tool_name = tool_call["name"]
124
141
  tool_args = tool_call["args"]
@@ -136,7 +153,8 @@ class DMAIAgent:
136
153
  self._logger.debug(f"Tool response:\n{tool_response}", tool_id=tool_id)
137
154
 
138
155
  tool_message = ToolMessage(content=str(tool_response), name=tool_name, tool_call_id=tool_id)
139
- state.messages.append(tool_message)
156
+ state["messages"].append(tool_message)
157
+ state["new_messages"].append(tool_message)
140
158
 
141
159
  threads.append(Thread(target=tool_callback, daemon=True))
142
160
 
@@ -144,34 +162,27 @@ class DMAIAgent:
144
162
  t.start()
145
163
  for t in threads:
146
164
  t.join()
147
-
148
165
  return state
149
166
 
150
167
  def _exit_node(self, state: State) -> State:
151
- answer = state.messages[-1].content
152
168
  if self._input_output_logging:
153
- log_kwargs = {} if state.memory_id is None else {"memory_id": state.memory_id}
154
- self._logger.debug(f"Answer:\n{answer}", **log_kwargs)
169
+ self._logger.debug(f'Answer:\n{state["messages"][-1].content}')
155
170
 
156
171
  if self._is_memory_enabled:
157
- memory_id = self._validate_memory_id(state.memory_id)
158
- messages_to_memory = state.messages[-self._max_memory_messages:]
172
+ messages_to_memory = state["messages"][-self._max_memory_messages:]
159
173
  if self._save_tools_responses_in_memory:
160
174
  # drop ToolsMessages from start of list
161
- self._memory[memory_id] = list(dropwhile(lambda x: isinstance(x, ToolMessage), messages_to_memory))
175
+ self._memory_messages = list(dropwhile(lambda x: isinstance(x, ToolMessage), messages_to_memory))
162
176
  else:
163
- self._memory[memory_id] = []
177
+ self._memory_messages.clear()
164
178
  for mes in messages_to_memory:
165
179
  if isinstance(mes, ToolMessage) or (isinstance(mes, AIMessage) and mes.tool_calls):
166
180
  continue
167
- self._memory[memory_id].append(mes)
168
- state.response = answer
169
- else:
170
- state.response = state.messages[len(state.input_messages):]
181
+ self._memory_messages.append(mes)
171
182
  return state
172
183
 
173
184
  def _messages_router(self, state: State) -> str:
174
- if self._is_tools_exists and state.messages[-1].tool_calls:
185
+ if self._is_tools_exists and state["messages"][-1].tool_calls:
175
186
  route = "execute_tool"
176
187
  else:
177
188
  route = "exit"
@@ -202,7 +213,6 @@ class DMAIAgent:
202
213
  MessagesPlaceholder(variable_name="messages")])
203
214
 
204
215
  self._agent = prompt | llm
205
- self._memory = {}
206
216
 
207
217
  def _init_graph(self) -> None:
208
218
  workflow = StateGraph(State)
@@ -221,8 +231,12 @@ class DMAIAgent:
221
231
  self._graph = workflow.compile()
222
232
 
223
233
  @staticmethod
224
- def _validate_memory_id(memory_id: Union[str, None]) -> Union[str, int]:
225
- return str(memory_id) if memory_id else 0
234
+ def _check_langsmith_envs() -> None:
235
+ if os.getenv("LANGCHAIN_API_KEY"):
236
+ if not os.getenv("LANGCHAIN_TRACING_V2"):
237
+ os.environ["LANGCHAIN_TRACING_V2"] = "true"
238
+ if not os.getenv("LANGCHAIN_ENDPOINT"):
239
+ os.environ["LANGCHAIN_ENDPOINT"] = "https://api.smith.langchain.com"
226
240
 
227
241
  @classmethod
228
242
  def _validate_max_memory_messages(cls, max_messages_in_memory: int) -> int:
@@ -1,5 +1,7 @@
1
1
  import sys
2
+ import uuid
2
3
  import asyncio
4
+ from typing import Any
3
5
  from langchain_core.messages import AIMessage, ToolMessage
4
6
 
5
7
  from .ai_agent import DMAIAgent
@@ -14,28 +16,54 @@ __all__ = ["DMAioAIAgent"]
14
16
  class DMAioAIAgent(DMAIAgent):
15
17
  agent_name = "AsyncAIAgent"
16
18
 
17
- async def run(self, input_messages: InputMessagesType, memory_id: str = None) -> ResponseType:
18
- state = await self._graph.ainvoke({"input_messages": input_messages, "memory_id": memory_id})
19
- return state["response"]
19
+ async def run(self, query: str, **kwargs) -> str:
20
+ new_messages = await self.run_messages(messages=[{"role": "user", "content": query}], **kwargs)
21
+ return new_messages[-1].content
22
+
23
+ async def run_messages(
24
+ self,
25
+ messages: InputMessagesType,
26
+ *,
27
+ ls_metadata: dict[str, Any] = None,
28
+ ls_tags: list[str] = None,
29
+ ls_run_id: uuid.UUID = None,
30
+ ls_thread_id: uuid.UUID = None
31
+ ) -> list[BaseMessage]:
32
+ if ls_metadata is None:
33
+ ls_metadata = {}
34
+ if isinstance(ls_run_id, uuid.UUID):
35
+ ls_run_id = ls_run_id
36
+ if isinstance(ls_thread_id, uuid.UUID):
37
+ ls_metadata["thread_id"] = ls_thread_id
38
+
39
+ config_data = {
40
+ "metadata": ls_metadata,
41
+ "tags": ls_tags,
42
+ "run_id": ls_run_id
43
+ }
44
+ state = await self._graph.ainvoke(input={"messages": messages, "new_messages": []},
45
+ config={k: v for k, v in config_data.items() if v})
46
+ return state["new_messages"]
20
47
 
21
48
  async def _invoke_llm_node(self, state: State, second_attempt: bool = False) -> State:
22
49
  self._logger.debug("Run node: Invoke LLM")
23
50
  try:
24
- ai_response = await self._agent.ainvoke({"messages": state.messages})
51
+ ai_response = await self._agent.ainvoke({"messages": state["messages"]})
25
52
  except Exception as e:
26
53
  self._logger.error(e)
27
54
  if second_attempt:
28
55
  response = self._response_if_invalid_image if "invalid_image_url" in str(e) else self._response_if_request_fail
29
- state.messages.append(AIMessage(content=response))
56
+ state["messages"].append(AIMessage(content=response))
30
57
  return state
31
58
  return await self._invoke_llm_node(state, second_attempt=True)
32
- state.messages.append(ai_response)
59
+ state["messages"].append(ai_response)
60
+ state["new_messages"].append(ai_response)
33
61
  return state
34
62
 
35
63
  async def _execute_tool_node(self, state: State) -> State:
36
64
  self._logger.debug("Run node: Execute tool")
37
65
  tasks = []
38
- for tool_call in state.messages[-1].tool_calls:
66
+ for tool_call in state["messages"][-1].tool_calls:
39
67
  tool_id = tool_call["id"]
40
68
  tool_name = tool_call["name"]
41
69
  tool_args = tool_call["args"]
@@ -53,7 +81,8 @@ class DMAioAIAgent(DMAIAgent):
53
81
  self._logger.debug(f"Tool response:\n{tool_response}", tool_id=tool_id)
54
82
 
55
83
  tool_message = ToolMessage(content=str(tool_response), name=tool_name, tool_call_id=tool_id)
56
- state.messages.append(tool_message)
84
+ state["messages"].append(tool_message)
85
+ state["new_messages"].append(tool_message)
57
86
 
58
87
  tasks.append(asyncio.create_task(tool_callback()))
59
88
 
@@ -0,0 +1,30 @@
1
+ from typing import Literal, Union
2
+ from typing_extensions import TypedDict
3
+ from langchain_core.messages import BaseMessage
4
+
5
+
6
+ class ImageMessageTextMessage(TypedDict):
7
+ type: Literal['text']
8
+ text: str
9
+
10
+
11
+ class ImageMessageImageItem(TypedDict):
12
+ type: Literal['image_url']
13
+ image_url: dict
14
+
15
+
16
+ class ImageMessage(TypedDict):
17
+ role: Literal["user"]
18
+ content: list[Union[ImageMessageTextMessage, ImageMessageImageItem]]
19
+
20
+
21
+ class TextMessage(TypedDict):
22
+ role: Literal["user", "ai"]
23
+ content: str
24
+
25
+
26
+ InputMessagesType = list[Union[TextMessage, ImageMessage, BaseMessage]]
27
+
28
+ class State(TypedDict):
29
+ messages: InputMessagesType
30
+ new_messages: list[BaseMessage]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dm-aioaiagent
3
- Version: 0.3.6
3
+ Version: 0.4.0
4
4
  Summary: This is my custom aioaiagent client
5
5
  Home-page: https://pypi.org/project/dm-aioaiagent
6
6
  Author: dimka4621
@@ -35,7 +35,7 @@ Requires-Dist: langchain-openai~=0.2.0
35
35
 
36
36
  Analogue to `DMAioAIAgent` is the synchronous client `DMAIAgent`.
37
37
 
38
- ### Use agent *with* inner memory
38
+ ### Use agent *with* inner memory and run *single* message
39
39
 
40
40
  By default, agent use inner memory to store the conversation history.
41
41
 
@@ -61,35 +61,24 @@ async def main():
61
61
  # if you don't want to see the input and output messages from agent
62
62
  # you can set `input_output_logging=False` init argument
63
63
 
64
- # define the conversation message
65
- input_messages = [
66
- {"role": "user", "content": "Hello!"},
67
- ]
68
-
69
64
  # call an agent
70
- # specify `memory_id` argument to store the conversation history by your custom id
71
- answer = await ai_agent.run(input_messages)
72
-
73
- # define the next conversation message
74
- input_messages = [
75
- {"role": "user", "content": "I want to know the weather in Kyiv"}
76
- ]
65
+ answer = await ai_agent.run("Hello!")
77
66
 
78
67
  # call an agent
79
- answer = await ai_agent.run(input_messages)
68
+ answer = await ai_agent.run("I want to know the weather in Kyiv")
80
69
 
81
70
  # get full conversation history
82
- conversation_history = ai_agent.get_memory_messages()
71
+ conversation_history = ai_agent.memory_messages
83
72
 
84
73
  # clear conversation history
85
- ai_agent.clear_memory()
74
+ ai_agent.clear_memory_messages()
86
75
 
87
76
 
88
77
  if __name__ == "__main__":
89
78
  asyncio.run(main())
90
79
  ```
91
80
 
92
- ### Use agent *without* inner memory
81
+ ### Use agent *without* inner memory and run *multiple* messages
93
82
 
94
83
  If you want to control the memory of the agent, you can disable it by setting `is_memory_enabled=False`
95
84
 
@@ -114,13 +103,13 @@ async def main():
114
103
  # if you don't want to see the input and output messages from agent
115
104
  # you can set input_output_logging=False
116
105
 
117
- # define the conversation message
106
+ # define the conversation message(s)
118
107
  messages = [
119
108
  {"role": "user", "content": "Hello!"}
120
109
  ]
121
110
 
122
111
  # call an agent
123
- new_messages = await ai_agent.run(messages)
112
+ new_messages = await ai_agent.run_messages(messages)
124
113
 
125
114
  # add new_messages to messages
126
115
  messages.extend(new_messages)
@@ -131,7 +120,7 @@ async def main():
131
120
  )
132
121
 
133
122
  # call an agent
134
- new_messages = await ai_agent.run(messages)
123
+ new_messages = await ai_agent.run_messages(messages)
135
124
 
136
125
 
137
126
  if __name__ == "__main__":
@@ -153,14 +142,15 @@ def main():
153
142
  img_content = OpenAIImageMessageContent(image_url="https://your.domain/image",
154
143
  text="Hello, what is shown in the photo?")
155
144
 
156
- # define the conversation message
145
+ # define the conversation messages
157
146
  messages = [
158
147
  {"role": "user", "content": "Hello!"},
159
148
  {"role": "user", "content": img_content},
160
149
  ]
161
150
 
162
151
  # call an agent
163
- answer = ai_agent.run(messages)
152
+ new_messages = ai_agent.run_messages(messages)
153
+ answer = new_messages[-1].content
164
154
 
165
155
 
166
156
  if __name__ == "__main__":
@@ -8,7 +8,7 @@ def readme():
8
8
 
9
9
  setup(
10
10
  name='dm-aioaiagent',
11
- version='v0.3.6',
11
+ version='v0.4.0',
12
12
  author='dimka4621',
13
13
  author_email='mismartconfig@gmail.com',
14
14
  description='This is my custom aioaiagent client',
@@ -1,41 +0,0 @@
1
- from typing import Optional, Literal, Union
2
- from typing_extensions import TypedDict
3
- from pydantic import BaseModel, Field
4
- from langchain_core.messages import BaseMessage
5
-
6
-
7
- class ImageMessageTextMessage(TypedDict):
8
- type: Literal['text']
9
- text: str
10
-
11
-
12
- class ImageMessageImageItem(TypedDict):
13
- type: Literal['image_url']
14
- image_url: dict
15
-
16
-
17
- ImageMessageContent = list[Union[ImageMessageTextMessage, ImageMessageImageItem]]
18
-
19
-
20
- class ImageMessage(TypedDict):
21
- role: Literal["user"]
22
- content: ImageMessageContent
23
-
24
-
25
- class TextMessage(TypedDict):
26
- role: Literal["user", "ai"]
27
- content: str
28
-
29
-
30
- Message = Union[TextMessage, ImageMessage]
31
-
32
- InputMessagesType = list[Union[Message, BaseMessage]]
33
-
34
- ResponseType = Union[str, list[BaseMessage]]
35
-
36
-
37
- class State(BaseModel):
38
- input_messages: InputMessagesType
39
- memory_id: Union[str, int, None] = Field(default=0)
40
- messages: Optional[list[BaseMessage]] = Field(default_factory=list)
41
- response: ResponseType = Field(default="")
File without changes