llm-dialog-manager 0.4.4__py3-none-any.whl → 0.4.6__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.
- llm_dialog_manager/__init__.py +1 -1
- llm_dialog_manager/agent.py +95 -32
- {llm_dialog_manager-0.4.4.dist-info → llm_dialog_manager-0.4.6.dist-info}/METADATA +1 -1
- llm_dialog_manager-0.4.6.dist-info/RECORD +9 -0
- llm_dialog_manager-0.4.4.dist-info/RECORD +0 -9
- {llm_dialog_manager-0.4.4.dist-info → llm_dialog_manager-0.4.6.dist-info}/LICENSE +0 -0
- {llm_dialog_manager-0.4.4.dist-info → llm_dialog_manager-0.4.6.dist-info}/WHEEL +0 -0
- {llm_dialog_manager-0.4.4.dist-info → llm_dialog_manager-0.4.6.dist-info}/top_level.txt +0 -0
llm_dialog_manager/__init__.py
CHANGED
llm_dialog_manager/agent.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import json
|
3
3
|
import os
|
4
4
|
import uuid
|
5
|
-
from typing import List, Dict, Optional,
|
5
|
+
from typing import List, Dict, Union, Optional, Any
|
6
6
|
import logging
|
7
7
|
from pathlib import Path
|
8
8
|
import random
|
@@ -97,13 +97,30 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
97
97
|
api_key = os.getenv(f"{service.upper()}_API_KEY")
|
98
98
|
base_url = os.getenv(f"{service.upper()}_BASE_URL")
|
99
99
|
|
100
|
-
def format_messages_for_api(
|
101
|
-
|
100
|
+
def format_messages_for_api(
|
101
|
+
model: str,
|
102
|
+
messages: List[Dict[str, Union[str, List[Union[str, Image.Image, Dict]]]]]
|
103
|
+
) -> tuple[Optional[str], List[Dict[str, Any]]]:
|
104
|
+
"""
|
105
|
+
Convert ChatHistory messages to the format required by the specific API.
|
106
|
+
|
107
|
+
Args:
|
108
|
+
model: The model name (e.g., "claude", "gemini", "gpt")
|
109
|
+
messages: List of message dictionaries with role and content
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
tuple: (system_message, formatted_messages)
|
113
|
+
- system_message is extracted system message for Claude, None for others
|
114
|
+
- formatted_messages is the list of formatted message dictionaries
|
115
|
+
"""
|
102
116
|
if "claude" in model and "openai" not in model:
|
103
117
|
formatted = []
|
104
118
|
system_msg = ""
|
119
|
+
|
120
|
+
# Extract system message if present
|
105
121
|
if messages and messages[0]["role"] == "system":
|
106
122
|
system_msg = messages.pop(0)["content"]
|
123
|
+
|
107
124
|
for msg in messages:
|
108
125
|
content = msg["content"]
|
109
126
|
if isinstance(content, str):
|
@@ -113,9 +130,12 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
113
130
|
combined_content = []
|
114
131
|
for block in content:
|
115
132
|
if isinstance(block, str):
|
116
|
-
combined_content.append({
|
133
|
+
combined_content.append({
|
134
|
+
"type": "text",
|
135
|
+
"text": block
|
136
|
+
})
|
117
137
|
elif isinstance(block, Image.Image):
|
118
|
-
#
|
138
|
+
# Convert PIL.Image to base64
|
119
139
|
buffered = io.BytesIO()
|
120
140
|
block.save(buffered, format="PNG")
|
121
141
|
image_base64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
@@ -145,9 +165,12 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
145
165
|
"data": block["image_base64"]["data"]
|
146
166
|
}
|
147
167
|
})
|
148
|
-
formatted.append({
|
168
|
+
formatted.append({
|
169
|
+
"role": msg["role"],
|
170
|
+
"content": combined_content
|
171
|
+
})
|
149
172
|
return system_msg, formatted
|
150
|
-
|
173
|
+
|
151
174
|
elif ("gemini" in model or "gpt" in model or "grok" in model) and "openai" not in model:
|
152
175
|
formatted = []
|
153
176
|
for msg in messages:
|
@@ -160,40 +183,75 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
160
183
|
if isinstance(block, str):
|
161
184
|
parts.append(block)
|
162
185
|
elif isinstance(block, Image.Image):
|
186
|
+
# Keep PIL.Image objects as is for Gemini
|
163
187
|
parts.append(block)
|
164
188
|
elif isinstance(block, dict):
|
165
189
|
if block.get("type") == "image_url":
|
166
|
-
parts.append({
|
190
|
+
parts.append({
|
191
|
+
"type": "image_url",
|
192
|
+
"image_url": {
|
193
|
+
"url": block["image_url"]["url"]
|
194
|
+
}
|
195
|
+
})
|
167
196
|
elif block.get("type") == "image_base64":
|
168
|
-
parts.append({
|
169
|
-
|
197
|
+
parts.append({
|
198
|
+
"type": "image_base64",
|
199
|
+
"image_base64": {
|
200
|
+
"data": block["image_base64"]["data"],
|
201
|
+
"media_type": block["image_base64"]["media_type"]
|
202
|
+
}
|
203
|
+
})
|
204
|
+
formatted.append({
|
205
|
+
"role": msg["role"],
|
206
|
+
"parts": parts
|
207
|
+
})
|
170
208
|
return None, formatted
|
171
|
-
|
209
|
+
|
172
210
|
else: # OpenAI models
|
173
211
|
formatted = []
|
174
212
|
for msg in messages:
|
175
213
|
content = msg["content"]
|
176
214
|
if isinstance(content, str):
|
177
|
-
formatted.append({
|
215
|
+
formatted.append({
|
216
|
+
"role": msg["role"],
|
217
|
+
"content": content
|
218
|
+
})
|
178
219
|
elif isinstance(content, list):
|
179
|
-
|
180
|
-
# You can convert images to URLs or descriptions if needed
|
181
|
-
combined_content = ""
|
220
|
+
formatted_content = []
|
182
221
|
for block in content:
|
183
222
|
if isinstance(block, str):
|
184
|
-
|
223
|
+
formatted_content.append({
|
224
|
+
"type": "text",
|
225
|
+
"text": block
|
226
|
+
})
|
185
227
|
elif isinstance(block, Image.Image):
|
186
|
-
# Convert PIL.Image to base64
|
228
|
+
# Convert PIL.Image to base64
|
187
229
|
buffered = io.BytesIO()
|
188
230
|
block.save(buffered, format="PNG")
|
189
231
|
image_base64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
190
|
-
|
232
|
+
formatted_content.append({
|
233
|
+
"type": "image_url",
|
234
|
+
"image_url": {
|
235
|
+
"url": f"data:image/jpeg;base64,{image_base64}"
|
236
|
+
}
|
237
|
+
})
|
191
238
|
elif isinstance(block, dict):
|
192
239
|
if block.get("type") == "image_url":
|
193
|
-
|
240
|
+
formatted_content.append({
|
241
|
+
"type": "image_url",
|
242
|
+
"image_url": block["image_url"]
|
243
|
+
})
|
194
244
|
elif block.get("type") == "image_base64":
|
195
|
-
|
196
|
-
|
245
|
+
formatted_content.append({
|
246
|
+
"type": "image_url",
|
247
|
+
"image_url": {
|
248
|
+
"url": f"data:image/jpeg;base64,{block['image_base64']['data']}"
|
249
|
+
}
|
250
|
+
})
|
251
|
+
formatted.append({
|
252
|
+
"role": msg["role"],
|
253
|
+
"content": formatted_content
|
254
|
+
})
|
197
255
|
return None, formatted
|
198
256
|
|
199
257
|
system_msg, formatted_messages = format_messages_for_api(model, messages.copy())
|
@@ -336,16 +394,21 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
336
394
|
if model.endswith("-openai"):
|
337
395
|
model = model[:-7] # Remove last 7 characters ("-openai")
|
338
396
|
client = openai.OpenAI(api_key=api_key, base_url=base_url)
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
397
|
+
|
398
|
+
# Create base parameters
|
399
|
+
params = {
|
400
|
+
"model": model,
|
401
|
+
"messages": formatted_messages,
|
402
|
+
}
|
403
|
+
|
404
|
+
# Add optional parameters
|
405
|
+
if json_format:
|
406
|
+
params["response_format"] = {"type": "json_object"}
|
407
|
+
if not ("o1" in model or "o3" in model):
|
408
|
+
params["max_tokens"] = max_tokens
|
409
|
+
params["temperature"] = temperature
|
410
|
+
|
411
|
+
response = client.chat.completions.create(**params)
|
349
412
|
return response.choices[0].message.content
|
350
413
|
|
351
414
|
# Release the API key after successful use
|
@@ -546,7 +609,7 @@ class Agent:
|
|
546
609
|
if __name__ == "__main__":
|
547
610
|
# Example Usage
|
548
611
|
# Create an Agent instance (Gemini model)
|
549
|
-
agent = Agent("gemini-1.5-flash", "you are Jack101", memory_enabled=True)
|
612
|
+
agent = Agent("gemini-1.5-flash-openai", "you are Jack101", memory_enabled=True)
|
550
613
|
|
551
614
|
# Add an image
|
552
615
|
agent.add_image(image_path="example.png")
|
@@ -0,0 +1,9 @@
|
|
1
|
+
llm_dialog_manager/__init__.py,sha256=klLFvHayR7ew1Oh9xyhAXdXnfs82YnFUEFzw0YvxKJI,86
|
2
|
+
llm_dialog_manager/agent.py,sha256=NVQKIMebl4cYkqMaBceZ3qs1vYhq1bum9okAn8VcfCg,27680
|
3
|
+
llm_dialog_manager/chat_history.py,sha256=DKKRnj_M6h-4JncnH6KekMTghX7vMgdN3J9uOwXKzMU,10347
|
4
|
+
llm_dialog_manager/key_manager.py,sha256=shvxmn4zUtQx_p-x1EFyOmnk-WlhigbpKtxTKve-zXk,4421
|
5
|
+
llm_dialog_manager-0.4.6.dist-info/LICENSE,sha256=vWGbYgGuWpWrXL8-xi6pNcX5UzD6pWoIAZmcetyfbus,1064
|
6
|
+
llm_dialog_manager-0.4.6.dist-info/METADATA,sha256=-qTRYkfAJMJCQTkRqNrtHjUuN-xGLhLR4CJvSJURgeg,4194
|
7
|
+
llm_dialog_manager-0.4.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
8
|
+
llm_dialog_manager-0.4.6.dist-info/top_level.txt,sha256=u2EQEXW0NGAt0AAHT7jx1odXZ4rZfjcgbmJhvKFuMkI,19
|
9
|
+
llm_dialog_manager-0.4.6.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
llm_dialog_manager/__init__.py,sha256=J7qsuEH4NWFkTQVvCqHgxX1jOYnY79s9BMi02KTo3-A,86
|
2
|
-
llm_dialog_manager/agent.py,sha256=ou9D8NtRt6fDXgrneXP5jZRil7XyKpCTUHCADPJmeeA,25332
|
3
|
-
llm_dialog_manager/chat_history.py,sha256=DKKRnj_M6h-4JncnH6KekMTghX7vMgdN3J9uOwXKzMU,10347
|
4
|
-
llm_dialog_manager/key_manager.py,sha256=shvxmn4zUtQx_p-x1EFyOmnk-WlhigbpKtxTKve-zXk,4421
|
5
|
-
llm_dialog_manager-0.4.4.dist-info/LICENSE,sha256=vWGbYgGuWpWrXL8-xi6pNcX5UzD6pWoIAZmcetyfbus,1064
|
6
|
-
llm_dialog_manager-0.4.4.dist-info/METADATA,sha256=Rjjs7I8JwbQ21QyMxTDrDrwzmAqMcdY30srUOJxYzWs,4194
|
7
|
-
llm_dialog_manager-0.4.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
8
|
-
llm_dialog_manager-0.4.4.dist-info/top_level.txt,sha256=u2EQEXW0NGAt0AAHT7jx1odXZ4rZfjcgbmJhvKFuMkI,19
|
9
|
-
llm_dialog_manager-0.4.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|