aient 1.2.38__tar.gz → 1.2.40__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.
- {aient-1.2.38 → aient-1.2.40}/PKG-INFO +1 -1
- {aient-1.2.38 → aient-1.2.40}/aient/models/chatgpt.py +19 -12
- {aient-1.2.38 → aient-1.2.40}/aient/utils/scripts.py +55 -0
- {aient-1.2.38 → aient-1.2.40}/aient.egg-info/PKG-INFO +1 -1
- {aient-1.2.38 → aient-1.2.40}/pyproject.toml +1 -1
- {aient-1.2.38 → aient-1.2.40}/LICENSE +0 -0
- {aient-1.2.38 → aient-1.2.40}/README.md +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/architext/architext/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/architext/architext/core.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/architext/test/openai_client.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/architext/test/test.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/architext/test/test_save_load.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/log_config.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/models.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/request.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/response.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/test/test_base_api.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/test/test_geminimask.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/test/test_image.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/test/test_payload.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/core/utils.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/models/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/models/audio.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/models/base.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/arXiv.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/config.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/excute_command.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/get_time.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/image.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/list_directory.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/read_file.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/read_image.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/readonly.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/registry.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/run_python.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/websearch.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/plugins/write_file.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/utils/__init__.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient/utils/prompt.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient.egg-info/SOURCES.txt +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient.egg-info/dependency_links.txt +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient.egg-info/requires.txt +0 -0
- {aient-1.2.38 → aient-1.2.40}/aient.egg-info/top_level.txt +0 -0
- {aient-1.2.38 → aient-1.2.40}/setup.cfg +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_Web_crawler.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_ddg_search.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_google_search.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_ollama.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_plugin.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_url.py +0 -0
- {aient-1.2.38 → aient-1.2.40}/test/test_whisper.py +0 -0
@@ -12,7 +12,7 @@ from typing import Union, Optional, Callable
|
|
12
12
|
from .base import BaseLLM
|
13
13
|
from ..plugins.registry import registry
|
14
14
|
from ..plugins import PLUGINS, get_tools_result_async, function_call_list, update_tools_config
|
15
|
-
from ..utils.scripts import safe_get, async_generator_to_sync, parse_function_xml, parse_continuous_json, convert_functions_to_xml, remove_xml_tags_and_content
|
15
|
+
from ..utils.scripts import safe_get, async_generator_to_sync, parse_function_xml, parse_continuous_json, convert_functions_to_xml, remove_xml_tags_and_content, find_most_frequent_phrase
|
16
16
|
from ..core.request import prepare_request_payload
|
17
17
|
from ..core.response import fetch_response_stream, fetch_response
|
18
18
|
from ..architext.architext import Messages, SystemMessage, UserMessage, AssistantMessage, ToolCalls, ToolResults, Texts, RoleMessage, Images, Files
|
@@ -81,6 +81,14 @@ class TaskComplete(Exception):
|
|
81
81
|
super().__init__(f"Task completed with message: {message}")
|
82
82
|
|
83
83
|
|
84
|
+
class RepetitiveResponseError(Exception):
|
85
|
+
"""Custom exception for detecting repetitive and meaningless generated strings."""
|
86
|
+
def __init__(self, message, phrase, count):
|
87
|
+
super().__init__(message)
|
88
|
+
self.phrase = phrase
|
89
|
+
self.count = count
|
90
|
+
|
91
|
+
|
84
92
|
class chatgpt(BaseLLM):
|
85
93
|
"""
|
86
94
|
Official ChatGPT API
|
@@ -438,6 +446,13 @@ class chatgpt(BaseLLM):
|
|
438
446
|
|
439
447
|
if not full_response.strip() and not need_function_call:
|
440
448
|
raise EmptyResponseError("Response is empty")
|
449
|
+
most_frequent_phrase, most_frequent_phrase_count = find_most_frequent_phrase(full_response)
|
450
|
+
if most_frequent_phrase_count > 100:
|
451
|
+
raise RepetitiveResponseError(
|
452
|
+
f"Detected repetitive and meaningless content. The phrase '{most_frequent_phrase}' appeared {most_frequent_phrase_count} times.",
|
453
|
+
most_frequent_phrase,
|
454
|
+
most_frequent_phrase_count
|
455
|
+
)
|
441
456
|
|
442
457
|
if self.print_log:
|
443
458
|
self.logger.info(f"total_tokens: {total_tokens}")
|
@@ -660,17 +675,6 @@ class chatgpt(BaseLLM):
|
|
660
675
|
self.add_to_conversation(full_response, response_role, convo_id=convo_id, total_tokens=total_tokens, pass_history=pass_history)
|
661
676
|
self.function_calls_counter = {}
|
662
677
|
|
663
|
-
# 清理翻译引擎相关的历史记录
|
664
|
-
if pass_history <= 2 and len(self.conversation[convo_id]) >= 2 \
|
665
|
-
and (
|
666
|
-
"You are a translation engine" in self.conversation[convo_id][-2]["content"] \
|
667
|
-
or "You are a translation engine" in safe_get(self.conversation, convo_id, -2, "content", 0, "text", default="") \
|
668
|
-
or "你是一位精通简体中文的专业翻译" in self.conversation[convo_id][-2]["content"] \
|
669
|
-
or "你是一位精通简体中文的专业翻译" in safe_get(self.conversation, convo_id, -2, "content", 0, "text", default="")
|
670
|
-
):
|
671
|
-
self.conversation[convo_id].pop(-1)
|
672
|
-
self.conversation[convo_id].pop(-1)
|
673
|
-
|
674
678
|
async def _ask_stream_handler(
|
675
679
|
self,
|
676
680
|
prompt: list,
|
@@ -811,6 +815,9 @@ class chatgpt(BaseLLM):
|
|
811
815
|
except EmptyResponseError as e:
|
812
816
|
self.logger.warning(f"{e}, retrying...")
|
813
817
|
continue
|
818
|
+
except RepetitiveResponseError as e:
|
819
|
+
self.logger.warning(f"{e}, retrying...")
|
820
|
+
continue
|
814
821
|
except TaskComplete as e:
|
815
822
|
raise
|
816
823
|
except ModelNotFoundError as e:
|
@@ -3,10 +3,65 @@ import re
|
|
3
3
|
import json
|
4
4
|
import fnmatch
|
5
5
|
import requests
|
6
|
+
import collections
|
6
7
|
import urllib.parse
|
7
8
|
|
8
9
|
from ..core.utils import get_image_message
|
9
10
|
|
11
|
+
def find_most_frequent_phrase(s, min_len=4, max_phrase_len=20):
|
12
|
+
"""
|
13
|
+
查找字符串中出现次数最多的短语(单词序列)。
|
14
|
+
此版本经过性能优化,并增加了最大短语长度限制。
|
15
|
+
|
16
|
+
Args:
|
17
|
+
s: 输入字符串。
|
18
|
+
min_len: 短语的最小字符长度。
|
19
|
+
max_phrase_len: 要搜索的最大短语长度(以单词为单位)。
|
20
|
+
|
21
|
+
Returns:
|
22
|
+
一个元组 (most_frequent_phrase, count),其中
|
23
|
+
most_frequent_phrase 是出现次数最多的短语,
|
24
|
+
count 是它的出现次数。
|
25
|
+
如果没有找到符合条件的重复短语,则返回 ("", 0)。
|
26
|
+
"""
|
27
|
+
# start_time = time.time()
|
28
|
+
if not s or len(s) < min_len:
|
29
|
+
return "", 0
|
30
|
+
|
31
|
+
words = [word for word in re.split(r'[\s\n]+', s) if word]
|
32
|
+
if not words:
|
33
|
+
return "", 0
|
34
|
+
n = len(words)
|
35
|
+
|
36
|
+
phrase_counts = collections.defaultdict(int)
|
37
|
+
|
38
|
+
# 确定要检查的实际最大长度
|
39
|
+
effective_max_len = min(n // 2, max_phrase_len)
|
40
|
+
|
41
|
+
# 优化的核心:直接在单词列表上生成并统计所有可能的短语(n-grams)
|
42
|
+
for length in range(1, effective_max_len + 1):
|
43
|
+
for i in range(n - length + 1):
|
44
|
+
phrase_tuple = tuple(words[i:i + length])
|
45
|
+
phrase_counts[phrase_tuple] += 1
|
46
|
+
# 筛选出重复次数大于1且满足最小长度要求的短语
|
47
|
+
best_phrase = ""
|
48
|
+
max_count = 0
|
49
|
+
|
50
|
+
for phrase_tuple, count in phrase_counts.items():
|
51
|
+
if count > 1:
|
52
|
+
phrase = " ".join(phrase_tuple)
|
53
|
+
if len(phrase) >= min_len:
|
54
|
+
if count > max_count:
|
55
|
+
max_count = count
|
56
|
+
best_phrase = phrase
|
57
|
+
elif count == max_count and len(phrase) > len(best_phrase):
|
58
|
+
best_phrase = phrase
|
59
|
+
|
60
|
+
if max_count > 0:
|
61
|
+
return best_phrase, max_count
|
62
|
+
else:
|
63
|
+
return "", 0
|
64
|
+
|
10
65
|
def get_doc_from_url(url):
|
11
66
|
filename = urllib.parse.unquote(url.split("/")[-1])
|
12
67
|
response = requests.get(url, stream=True)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|