llm-dialog-manager 0.3.5__tar.gz → 0.4.2__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.
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/PKG-INFO +2 -1
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/README.md +1 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager/__init__.py +1 -1
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager/agent.py +68 -32
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/PKG-INFO +2 -1
- llm_dialog_manager-0.4.2/pyproject.toml +32 -0
- llm_dialog_manager-0.3.5/pyproject.toml +0 -64
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/LICENSE +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager/chat_history.py +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager/key_manager.py +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/SOURCES.txt +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/dependency_links.txt +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/requires.txt +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/top_level.txt +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/setup.cfg +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/tests/test_agent.py +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/tests/test_chat_history.py +0 -0
- {llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/tests/test_key_manager.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: llm_dialog_manager
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.2
|
4
4
|
Summary: A Python package for managing LLM chat conversation history
|
5
5
|
Author-email: xihajun <work@2333.fun>
|
6
6
|
License: MIT
|
@@ -64,6 +64,7 @@ A Python package for managing AI chat conversation history with support for mult
|
|
64
64
|
- Memory management options
|
65
65
|
- Conversation search and indexing
|
66
66
|
- Rich conversation display options
|
67
|
+
- Vision & Json Output enabled [20240111]
|
67
68
|
|
68
69
|
## Installation
|
69
70
|
|
@@ -38,15 +38,46 @@ def load_env_vars():
|
|
38
38
|
|
39
39
|
load_env_vars()
|
40
40
|
|
41
|
+
def format_messages_for_gemini(messages):
|
42
|
+
"""
|
43
|
+
将标准化的消息格式转化为 Gemini 格式。
|
44
|
+
system 消息应该通过 GenerativeModel 的 system_instruction 参数传入,
|
45
|
+
不在这个函数处理。
|
46
|
+
"""
|
47
|
+
gemini_messages = []
|
48
|
+
|
49
|
+
for msg in messages:
|
50
|
+
role = msg["role"]
|
51
|
+
content = msg["content"]
|
52
|
+
|
53
|
+
# 跳过 system 消息,因为它会通过 system_instruction 设置
|
54
|
+
if role == "system":
|
55
|
+
continue
|
56
|
+
|
57
|
+
# 处理 user/assistant 消息
|
58
|
+
# 如果 content 是单一对象,转换为列表
|
59
|
+
if not isinstance(content, list):
|
60
|
+
content = [content]
|
61
|
+
|
62
|
+
gemini_messages.append({
|
63
|
+
"role": role,
|
64
|
+
"parts": content # content 可以包含文本和 FileMedia
|
65
|
+
})
|
66
|
+
|
67
|
+
return gemini_messages
|
68
|
+
|
41
69
|
def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, Image.Image, Dict]]]]], max_tokens: int = 1000,
|
42
|
-
temperature: float = 0.5, api_key: Optional[str] = None,
|
70
|
+
temperature: float = 0.5, top_p: float = 1.0, top_k: int = 40, api_key: Optional[str] = None,
|
43
71
|
base_url: Optional[str] = None, json_format: bool = False) -> str:
|
44
72
|
"""
|
45
73
|
Generate a completion using the specified model and messages.
|
46
74
|
"""
|
47
75
|
try:
|
48
76
|
service = ""
|
49
|
-
if "
|
77
|
+
if "openai" in model:
|
78
|
+
service = "openai"
|
79
|
+
model
|
80
|
+
elif "claude" in model:
|
50
81
|
service = "anthropic"
|
51
82
|
elif "gemini" in model:
|
52
83
|
service = "gemini"
|
@@ -64,7 +95,7 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
64
95
|
|
65
96
|
def format_messages_for_api(model, messages):
|
66
97
|
"""Convert ChatHistory messages to the format required by the specific API."""
|
67
|
-
if "claude" in model:
|
98
|
+
if "claude" in model and "openai" not in model:
|
68
99
|
formatted = []
|
69
100
|
system_msg = ""
|
70
101
|
if messages and messages[0]["role"] == "system":
|
@@ -113,7 +144,7 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
113
144
|
formatted.append({"role": msg["role"], "content": combined_content})
|
114
145
|
return system_msg, formatted
|
115
146
|
|
116
|
-
elif "gemini" in model or "gpt" in model or "grok" in model:
|
147
|
+
elif ("gemini" in model or "gpt" in model or "grok" in model) and "openai" not in model:
|
117
148
|
formatted = []
|
118
149
|
for msg in messages:
|
119
150
|
content = msg["content"]
|
@@ -163,7 +194,7 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
163
194
|
|
164
195
|
system_msg, formatted_messages = format_messages_for_api(model, messages.copy())
|
165
196
|
|
166
|
-
if "claude" in model:
|
197
|
+
if "claude" in model and "openai" not in model:
|
167
198
|
# Check for Vertex configuration
|
168
199
|
vertex_project_id = os.getenv('VERTEX_PROJECT_ID')
|
169
200
|
vertex_region = os.getenv('VERTEX_REGION')
|
@@ -204,7 +235,7 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
204
235
|
|
205
236
|
return response.completion
|
206
237
|
|
207
|
-
elif "gemini" in model:
|
238
|
+
elif "gemini" in model and "openai" not in model:
|
208
239
|
try:
|
209
240
|
# First try OpenAI-style API
|
210
241
|
client = openai.OpenAI(
|
@@ -216,6 +247,9 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
216
247
|
|
217
248
|
response = client.chat.completions.create(
|
218
249
|
model=model,
|
250
|
+
max_tokens=max_tokens,
|
251
|
+
top_p=top_p,
|
252
|
+
top_k=top_k,
|
219
253
|
messages=formatted_messages,
|
220
254
|
temperature=temperature,
|
221
255
|
response_format=response_format # Added response_format
|
@@ -226,36 +260,34 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
226
260
|
# If OpenAI-style API fails, fall back to Google's genai library
|
227
261
|
logger.info("Falling back to Google's genai library")
|
228
262
|
genai.configure(api_key=api_key)
|
229
|
-
|
230
|
-
# Convert messages to Gemini format
|
231
|
-
gemini_messages = []
|
263
|
+
system_instruction = ""
|
232
264
|
for msg in messages:
|
233
265
|
if msg["role"] == "system":
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
else:
|
240
|
-
gemini_messages.append({"role": msg["role"], "parts": msg["content"]})
|
241
|
-
|
242
|
-
# Set response_mime_type based on json_format
|
266
|
+
system_instruction = msg["content"]
|
267
|
+
break
|
268
|
+
|
269
|
+
# 将其他消息转换为 gemini 格式
|
270
|
+
gemini_messages = format_messages_for_gemini(messages)
|
243
271
|
mime_type = "application/json" if json_format else "text/plain"
|
272
|
+
generation_config = genai.types.GenerationConfig(
|
273
|
+
temperature=temperature,
|
274
|
+
top_p=top_p,
|
275
|
+
top_k=top_k,
|
276
|
+
max_output_tokens=max_tokens,
|
277
|
+
response_mime_type=mime_type
|
278
|
+
)
|
244
279
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
generation_config=genai.types.GenerationConfig(
|
250
|
-
temperature=temperature,
|
251
|
-
response_mime_type=mime_type, # Modified based on json_format
|
252
|
-
max_output_tokens=max_tokens
|
253
|
-
)
|
280
|
+
model_instance = genai.GenerativeModel(
|
281
|
+
model_name=model,
|
282
|
+
system_instruction=system_instruction, # system 消息通过这里传入
|
283
|
+
generation_config=generation_config
|
254
284
|
)
|
255
285
|
|
286
|
+
response = model_instance.generate_content(gemini_messages, generation_config=generation_config)
|
287
|
+
|
256
288
|
return response.text
|
257
289
|
|
258
|
-
elif "grok" in model:
|
290
|
+
elif "grok" in model and "openai" not in model:
|
259
291
|
# Randomly choose between OpenAI and Anthropic SDK
|
260
292
|
use_anthropic = random.choice([True, False])
|
261
293
|
|
@@ -297,6 +329,8 @@ def completion(model: str, messages: List[Dict[str, Union[str, List[Union[str, I
|
|
297
329
|
return response.choices[0].message.content
|
298
330
|
|
299
331
|
else: # OpenAI models
|
332
|
+
if model.endswith("-openai"):
|
333
|
+
model = model[:-7] # Remove last 7 characters ("-openai")
|
300
334
|
client = openai.OpenAI(api_key=api_key, base_url=base_url)
|
301
335
|
# Set response_format based on json_format
|
302
336
|
response_format = {"type": "json_object"} if json_format else {"type": "plain_text"}
|
@@ -395,7 +429,7 @@ class Agent:
|
|
395
429
|
# Start a new user message with the image
|
396
430
|
self.history.add_message([image_block], "user")
|
397
431
|
|
398
|
-
def generate_response(self, max_tokens=3585, temperature=0.7, json_format: bool = False) -> str:
|
432
|
+
def generate_response(self, max_tokens=3585, temperature=0.7, top_p=1.0, top_k=40, json_format: bool = False) -> str:
|
399
433
|
"""Generate a response from the agent.
|
400
434
|
|
401
435
|
Args:
|
@@ -410,12 +444,14 @@ class Agent:
|
|
410
444
|
raise ValueError("No messages in history to generate response from")
|
411
445
|
|
412
446
|
messages = self.history.messages
|
413
|
-
|
447
|
+
print(self.model_name)
|
414
448
|
response_text = completion(
|
415
449
|
model=self.model_name,
|
416
450
|
messages=messages,
|
417
451
|
max_tokens=max_tokens,
|
418
452
|
temperature=temperature,
|
453
|
+
top_p=top_p,
|
454
|
+
top_k=top_k,
|
419
455
|
api_key=self.api_key,
|
420
456
|
json_format=json_format # Pass json_format to completion
|
421
457
|
)
|
@@ -486,13 +522,13 @@ class Agent:
|
|
486
522
|
if __name__ == "__main__":
|
487
523
|
# Example Usage
|
488
524
|
# Create an Agent instance (Gemini model)
|
489
|
-
agent = Agent("gemini-1.5-flash", "you are
|
525
|
+
agent = Agent("gemini-1.5-flash", "you are Jack101", memory_enabled=True)
|
490
526
|
|
491
527
|
# Add an image
|
492
528
|
agent.add_image(image_path="/Users/junfan/Projects/Personal/oneapi/dialog_manager/example.png")
|
493
529
|
|
494
530
|
# Add a user message
|
495
|
-
agent.add_message("user", "What's in this image?")
|
531
|
+
agent.add_message("user", "Who are you? What's in this image?")
|
496
532
|
|
497
533
|
# Generate response with JSON format enabled
|
498
534
|
try:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: llm_dialog_manager
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.2
|
4
4
|
Summary: A Python package for managing LLM chat conversation history
|
5
5
|
Author-email: xihajun <work@2333.fun>
|
6
6
|
License: MIT
|
@@ -64,6 +64,7 @@ A Python package for managing AI chat conversation history with support for mult
|
|
64
64
|
- Memory management options
|
65
65
|
- Conversation search and indexing
|
66
66
|
- Rich conversation display options
|
67
|
+
- Vision & Json Output enabled [20240111]
|
67
68
|
|
68
69
|
## Installation
|
69
70
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = [ "setuptools>=61.0", "wheel",]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "llm_dialog_manager"
|
7
|
+
version = "0.4.2"
|
8
|
+
description = "A Python package for managing LLM chat conversation history"
|
9
|
+
readme = "README.md"
|
10
|
+
classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Scientific/Engineering :: Artificial Intelligence",]
|
11
|
+
requires-python = ">=3.7"
|
12
|
+
dependencies = [ "openai>=1.54.2", "anthropic>=0.39.0", "google-generativeai>=0.1.0", "python-dotenv>=1.0.0", "typing-extensions>=4.0.0", "uuid>=1.30",]
|
13
|
+
[[project.authors]]
|
14
|
+
name = "xihajun"
|
15
|
+
email = "work@2333.fun"
|
16
|
+
|
17
|
+
[project.license]
|
18
|
+
text = "MIT"
|
19
|
+
|
20
|
+
[project.optional-dependencies]
|
21
|
+
dev = [ "pytest>=8.0.0", "pytest-asyncio>=0.21.1", "pytest-cov>=4.1.0", "black>=23.9.1", "isort>=5.12.0",]
|
22
|
+
test = [ "pytest>=6.0", "pytest-asyncio>=0.14.0", "pytest-cov>=2.0",]
|
23
|
+
lint = [ "black>=22.0", "isort>=5.0",]
|
24
|
+
all = [ "pytest>=8.0.0", "pytest-asyncio>=0.21.1", "pytest-cov>=4.1.0", "black>=23.9.1", "isort>=5.12.0",]
|
25
|
+
|
26
|
+
[project.urls]
|
27
|
+
"Bug Tracker" = "https://github.com/xihajun/llm_dialog_manager/issues"
|
28
|
+
Documentation = "https://github.com/xihajun/llm_dialog_manager#readme"
|
29
|
+
"Source Code" = "https://github.com/xihajun/llm_dialog_manager"
|
30
|
+
|
31
|
+
[tool.setuptools]
|
32
|
+
packages = [ "llm_dialog_manager",]
|
@@ -1,64 +0,0 @@
|
|
1
|
-
[build-system]
|
2
|
-
requires = ["setuptools>=61.0", "wheel"]
|
3
|
-
build-backend = "setuptools.build_meta"
|
4
|
-
|
5
|
-
[project]
|
6
|
-
name = "llm_dialog_manager"
|
7
|
-
version = "0.3.5"
|
8
|
-
description = "A Python package for managing LLM chat conversation history"
|
9
|
-
readme = "README.md"
|
10
|
-
authors = [{ name = "xihajun", email = "work@2333.fun" }]
|
11
|
-
license = { text = "MIT" }
|
12
|
-
classifiers = [
|
13
|
-
"Development Status :: 3 - Alpha",
|
14
|
-
"Intended Audience :: Developers",
|
15
|
-
"License :: OSI Approved :: MIT License",
|
16
|
-
"Operating System :: OS Independent",
|
17
|
-
"Programming Language :: Python :: 3.8",
|
18
|
-
"Programming Language :: Python :: 3.9",
|
19
|
-
"Programming Language :: Python :: 3.10",
|
20
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
21
|
-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
22
|
-
]
|
23
|
-
requires-python = ">=3.7"
|
24
|
-
dependencies = [
|
25
|
-
"openai>=1.54.2",
|
26
|
-
"anthropic>=0.39.0",
|
27
|
-
"google-generativeai>=0.1.0",
|
28
|
-
"python-dotenv>=1.0.0",
|
29
|
-
"typing-extensions>=4.0.0",
|
30
|
-
"uuid>=1.30",
|
31
|
-
]
|
32
|
-
|
33
|
-
[project.optional-dependencies]
|
34
|
-
dev = [
|
35
|
-
"pytest>=8.0.0",
|
36
|
-
"pytest-asyncio>=0.21.1",
|
37
|
-
"pytest-cov>=4.1.0",
|
38
|
-
"black>=23.9.1",
|
39
|
-
"isort>=5.12.0",
|
40
|
-
]
|
41
|
-
test = [
|
42
|
-
"pytest>=6.0",
|
43
|
-
"pytest-asyncio>=0.14.0",
|
44
|
-
"pytest-cov>=2.0",
|
45
|
-
]
|
46
|
-
lint = [
|
47
|
-
"black>=22.0",
|
48
|
-
"isort>=5.0",
|
49
|
-
]
|
50
|
-
all = [
|
51
|
-
"pytest>=8.0.0",
|
52
|
-
"pytest-asyncio>=0.21.1",
|
53
|
-
"pytest-cov>=4.1.0",
|
54
|
-
"black>=23.9.1",
|
55
|
-
"isort>=5.12.0",
|
56
|
-
]
|
57
|
-
|
58
|
-
[project.urls]
|
59
|
-
"Bug Tracker" = "https://github.com/xihajun/llm_dialog_manager/issues"
|
60
|
-
"Documentation" = "https://github.com/xihajun/llm_dialog_manager#readme"
|
61
|
-
"Source Code" = "https://github.com/xihajun/llm_dialog_manager"
|
62
|
-
|
63
|
-
[tool.setuptools]
|
64
|
-
packages = ["llm_dialog_manager"]
|
File without changes
|
File without changes
|
File without changes
|
{llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/SOURCES.txt
RENAMED
File without changes
|
File without changes
|
{llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/requires.txt
RENAMED
File without changes
|
{llm_dialog_manager-0.3.5 → llm_dialog_manager-0.4.2}/llm_dialog_manager.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|