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 CHANGED
@@ -41,4 +41,7 @@ def get_llm(
41
41
  if llm is None:
42
42
  raise Exception(f"初始化原始LLM实例失败:{model}")
43
43
 
44
- return LLMWithAutoTokenUsage(llm, langfuse, llmConfig)
44
+ # 获取kwargs中summary_prompt参数
45
+ summary_prompt: str = kwargs.get("summary_prompt")
46
+
47
+ return LLMWithAutoTokenUsage(llm, langfuse, llmConfig, summary_prompt)
@@ -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 = 4
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
 
@@ -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
 
@@ -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, **kwargs)
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
- # 如果连通道都创建不了,说明这个连接也是坏的,回滚到阶段A
213
- logger.error(f"❌ [CHANNEL_FAIL] 通道创建失败,标记连接无效: {e}")
214
- # 强制清理连接,触发下一次进入阶段A
220
+ logger.error(f"❌ [CHANNEL_FAIL] 通道创建失败: {e}")
221
+ # 如果连通道都创建不了,说明连接状态有问题,回滚清理
215
222
  await self._cleanup_resources()
216
223
  raise
217
224
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.1.57b7
3
+ Version: 0.1.57b9
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -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=eZtVx9yNl-VO3O6AhZzCECRTDXRsUTcR88os8hGyJIY,1241
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=s8HQf6ZdqKRAnanAo8yPwAM-Ez4P9gGlhI_zBEffphM,12301
27
- sycommon/llm/sy_langfuse.py,sha256=NZv6ydfn3-cxqQvuB5WdnM9GYliO9qB_RWh_XqIS3VU,3692
28
- sycommon/llm/usage_token.py,sha256=CDoA_UeZKpNvxH0vNZ8f58tfLV3wC4kd5e1Oferyy9s,5318
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=BiFQgZPzSAFR-n5XhyIafoeWQXETF_31nFRDhMbe6aU,15577
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.57b7.dist-info/METADATA,sha256=e43DQ_eU9kbXuhiZpJF4ys1betxau0wepQuOm6v4l1c,7333
86
- sycommon_python_lib-0.1.57b7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
87
- sycommon_python_lib-0.1.57b7.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
88
- sycommon_python_lib-0.1.57b7.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
89
- sycommon_python_lib-0.1.57b7.dist-info/RECORD,,
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,,