sycommon-python-lib 0.1.57b7__py3-none-any.whl → 0.1.57b9__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.
- sycommon/llm/get_llm.py +4 -1
- sycommon/llm/struct_token.py +5 -3
- sycommon/llm/sy_langfuse.py +4 -0
- sycommon/llm/usage_token.py +5 -3
- sycommon/rabbitmq/rabbitmq_pool.py +27 -20
- {sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/METADATA +1 -1
- {sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/RECORD +10 -10
- {sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/top_level.txt +0 -0
sycommon/llm/get_llm.py
CHANGED
|
@@ -41,4 +41,7 @@ def get_llm(
|
|
|
41
41
|
if llm is None:
|
|
42
42
|
raise Exception(f"初始化原始LLM实例失败:{model}")
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
# 获取kwargs中summary_prompt参数
|
|
45
|
+
summary_prompt: str = kwargs.get("summary_prompt")
|
|
46
|
+
|
|
47
|
+
return LLMWithAutoTokenUsage(llm, langfuse, llmConfig, summary_prompt)
|
sycommon/llm/struct_token.py
CHANGED
|
@@ -21,6 +21,7 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
21
21
|
retry_chain: Runnable,
|
|
22
22
|
langfuse: Optional[Langfuse] = None,
|
|
23
23
|
llmConfig: Optional[LLMConfig] = None,
|
|
24
|
+
summary_prompt: Optional[str] = None,
|
|
24
25
|
model_name: str = "Qwen2.5-72B",
|
|
25
26
|
enable_compression: bool = True,
|
|
26
27
|
threshold_ratio: float = 0.8
|
|
@@ -29,6 +30,7 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
29
30
|
self.retry_chain = retry_chain
|
|
30
31
|
self.langfuse = langfuse
|
|
31
32
|
self.llmConfig = llmConfig
|
|
33
|
+
self.summary_prompt = summary_prompt
|
|
32
34
|
self.model_name = model_name
|
|
33
35
|
self.enable_compression = enable_compression
|
|
34
36
|
self.threshold_ratio = threshold_ratio
|
|
@@ -59,7 +61,7 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
59
61
|
async def _acompress_context(self, messages: List[BaseMessage]) -> List[BaseMessage]:
|
|
60
62
|
"""执行异步上下文压缩"""
|
|
61
63
|
# 策略:保留 System Prompt + 最近 N 条,中间的摘要
|
|
62
|
-
keep_last_n =
|
|
64
|
+
keep_last_n = 1
|
|
63
65
|
|
|
64
66
|
# 分离系统消息和对话消息
|
|
65
67
|
system_msgs = [m for m in messages if isinstance(m, SystemMessage)]
|
|
@@ -74,9 +76,9 @@ class StructuredRunnableWithToken(Runnable):
|
|
|
74
76
|
|
|
75
77
|
# 构造摘要 Prompt
|
|
76
78
|
# 注意:这里直接使用 retry_chain 进行摘要,防止死循环
|
|
79
|
+
summary_content = self.summary_prompt or "请将上下文内容进行摘要,保留关键信息,将内容压缩到原来长度的50%左右,保留关键信息。"
|
|
77
80
|
summary_prompt = [
|
|
78
|
-
SystemMessage(
|
|
79
|
-
content="请将上下文内容进行摘要,保留关键信息,将内容压缩到原来长度的50%左右,保留关键信息。"),
|
|
81
|
+
SystemMessage(content=summary_content),
|
|
80
82
|
HumanMessage(content=f"历史记录:\n{to_summarize}\n\n摘要:")
|
|
81
83
|
]
|
|
82
84
|
|
sycommon/llm/sy_langfuse.py
CHANGED
|
@@ -46,6 +46,10 @@ class LangfuseInitializer(metaclass=SingletonMeta):
|
|
|
46
46
|
'baseUrl', '')
|
|
47
47
|
os.environ["LANGFUSE_TRACING_ENVIRONMENT"] = environment
|
|
48
48
|
os.environ["OTEL_SERVICE_NAME"] = server_name
|
|
49
|
+
# 设置 OTLP 追踪导出器超时时间(单位:秒)
|
|
50
|
+
os.environ["OTEL_EXPORTER_OTLP_TRACES_TIMEOUT"] = 60
|
|
51
|
+
# 全局 OTLP 超时(覆盖所有信号:追踪/指标/日志)
|
|
52
|
+
os.environ["OTEL_EXPORTER_OTLP_TIMEOUT"] = 60
|
|
49
53
|
|
|
50
54
|
self._langfuse_client = get_client()
|
|
51
55
|
|
sycommon/llm/usage_token.py
CHANGED
|
@@ -15,9 +15,11 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
15
15
|
llm: BaseChatModel = Field(default=None)
|
|
16
16
|
langfuse: Optional[Langfuse] = Field(default=None, exclude=True)
|
|
17
17
|
llmConfig: Optional[LLMConfig] = Field(default=None, exclude=True)
|
|
18
|
+
summary_prompt: Optional[str] = Field(default=None, exclude=True)
|
|
18
19
|
|
|
19
|
-
def __init__(self, llm: BaseChatModel, langfuse: Langfuse, llmConfig: LLMConfig, **kwargs):
|
|
20
|
-
super().__init__(llm=llm, langfuse=langfuse, llmConfig=llmConfig,
|
|
20
|
+
def __init__(self, llm: BaseChatModel, langfuse: Langfuse, llmConfig: LLMConfig, summary_prompt: str, **kwargs):
|
|
21
|
+
super().__init__(llm=llm, langfuse=langfuse, llmConfig=llmConfig,
|
|
22
|
+
summary_prompt=summary_prompt, **kwargs)
|
|
21
23
|
|
|
22
24
|
def with_structured_output(
|
|
23
25
|
self,
|
|
@@ -108,7 +110,7 @@ class LLMWithAutoTokenUsage(BaseChatModel):
|
|
|
108
110
|
"initial": 0.1, "max": 3.0, "exp_base": 2.0, "jitter": 1.0}
|
|
109
111
|
)
|
|
110
112
|
|
|
111
|
-
return StructuredRunnableWithToken(retry_chain, self.langfuse, self.llmConfig)
|
|
113
|
+
return StructuredRunnableWithToken(retry_chain, self.langfuse, self.llmConfig, self.summary_prompt)
|
|
112
114
|
|
|
113
115
|
# ========== 实现BaseChatModel抽象方法 ==========
|
|
114
116
|
def _generate(self, messages, stop=None, run_manager=None, ** kwargs):
|
|
@@ -142,19 +142,18 @@ class RabbitMQConnectionPool:
|
|
|
142
142
|
async def _ensure_main_channel(self) -> RobustChannel:
|
|
143
143
|
"""
|
|
144
144
|
确保主通道有效
|
|
145
|
-
|
|
146
|
-
1.
|
|
147
|
-
2.
|
|
148
|
-
3.
|
|
145
|
+
修复逻辑:
|
|
146
|
+
1. 如果连接对象不存在或已关闭 -> 重建连接
|
|
147
|
+
2. 如果连接对象存在但处于重连中 -> 等待其 ready
|
|
148
|
+
3. 如果通道不存在或已关闭 -> 重建通道
|
|
149
149
|
"""
|
|
150
150
|
async with self._lock:
|
|
151
151
|
if self._is_shutdown:
|
|
152
152
|
raise RuntimeError("客户端已关闭")
|
|
153
153
|
|
|
154
|
-
# --- 阶段A:连接恢复逻辑
|
|
154
|
+
# --- 阶段A:连接恢复逻辑 ---
|
|
155
155
|
if self._connection is None or self._connection.is_closed:
|
|
156
|
-
|
|
157
|
-
# 1. 【强制】先彻底清理所有旧资源
|
|
156
|
+
# 情况1:连接对象不存在,或已显式关闭 -> 走清理重连流程
|
|
158
157
|
await self._cleanup_resources()
|
|
159
158
|
|
|
160
159
|
retry_hosts = self.hosts.copy()
|
|
@@ -162,7 +161,6 @@ class RabbitMQConnectionPool:
|
|
|
162
161
|
last_error = None
|
|
163
162
|
max_attempts = min(len(retry_hosts), 3)
|
|
164
163
|
|
|
165
|
-
# 2. 轮询尝试新连接
|
|
166
164
|
for _ in range(max_attempts):
|
|
167
165
|
if not retry_hosts:
|
|
168
166
|
break
|
|
@@ -173,19 +171,15 @@ class RabbitMQConnectionPool:
|
|
|
173
171
|
|
|
174
172
|
try:
|
|
175
173
|
temp_conn = await self._create_connection_impl(host)
|
|
176
|
-
|
|
177
|
-
# 3. 只有在连接成功后,才更新 self._connection
|
|
178
174
|
self._connection = temp_conn
|
|
179
|
-
temp_conn = None
|
|
175
|
+
temp_conn = None
|
|
180
176
|
self._initialized = True
|
|
181
177
|
last_error = None
|
|
182
178
|
logger.info(f"🔗 [RECONNECT_OK] 切换到节点: {host}")
|
|
183
179
|
break
|
|
184
|
-
|
|
185
180
|
except Exception as e:
|
|
186
181
|
logger.warning(f"⚠️ [RECONNECT_RETRY] 节点 {host} 不可用")
|
|
187
182
|
if temp_conn is not None:
|
|
188
|
-
# 尝试连接失败了,必须把这个“半成品”连接关掉
|
|
189
183
|
try:
|
|
190
184
|
await temp_conn.close()
|
|
191
185
|
except Exception:
|
|
@@ -193,25 +187,38 @@ class RabbitMQConnectionPool:
|
|
|
193
187
|
last_error = e
|
|
194
188
|
await asyncio.sleep(self.reconnect_interval)
|
|
195
189
|
|
|
196
|
-
# 4. 如果所有尝试都失败
|
|
197
190
|
if last_error:
|
|
198
|
-
# 确保状态是干净的
|
|
199
191
|
self._connection = None
|
|
200
192
|
self._initialized = False
|
|
201
193
|
logger.error("💥 [RECONNECT_FATAL] 所有节点重试失败")
|
|
202
194
|
raise ConnectionError("所有 RabbitMQ 节点连接失败") from last_error
|
|
195
|
+
else:
|
|
196
|
+
# 情况2:连接对象存在,但可能处于“连接丢失,正在重连”的状态
|
|
197
|
+
# 【关键修复】显式调用 connect() 确保连接真正就绪
|
|
198
|
+
# 如果连接已经好,这会立即返回;如果正在重连,这会等待完成
|
|
199
|
+
try:
|
|
200
|
+
logger.debug(f"⏳ [WAIT_CONN] 等待连接就绪...")
|
|
201
|
+
await self._connection.connect(timeout=5) # 设置一个短暂超时避免卡死太久
|
|
202
|
+
logger.debug(f"✅ [WAIT_CONN_OK] 连接已就绪")
|
|
203
|
+
except asyncio.TimeoutError:
|
|
204
|
+
logger.warning("⚠️ [WAIT_CONN_TIMEOUT] 等待连接就绪超时,强制重连")
|
|
205
|
+
await self._cleanup_resources()
|
|
206
|
+
raise
|
|
207
|
+
except Exception as e:
|
|
208
|
+
logger.error(f"❌ [WAIT_CONN_FAIL] 连接不可用: {e}")
|
|
209
|
+
await self._cleanup_resources()
|
|
210
|
+
raise
|
|
203
211
|
|
|
204
|
-
# --- 阶段B:通道恢复逻辑
|
|
205
|
-
# 注意:这里不需要清理连接,只重置通道
|
|
212
|
+
# --- 阶段B:通道恢复逻辑 ---
|
|
206
213
|
if self._channel is None or self._channel.is_closed:
|
|
207
214
|
try:
|
|
215
|
+
# 只有在确保连接有效后,才创建通道
|
|
208
216
|
self._channel = await self._connection.channel()
|
|
209
217
|
await self._channel.set_qos(prefetch_count=self.prefetch_count)
|
|
210
218
|
logger.info(f"✅ [CHANNEL_OK] 主通道已恢复")
|
|
211
219
|
except Exception as e:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
# 强制清理连接,触发下一次进入阶段A
|
|
220
|
+
logger.error(f"❌ [CHANNEL_FAIL] 通道创建失败: {e}")
|
|
221
|
+
# 如果连通道都创建不了,说明连接状态有问题,回滚清理
|
|
215
222
|
await self._cleanup_resources()
|
|
216
223
|
raise
|
|
217
224
|
|
|
@@ -20,12 +20,12 @@ sycommon/health/metrics.py,sha256=fHqO73JuhoZkNPR-xIlxieXiTCvttq-kG-tvxag1s1s,26
|
|
|
20
20
|
sycommon/health/ping.py,sha256=FTlnIKk5y1mPfS1ZGOeT5IM_2udF5aqVLubEtuBp18M,250
|
|
21
21
|
sycommon/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
sycommon/llm/embedding.py,sha256=Qi9mHQiOUVEcZd4elAaqsAyofdeLtPgU_LF35KlIFU4,14735
|
|
23
|
-
sycommon/llm/get_llm.py,sha256=
|
|
23
|
+
sycommon/llm/get_llm.py,sha256=jqwGz8RJRx95XwFl6DsRihQX-6B4Q34RAFeFVOQSlAc,1355
|
|
24
24
|
sycommon/llm/llm_logger.py,sha256=n4UeNy_-g4oHQOsw-VUzF4uo3JVRLtxaMp1FcI8FiEo,5437
|
|
25
25
|
sycommon/llm/llm_tokens.py,sha256=-udDyFcmyzx6UAwIi6_d_wwI5kMd5w0-WcS2soVPQxg,4309
|
|
26
|
-
sycommon/llm/struct_token.py,sha256=
|
|
27
|
-
sycommon/llm/sy_langfuse.py,sha256=
|
|
28
|
-
sycommon/llm/usage_token.py,sha256=
|
|
26
|
+
sycommon/llm/struct_token.py,sha256=ScgfO6CzwwMbqXJhoRN-sD2lbYzX7zGhldrsc4s2X08,12440
|
|
27
|
+
sycommon/llm/sy_langfuse.py,sha256=6diWYBmFExQg-PsP_YZdP5niARtgRXfBR-lcYcITfNc,3983
|
|
28
|
+
sycommon/llm/usage_token.py,sha256=7sFpoGgkBeUt0DguW_ASP2tjAskEzbGn4ZmTGmEYQMo,5486
|
|
29
29
|
sycommon/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
sycommon/logging/async_sql_logger.py,sha256=_OY36XkUm__U3NhMgiecy-qd-nptZ_0gpE3J8lGAr58,2619
|
|
31
31
|
sycommon/logging/kafka_log.py,sha256=gfOqdZe0HJ3PkIFfnNWG4DZVadxsCKJ6AmelR7_Z1Xs,9960
|
|
@@ -52,7 +52,7 @@ sycommon/models/sso_user.py,sha256=i1WAN6k5sPcPApQEdtjpWDy7VrzWLpOrOQewGLGoGIw,2
|
|
|
52
52
|
sycommon/notice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
53
|
sycommon/notice/uvicorn_monitor.py,sha256=VryQYcAtjijJuGDBimbVurgwxlsLaLtkNnABPDY5Tao,7332
|
|
54
54
|
sycommon/rabbitmq/rabbitmq_client.py,sha256=pAhyLfuHl72szLBr-nRqv-QKseT9x_QCR6Mu-IonP1U,16689
|
|
55
|
-
sycommon/rabbitmq/rabbitmq_pool.py,sha256=
|
|
55
|
+
sycommon/rabbitmq/rabbitmq_pool.py,sha256=EzM3j3MCLgoy6VW8tLONtcZB3VmYQI7CWi_X1kOdqF8,16194
|
|
56
56
|
sycommon/rabbitmq/rabbitmq_service.py,sha256=XSHo9HuIJ_lq-vizRh4xJVdZr_2zLqeLhot09qb0euA,2025
|
|
57
57
|
sycommon/rabbitmq/rabbitmq_service_client_manager.py,sha256=IP9TMFeG5LSrwFPEmOy1ce4baPxBUZnWJZR3nN_-XR4,8009
|
|
58
58
|
sycommon/rabbitmq/rabbitmq_service_connection_monitor.py,sha256=uvoMuJDzJ9i63uVRq1NKFV10CvkbGnTMyEoq2rgjQx8,3013
|
|
@@ -82,8 +82,8 @@ sycommon/tools/env.py,sha256=Ah-tBwG2C0_hwLGFebVQgKdWWXCjTzBuF23gCkLHYy4,2437
|
|
|
82
82
|
sycommon/tools/merge_headers.py,sha256=u9u8_1ZIuGIminWsw45YJ5qnsx9MB-Fot0VPge7itPw,4941
|
|
83
83
|
sycommon/tools/snowflake.py,sha256=xQlYXwYnI85kSJ1rZ89gMVBhzemP03xrMPVX9vVa3MY,9228
|
|
84
84
|
sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
|
|
85
|
-
sycommon_python_lib-0.1.
|
|
86
|
-
sycommon_python_lib-0.1.
|
|
87
|
-
sycommon_python_lib-0.1.
|
|
88
|
-
sycommon_python_lib-0.1.
|
|
89
|
-
sycommon_python_lib-0.1.
|
|
85
|
+
sycommon_python_lib-0.1.57b9.dist-info/METADATA,sha256=NcmwXbyj9wboWXHTZ4B4ZGLRTuz_JwcvcohTThAg1N0,7333
|
|
86
|
+
sycommon_python_lib-0.1.57b9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
87
|
+
sycommon_python_lib-0.1.57b9.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
|
|
88
|
+
sycommon_python_lib-0.1.57b9.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
|
|
89
|
+
sycommon_python_lib-0.1.57b9.dist-info/RECORD,,
|
|
File without changes
|
{sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{sycommon_python_lib-0.1.57b7.dist-info → sycommon_python_lib-0.1.57b9.dist-info}/top_level.txt
RENAMED
|
File without changes
|