gohumanloop 0.0.5__py3-none-any.whl → 0.0.7__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.
@@ -1,4 +1,5 @@
1
- from typing import Dict, Any, Optional, List, Union
1
+ from typing import Dict, Any, Optional, List, Type
2
+ from types import TracebackType
2
3
  import os
3
4
  import asyncio
4
5
  import aiohttp
@@ -8,21 +9,27 @@ from datetime import datetime
8
9
 
9
10
  from gohumanloop.core.manager import DefaultHumanLoopManager
10
11
  from gohumanloop.providers.ghl_provider import GoHumanLoopProvider
11
- from gohumanloop.core.interface import HumanLoopProvider, HumanLoopStatus, HumanLoopType, HumanLoopResult
12
+ from gohumanloop.core.interface import (
13
+ HumanLoopProvider,
14
+ HumanLoopStatus,
15
+ HumanLoopResult,
16
+ )
12
17
  from gohumanloop.utils import get_secret_from_env
13
18
  from gohumanloop.models.glh_model import GoHumanLoopConfig
14
19
 
20
+
15
21
  class GoHumanLoopManager(DefaultHumanLoopManager):
16
22
  """
17
23
  GoHumanLoop 官方平台的人机交互管理器
18
-
24
+
19
25
  这个管理器专门使用 GoHumanLoopProvider 作为提供者,用于将交互过程数据传输到 GoHumanLoop 平台。
20
26
  它是 DefaultHumanLoopManager 的一个特殊实现,简化了与 GoHumanLoop 平台的集成。
21
-
27
+
22
28
  主要职责:
23
29
  1. 管理整个人机交互任务
24
30
  2. 将交互任务数据统一传输到 GoHumanLoop 平台
25
31
  """
32
+
26
33
  def __init__(
27
34
  self,
28
35
  request_timeout: int = 60,
@@ -30,12 +37,12 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
30
37
  max_retries: int = 3,
31
38
  sync_interval: int = 60, # 数据同步间隔(秒)
32
39
  additional_providers: Optional[List[HumanLoopProvider]] = None,
33
- auto_start_sync: bool = True, # 是否自动启动数据同步任务
40
+ auto_start_sync: bool = True, # 是否自动启动数据同步任务
34
41
  config: Optional[Dict[str, Any]] = None,
35
42
  ):
36
43
  """
37
44
  初始化 GoHumanLoop 管理器
38
-
45
+
39
46
  Args:
40
47
  request_timeout: API 请求超时时间(秒),默认60秒
41
48
  poll_interval: 轮询检查请求状态的时间间隔(秒),默认5秒
@@ -45,18 +52,20 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
45
52
  auto_start_sync: 是否在初始化时自动启动数据同步任务,默认为True
46
53
  config: 附加配置参数字典,可选
47
54
  """
48
- # Get API key from environment variables (if not provided)
55
+ # Get API key from environment variables (if not provided)
49
56
  api_key = get_secret_from_env("GOHUMANLOOP_API_KEY")
50
-
57
+
58
+ if api_key is None:
59
+ raise ValueError("GOHUMANLOOP_API_KEY environment variable is not set!")
60
+
51
61
  # Get API base URL from environment variables (if not provided)
52
- api_base_url = os.environ.get("GOHUMANLOOP_API_BASE_URL", "https://www.gohumanloop.com")
53
-
54
- # Validate configuration using pydantic model
55
- self.ghl_config = GoHumanLoopConfig(
56
- api_key=api_key,
57
- api_base_url=api_base_url
62
+ api_base_url = os.environ.get(
63
+ "GOHUMANLOOP_API_BASE_URL", "https://www.gohumanloop.com"
58
64
  )
59
-
65
+
66
+ # Validate configuration using pydantic model
67
+ self.ghl_config = GoHumanLoopConfig(api_key=api_key, api_base_url=api_base_url)
68
+
60
69
  self.name = "GoHumanLoop"
61
70
  # 创建 GoHumanLoop 提供者
62
71
  ghl_provider = GoHumanLoopProvider(
@@ -64,36 +73,38 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
64
73
  request_timeout=request_timeout,
65
74
  poll_interval=poll_interval,
66
75
  max_retries=max_retries,
67
- config=config
76
+ config=config,
68
77
  )
69
-
78
+
70
79
  # 初始化提供者列表
71
- providers = [ghl_provider]
80
+ providers: List[HumanLoopProvider] = [ghl_provider]
72
81
  if additional_providers:
73
82
  providers.extend(additional_providers)
74
-
83
+
75
84
  # 调用父类初始化方法
76
85
  super().__init__(initial_providers=providers)
77
-
86
+
78
87
  # 设置 GoHumanLoop 提供者为默认提供者
79
88
  self.default_provider_id = self.name
80
-
89
+
81
90
  # 存储最近同步时间
82
91
  self._last_sync_time = time.time()
83
-
92
+
84
93
  # 同步间隔
85
94
  self.sync_interval = sync_interval
86
-
95
+
87
96
  # 存储已取消的请求和对话信息
88
- self._cancelled_conversations = {} # conversation_id -> 取消信息
89
-
90
- # 同步任务引用
91
- self._sync_task = None
92
-
97
+ self._cancelled_conversations: Dict[
98
+ str, Dict[str, Any]
99
+ ] = {} # conversation_id -> 取消信息
100
+
101
+ # 数据同步任务引用
102
+ self._sync_task: asyncio.Task[None] | None = None
103
+
93
104
  # 同步模式相关属性
94
- self._sync_thread = None
105
+ self._sync_thread: threading.Thread | None = None
95
106
  self._sync_thread_stop_event = threading.Event()
96
-
107
+
97
108
  # 启动数据同步任务
98
109
  if auto_start_sync:
99
110
  # 判断是否处在异步环境
@@ -102,23 +113,24 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
102
113
  else:
103
114
  self.start_sync_task()
104
115
 
105
-
106
116
  async def async_get_ghl_provider(self) -> GoHumanLoopProvider:
107
117
  """
108
118
  获取 GoHumanLoop 提供者实例
109
-
119
+
110
120
  Returns:
111
121
  GoHumanLoopProvider: GoHumanLoop 提供者实例
112
122
  """
113
123
  provider = await self.async_get_provider(self.default_provider_id)
124
+ # 添加类型转换确保返回正确类型
125
+ assert isinstance(provider, GoHumanLoopProvider)
114
126
  return provider
115
-
116
- async def async_start_sync_task(self):
127
+
128
+ async def async_start_sync_task(self) -> None:
117
129
  """启动数据同步任务"""
118
130
  if self._sync_task is None or self._sync_task.done():
119
131
  self._sync_task = asyncio.create_task(self._async_data_periodically())
120
-
121
- async def _async_data_periodically(self):
132
+
133
+ async def _async_data_periodically(self) -> None:
122
134
  """定期同步数据到 GoHumanLoop 平台"""
123
135
  while True:
124
136
  try:
@@ -134,18 +146,17 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
134
146
  except Exception as e:
135
147
  print(f"最终数据同步错误: {str(e)}")
136
148
  raise # 重新抛出取消异常
137
-
138
- def start_sync_task(self):
149
+
150
+ def start_sync_task(self) -> None:
139
151
  """启动同步版本的数据同步任务"""
140
152
  if self._sync_thread is None or not self._sync_thread.is_alive():
141
153
  self._sync_thread_stop_event.clear()
142
154
  self._sync_thread = threading.Thread(
143
- target=self._sync_data_periodically,
144
- daemon=True
155
+ target=self._sync_data_periodically, daemon=True
145
156
  )
146
157
  self._sync_thread.start()
147
-
148
- def _sync_data_periodically(self):
158
+
159
+ def _sync_data_periodically(self) -> None:
149
160
  """同步版本:定期同步数据到 GoHumanLoop 平台"""
150
161
  while not self._sync_thread_stop_event.is_set():
151
162
  try:
@@ -155,207 +166,227 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
155
166
  except Exception as e:
156
167
  # 记录错误但不中断同步循环
157
168
  print(f"同步数据同步错误: {str(e)}")
158
-
169
+
159
170
  # 线程结束前执行最后一次同步
160
171
  try:
161
172
  self.sync_data_to_platform()
162
173
  except Exception as e:
163
174
  print(f"最终同步数据同步错误: {str(e)}")
164
-
165
- async def async_data_to_platform(self):
175
+
176
+ async def async_data_to_platform(self) -> None:
166
177
  """
167
178
  同步数据到 GoHumanLoop 平台
168
-
179
+
169
180
  此方法收集所有任务的数据,并通过 API 发送到 GoHumanLoop 平台
170
181
  """
171
182
  current_time = time.time()
172
-
183
+
173
184
  # 获取所有任务ID
174
185
  task_ids = list(self._task_conversations.keys())
175
-
186
+
176
187
  # 对每个任务进行数据同步
177
188
  for task_id in task_ids:
178
189
  # 获取任务相关的所有对话
179
190
  conversations = await self.async_get_task_conversations(task_id)
180
-
191
+
181
192
  # 收集任务数据
182
- task_data = {
193
+ task_data: Dict[str, Any] = {
183
194
  "task_id": task_id,
184
195
  "conversations": [],
185
- "timestamp": datetime.now().isoformat()
196
+ "timestamp": datetime.now().isoformat(),
186
197
  }
187
-
198
+
188
199
  # 收集每个对话的数据
189
200
  for conversation_id in conversations:
190
201
  # 获取对话中的所有请求
191
- request_ids = await self.async_get_conversation_requests(conversation_id)
192
-
193
- conversation_data = {
202
+ request_ids = await self.async_get_conversation_requests(
203
+ conversation_id
204
+ )
205
+
206
+ conversation_data: Dict[str, Any] = {
194
207
  "conversation_id": conversation_id,
195
208
  "provider_id": self._conversation_provider.get(conversation_id),
196
- "requests": []
209
+ "requests": [],
197
210
  }
198
-
211
+
199
212
  # 收集每个请求的数据
200
213
  for request_id in request_ids:
201
- result = await self._async_get_request_status(conversation_id, request_id)
202
-
214
+ result = await self._async_get_request_status(
215
+ conversation_id, request_id
216
+ )
217
+
203
218
  # 添加请求数据
204
- conversation_data["requests"].append({
205
- "request_id": request_id,
206
- "status": result.status.value,
207
- "loop_type": result.loop_type.value,
208
- "response": result.response,
209
- "feedback": result.feedback,
210
- "responded_by": result.responded_by,
211
- "responded_at": result.responded_at,
212
- "error": result.error
213
- })
214
-
219
+ conversation_data["requests"].append(
220
+ {
221
+ "request_id": request_id,
222
+ "status": result.status.value,
223
+ "loop_type": result.loop_type.value,
224
+ "response": result.response,
225
+ "feedback": result.feedback,
226
+ "responded_by": result.responded_by,
227
+ "responded_at": result.responded_at,
228
+ "error": result.error,
229
+ }
230
+ )
231
+
215
232
  # 添加对话数据
216
233
  task_data["conversations"].append(conversation_data)
217
-
234
+
218
235
  # 检查是否有已取消的对话需要添加
219
236
  for conv_id, cancel_info in self._cancelled_conversations.items():
220
237
  if conv_id not in conversations:
221
238
  # 创建已取消对话的数据
222
- cancelled_conv_data = {
239
+ cancelled_conv_data: Dict[str, Any] = {
223
240
  "conversation_id": conv_id,
224
241
  "provider_id": cancel_info.get("provider_id"),
225
- "requests": []
242
+ "requests": [],
226
243
  }
227
-
244
+
228
245
  # 添加此对话中的已取消请求
229
246
  for request_id in cancel_info.get("request_ids", []):
230
- result = await self._async_get_request_status(conv_id, request_id, cancel_info.get("provider_id"))
231
-
247
+ result = await self._async_get_request_status(
248
+ conv_id, request_id, cancel_info.get("provider_id")
249
+ )
250
+
232
251
  # 添加请求数据
233
- cancelled_conv_data["requests"].append({
234
- "request_id": request_id,
235
- "status": result.status.value,
236
- "loop_type": result.loop_type.value,
237
- "response": result.response,
238
- "feedback": result.feedback,
239
- "responded_by": result.responded_by,
240
- "responded_at": result.responded_at,
241
- "error": result.error
242
- })
243
-
252
+ cancelled_conv_data["requests"].append(
253
+ {
254
+ "request_id": request_id,
255
+ "status": result.status.value,
256
+ "loop_type": result.loop_type.value,
257
+ "response": result.response,
258
+ "feedback": result.feedback,
259
+ "responded_by": result.responded_by,
260
+ "responded_at": result.responded_at,
261
+ "error": result.error,
262
+ }
263
+ )
264
+
244
265
  # 添加已取消的对话
245
266
  task_data["conversations"].append(cancelled_conv_data)
246
-
267
+
247
268
  # 发送数据到平台
248
269
  await self._async_send_task_data_to_platform(task_data)
249
-
270
+
250
271
  # 更新最后同步时间
251
272
  self._last_sync_time = current_time
252
-
253
- def sync_data_to_platform(self):
273
+
274
+ def sync_data_to_platform(self) -> None:
254
275
  """
255
276
  同步版本:同步数据到 GoHumanLoop 平台
256
-
277
+
257
278
  此方法收集所有任务的数据,并通过 API 发送到 GoHumanLoop 平台
258
279
  """
259
280
  current_time = time.time()
260
-
281
+
261
282
  # 获取所有任务ID
262
283
  task_ids = list(self._task_conversations.keys())
263
-
284
+
264
285
  # 对每个任务进行数据同步
265
286
  for task_id in task_ids:
266
287
  # 获取任务相关的所有对话
267
288
  # 使用同步方式运行异步方法
268
289
  loop = asyncio.new_event_loop()
269
290
  conversations = self.get_task_conversations(task_id)
270
-
291
+
271
292
  # 收集任务数据
272
- task_data = {
293
+ task_data: Dict[str, Any] = {
273
294
  "task_id": task_id,
274
295
  "conversations": [],
275
- "timestamp": datetime.now().isoformat()
296
+ "timestamp": datetime.now().isoformat(),
276
297
  }
277
-
298
+
278
299
  # 收集每个对话的数据
279
300
  for conversation_id in conversations:
280
301
  # 获取对话中的所有请求
281
302
  request_ids = self.get_conversation_requests(conversation_id)
282
-
283
- conversation_data = {
303
+
304
+ conversation_data: Dict[str, Any] = {
284
305
  "conversation_id": conversation_id,
285
306
  "provider_id": self._conversation_provider.get(conversation_id),
286
- "requests": []
307
+ "requests": [],
287
308
  }
288
-
309
+
289
310
  # 收集每个请求的数据
290
311
  for request_id in request_ids:
291
- result = loop.run_until_complete(self._async_get_request_status(conversation_id, request_id))
292
-
312
+ result = loop.run_until_complete(
313
+ self._async_get_request_status(conversation_id, request_id)
314
+ )
315
+
293
316
  # 添加请求数据
294
- conversation_data["requests"].append({
295
- "request_id": request_id,
296
- "status": result.status.value,
297
- "loop_type": result.loop_type.value,
298
- "response": result.response,
299
- "feedback": result.feedback,
300
- "responded_by": result.responded_by,
301
- "responded_at": result.responded_at,
302
- "error": result.error
303
- })
304
-
317
+ conversation_data["requests"].append(
318
+ {
319
+ "request_id": request_id,
320
+ "status": result.status.value,
321
+ "loop_type": result.loop_type.value,
322
+ "response": result.response,
323
+ "feedback": result.feedback,
324
+ "responded_by": result.responded_by,
325
+ "responded_at": result.responded_at,
326
+ "error": result.error,
327
+ }
328
+ )
329
+
305
330
  # 添加对话数据
306
331
  task_data["conversations"].append(conversation_data)
307
-
332
+
308
333
  # 检查是否有已取消的对话需要添加
309
334
  for conv_id, cancel_info in self._cancelled_conversations.items():
310
335
  if conv_id not in conversations:
311
336
  # 创建已取消对话的数据
312
- cancelled_conv_data = {
337
+ cancelled_conv_data: Dict[str, Any] = {
313
338
  "conversation_id": conv_id,
314
339
  "provider_id": cancel_info.get("provider_id"),
315
- "requests": []
340
+ "requests": [],
316
341
  }
317
-
342
+
318
343
  # 添加此对话中的已取消请求
319
344
  for request_id in cancel_info.get("request_ids", []):
320
345
  result = loop.run_until_complete(
321
- self._async_get_request_status(conv_id, request_id, cancel_info.get("provider_id"))
346
+ self._async_get_request_status(
347
+ conv_id, request_id, cancel_info.get("provider_id")
348
+ )
322
349
  )
323
-
350
+
324
351
  # 添加请求数据
325
- cancelled_conv_data["requests"].append({
326
- "request_id": request_id,
327
- "status": result.status.value,
328
- "loop_type": result.loop_type.value,
329
- "response": result.response,
330
- "feedback": result.feedback,
331
- "responded_by": result.responded_by,
332
- "responded_at": result.responded_at,
333
- "error": result.error
334
- })
335
-
352
+ cancelled_conv_data["requests"].append(
353
+ {
354
+ "request_id": request_id,
355
+ "status": result.status.value,
356
+ "loop_type": result.loop_type.value,
357
+ "response": result.response,
358
+ "feedback": result.feedback,
359
+ "responded_by": result.responded_by,
360
+ "responded_at": result.responded_at,
361
+ "error": result.error,
362
+ }
363
+ )
364
+
336
365
  # 添加已取消的对话
337
366
  task_data["conversations"].append(cancelled_conv_data)
338
-
367
+
339
368
  # 发送数据到平台
340
369
  loop.run_until_complete(self._async_send_task_data_to_platform(task_data))
341
370
  loop.close()
342
-
371
+
343
372
  # 更新最后同步时间
344
373
  self._last_sync_time = current_time
345
-
346
- async def _async_send_task_data_to_platform(self, task_data: Dict[str, Any]):
374
+
375
+ async def _async_send_task_data_to_platform(
376
+ self, task_data: Dict[str, Any]
377
+ ) -> None:
347
378
  """发送任务数据到 GoHumanLoop 平台"""
348
379
  try:
349
380
  # 构建 API 请求 URL
350
381
  api_base_url = self.ghl_config.api_base_url
351
382
  url = f"{api_base_url}/v1/humanloop/tasks/sync"
352
-
383
+
353
384
  # 构建请求头
354
385
  headers = {
355
386
  "Content-Type": "application/json",
356
- "Authorization": f"Bearer {self.ghl_config.api_key.get_secret_value()}"
387
+ "Authorization": f"Bearer {self.ghl_config.api_key.get_secret_value()}",
357
388
  }
358
-
389
+
359
390
  # 使用 aiohttp 直接发送请求,而不依赖于 provider
360
391
  async with aiohttp.ClientSession() as session:
361
392
  try:
@@ -363,7 +394,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
363
394
  url=url,
364
395
  headers=headers,
365
396
  json=task_data,
366
- timeout=30 # 设置合理的超时时间
397
+ timeout=30, # 设置合理的超时时间
367
398
  ) as response:
368
399
  # 处理 404 错误
369
400
  if response.status == 404:
@@ -371,16 +402,18 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
371
402
  return
372
403
  # 处理 401 错误
373
404
  elif response.status == 401:
374
- print(f"同步任务数据失败: 认证失败 - 请检查 API 密钥")
405
+ print("同步任务数据失败: 认证失败 - 请检查 API 密钥")
375
406
  return
376
-
407
+
377
408
  # 处理其他错误状态码
378
409
  if not response.ok:
379
- print(f"同步任务数据失败: HTTP {response.status} - {response.reason}")
410
+ print(
411
+ f"同步任务数据失败: HTTP {response.status} - {response.reason}"
412
+ )
380
413
  return
381
-
414
+
382
415
  response_data = await response.json()
383
-
416
+
384
417
  if not response_data.get("success", False):
385
418
  error_msg = response_data.get("error", "未知错误")
386
419
  print(f"同步任务数据失败: {error_msg}")
@@ -389,66 +422,57 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
389
422
  except Exception as e:
390
423
  print(f"发送任务数据到平台异常: {str(e)}")
391
424
 
392
-
393
425
  async def async_cancel_conversation(
394
- self,
395
- conversation_id: str,
396
- provider_id: Optional[str] = None
426
+ self, conversation_id: str, provider_id: Optional[str] = None
397
427
  ) -> bool:
398
428
  """
399
429
  取消整个对话,并保存取消信息用于后续同步
400
-
430
+
401
431
  重写父类方法,在调用父类方法前保存对话信息
402
432
  """
403
433
  # 获取对话关联的provider_id
404
434
  if provider_id is None:
405
435
  provider_id = self._conversation_provider.get(conversation_id)
406
-
436
+
407
437
  # 保存对话取消信息,包括provider_id
408
438
  self._cancelled_conversations[conversation_id] = {
409
439
  "request_ids": list(self._conversation_requests.get(conversation_id, [])),
410
- "provider_id": provider_id
440
+ "provider_id": provider_id,
411
441
  }
412
-
442
+
413
443
  # 调用父类方法执行实际取消操作
414
444
  return await super().async_cancel_conversation(conversation_id, provider_id)
415
-
445
+
416
446
  def __str__(self) -> str:
417
447
  """返回此实例的字符串描述"""
418
448
  return f"GoHumanLoop(default_provider={self.default_provider_id}, providers={len(self.providers)})"
419
-
449
+
420
450
  async def _async_get_request_status(
421
- self,
422
- conversation_id: str,
423
- request_id: str,
424
- provider_id: Optional[str] = None
451
+ self, conversation_id: str, request_id: str, provider_id: Optional[str] = None
425
452
  ) -> HumanLoopResult:
426
453
  """
427
454
  获取请求状态的辅助方法
428
-
455
+
429
456
  Args:
430
457
  conversation_id: 对话ID
431
458
  request_id: 请求ID
432
459
  provider_id: 提供者ID(可选)
433
-
460
+
434
461
  Returns:
435
462
  HumanLoopResult: 请求状态结果
436
463
  """
437
464
  # check_request_status
438
465
  if provider_id is None:
439
466
  provider_id = self._conversation_provider.get(conversation_id)
440
-
467
+
441
468
  if not provider_id or provider_id not in self.providers:
442
469
  raise ValueError(f"Provider '{provider_id}' not found")
443
-
470
+
444
471
  provider = self.providers[provider_id]
445
472
  return await provider.async_check_request_status(conversation_id, request_id)
446
473
 
447
474
  async def async_check_request_status(
448
- self,
449
- conversation_id: str,
450
- request_id: str,
451
- provider_id: Optional[str] = None
475
+ self, conversation_id: str, request_id: str, provider_id: Optional[str] = None
452
476
  ) -> HumanLoopResult:
453
477
  """
454
478
  重写父类方法,增加数据同步操作
@@ -457,34 +481,36 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
457
481
  if provider_id is None:
458
482
  stored_provider_id = self._conversation_provider.get(conversation_id)
459
483
  provider_id = stored_provider_id or self.default_provider_id
460
-
484
+
461
485
  if not provider_id or provider_id not in self.providers:
462
486
  raise ValueError(f"Provider '{provider_id}' not found")
463
-
487
+
464
488
  provider = self.providers[provider_id]
465
489
  result = await provider.async_check_request_status(conversation_id, request_id)
466
-
490
+
467
491
  # 如果有回调且状态不是等待或进行中
468
492
  if result.status not in [HumanLoopStatus.PENDING]:
469
493
  # 同步数据到平台
470
494
  await self.async_data_to_platform()
471
495
  # 触发状态更新回调
472
496
  if (conversation_id, request_id) in self._callbacks:
473
- await self._async_trigger_update_callback(conversation_id, request_id, provider, result)
497
+ await self._async_trigger_update_callback(
498
+ conversation_id, request_id, provider, result
499
+ )
474
500
 
475
501
  return result
476
-
477
- def shutdown(self):
502
+
503
+ def shutdown(self) -> None:
478
504
  """
479
505
  关闭管理器并确保数据同步(同步版本)
480
-
506
+
481
507
  在程序退出前调用此方法,确保所有数据都被同步到平台
482
508
  """
483
509
  # 停止同步线程
484
510
  if self._sync_thread and self._sync_thread.is_alive():
485
511
  self._sync_thread_stop_event.set()
486
512
  self._sync_thread.join(timeout=5) # 等待线程结束,最多5秒
487
-
513
+
488
514
  # 执行最后一次同步数据同步
489
515
  try:
490
516
  self.sync_data_to_platform()
@@ -492,10 +518,10 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
492
518
  except Exception as e:
493
519
  print(f"最终同步数据同步失败: {str(e)}")
494
520
 
495
- async def async_shutdown(self):
521
+ async def async_shutdown(self) -> None:
496
522
  """
497
523
  关闭管理器并确保数据同步(异步版本)
498
-
524
+
499
525
  在程序退出前调用此方法,确保所有数据都被同步到平台
500
526
  """
501
527
  # 取消周期性同步任务
@@ -511,22 +537,34 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
511
537
  print("最终异步数据同步完成")
512
538
  except Exception as e:
513
539
  print(f"最终异步数据同步失败: {str(e)}")
514
-
515
- async def __aenter__(self):
540
+
541
+ async def __aenter__(self) -> "GoHumanLoopManager":
516
542
  """实现异步上下文管理器协议的进入方法"""
517
543
  await self.async_start_sync_task()
518
544
  return self
519
-
520
- async def __aexit__(self, exc_type, exc_val, exc_tb):
545
+
546
+ async def __aexit__(
547
+ self,
548
+ exc_type: Optional[Type[BaseException]],
549
+ exc_val: Optional[BaseException],
550
+ exc_tb: Optional[TracebackType],
551
+ ) -> Optional[bool]:
521
552
  """实现异步上下文管理器协议的退出方法"""
522
553
  await self.async_shutdown()
523
-
524
- def __enter__(self):
554
+ return None
555
+
556
+ def __enter__(self) -> "GoHumanLoopManager":
525
557
  """实现同步上下文管理器协议的进入方法"""
526
558
  # 使用同步模式
527
559
  self.start_sync_task()
528
560
  return self
529
-
530
- def __exit__(self, exc_type, exc_val, exc_tb):
561
+
562
+ def __exit__(
563
+ self,
564
+ exc_type: Optional[Type[BaseException]],
565
+ exc_val: Optional[BaseException],
566
+ exc_tb: Optional[TracebackType],
567
+ ) -> Optional[bool]:
531
568
  """实现同步上下文管理器协议的退出方法"""
532
569
  self.shutdown()
570
+ return None