gohumanloop 0.0.2__py3-none-any.whl → 0.0.3__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.
- gohumanloop/adapters/langgraph_adapter.py +39 -41
- gohumanloop/core/interface.py +342 -21
- gohumanloop/core/manager.py +302 -39
- gohumanloop/manager/ghl_manager.py +22 -22
- gohumanloop/providers/api_provider.py +18 -18
- gohumanloop/providers/base.py +239 -9
- gohumanloop/providers/email_provider.py +15 -15
- gohumanloop/providers/terminal_provider.py +12 -13
- gohumanloop/utils/utils.py +30 -3
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/METADATA +1 -1
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/RECORD +15 -15
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/WHEEL +1 -1
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/entry_points.txt +0 -0
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/licenses/LICENSE +0 -0
- {gohumanloop-0.0.2.dist-info → gohumanloop-0.0.3.dist-info}/top_level.txt +0 -0
@@ -98,22 +98,22 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
98
98
|
if auto_start_sync:
|
99
99
|
# 判断是否处在异步环境
|
100
100
|
if asyncio.get_event_loop().is_running():
|
101
|
-
asyncio.create_task(self.
|
101
|
+
asyncio.create_task(self.async_start_sync_task())
|
102
102
|
else:
|
103
103
|
self.start_sync_task()
|
104
104
|
|
105
105
|
|
106
|
-
async def
|
106
|
+
async def async_get_ghl_provider(self) -> GoHumanLoopProvider:
|
107
107
|
"""
|
108
108
|
获取 GoHumanLoop 提供者实例
|
109
109
|
|
110
110
|
Returns:
|
111
111
|
GoHumanLoopProvider: GoHumanLoop 提供者实例
|
112
112
|
"""
|
113
|
-
provider = await self.
|
113
|
+
provider = await self.async_get_provider(self.default_provider_id)
|
114
114
|
return provider
|
115
115
|
|
116
|
-
async def
|
116
|
+
async def async_start_sync_task(self):
|
117
117
|
"""启动数据同步任务"""
|
118
118
|
if self._sync_task is None or self._sync_task.done():
|
119
119
|
self._sync_task = asyncio.create_task(self._async_data_periodically())
|
@@ -176,7 +176,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
176
176
|
# 对每个任务进行数据同步
|
177
177
|
for task_id in task_ids:
|
178
178
|
# 获取任务相关的所有对话
|
179
|
-
conversations = await self.
|
179
|
+
conversations = await self.async_get_task_conversations(task_id)
|
180
180
|
|
181
181
|
# 收集任务数据
|
182
182
|
task_data = {
|
@@ -188,7 +188,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
188
188
|
# 收集每个对话的数据
|
189
189
|
for conversation_id in conversations:
|
190
190
|
# 获取对话中的所有请求
|
191
|
-
request_ids = await self.
|
191
|
+
request_ids = await self.async_get_conversation_requests(conversation_id)
|
192
192
|
|
193
193
|
conversation_data = {
|
194
194
|
"conversation_id": conversation_id,
|
@@ -198,7 +198,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
198
198
|
|
199
199
|
# 收集每个请求的数据
|
200
200
|
for request_id in request_ids:
|
201
|
-
result = await self.
|
201
|
+
result = await self._async_get_request_status(conversation_id, request_id)
|
202
202
|
|
203
203
|
# 添加请求数据
|
204
204
|
conversation_data["requests"].append({
|
@@ -227,7 +227,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
227
227
|
|
228
228
|
# 添加此对话中的已取消请求
|
229
229
|
for request_id in cancel_info.get("request_ids", []):
|
230
|
-
result = await self.
|
230
|
+
result = await self._async_get_request_status(conv_id, request_id, cancel_info.get("provider_id"))
|
231
231
|
|
232
232
|
# 添加请求数据
|
233
233
|
cancelled_conv_data["requests"].append({
|
@@ -245,7 +245,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
245
245
|
task_data["conversations"].append(cancelled_conv_data)
|
246
246
|
|
247
247
|
# 发送数据到平台
|
248
|
-
await self.
|
248
|
+
await self._async_send_task_data_to_platform(task_data)
|
249
249
|
|
250
250
|
# 更新最后同步时间
|
251
251
|
self._last_sync_time = current_time
|
@@ -288,7 +288,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
288
288
|
|
289
289
|
# 收集每个请求的数据
|
290
290
|
for request_id in request_ids:
|
291
|
-
result = loop.run_until_complete(self.
|
291
|
+
result = loop.run_until_complete(self._async_get_request_status(conversation_id, request_id))
|
292
292
|
|
293
293
|
# 添加请求数据
|
294
294
|
conversation_data["requests"].append({
|
@@ -318,7 +318,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
318
318
|
# 添加此对话中的已取消请求
|
319
319
|
for request_id in cancel_info.get("request_ids", []):
|
320
320
|
result = loop.run_until_complete(
|
321
|
-
self.
|
321
|
+
self._async_get_request_status(conv_id, request_id, cancel_info.get("provider_id"))
|
322
322
|
)
|
323
323
|
|
324
324
|
# 添加请求数据
|
@@ -337,13 +337,13 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
337
337
|
task_data["conversations"].append(cancelled_conv_data)
|
338
338
|
|
339
339
|
# 发送数据到平台
|
340
|
-
loop.run_until_complete(self.
|
340
|
+
loop.run_until_complete(self._async_send_task_data_to_platform(task_data))
|
341
341
|
loop.close()
|
342
342
|
|
343
343
|
# 更新最后同步时间
|
344
344
|
self._last_sync_time = current_time
|
345
345
|
|
346
|
-
async def
|
346
|
+
async def _async_send_task_data_to_platform(self, task_data: Dict[str, Any]):
|
347
347
|
"""发送任务数据到 GoHumanLoop 平台"""
|
348
348
|
try:
|
349
349
|
# 构建 API 请求 URL
|
@@ -390,7 +390,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
390
390
|
print(f"发送任务数据到平台异常: {str(e)}")
|
391
391
|
|
392
392
|
|
393
|
-
async def
|
393
|
+
async def async_cancel_conversation(
|
394
394
|
self,
|
395
395
|
conversation_id: str,
|
396
396
|
provider_id: Optional[str] = None
|
@@ -411,13 +411,13 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
411
411
|
}
|
412
412
|
|
413
413
|
# 调用父类方法执行实际取消操作
|
414
|
-
return await super().
|
414
|
+
return await super().async_cancel_conversation(conversation_id, provider_id)
|
415
415
|
|
416
416
|
def __str__(self) -> str:
|
417
417
|
"""返回此实例的字符串描述"""
|
418
418
|
return f"GoHumanLoop(default_provider={self.default_provider_id}, providers={len(self.providers)})"
|
419
419
|
|
420
|
-
async def
|
420
|
+
async def _async_get_request_status(
|
421
421
|
self,
|
422
422
|
conversation_id: str,
|
423
423
|
request_id: str,
|
@@ -444,7 +444,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
444
444
|
provider = self.providers[provider_id]
|
445
445
|
return await provider.check_request_status(conversation_id, request_id)
|
446
446
|
|
447
|
-
async def
|
447
|
+
async def async_check_request_status(
|
448
448
|
self,
|
449
449
|
conversation_id: str,
|
450
450
|
request_id: str,
|
@@ -462,7 +462,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
462
462
|
raise ValueError(f"Provider '{provider_id}' not found")
|
463
463
|
|
464
464
|
provider = self.providers[provider_id]
|
465
|
-
result = await provider.
|
465
|
+
result = await provider.async_check_request_status(conversation_id, request_id)
|
466
466
|
|
467
467
|
# 如果有回调且状态不是等待或进行中
|
468
468
|
if result.status not in [HumanLoopStatus.PENDING]:
|
@@ -470,7 +470,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
470
470
|
await self.async_data_to_platform()
|
471
471
|
# 触发状态更新回调
|
472
472
|
if (conversation_id, request_id) in self._callbacks:
|
473
|
-
await self.
|
473
|
+
await self._async_trigger_update_callback(conversation_id, request_id, provider, result)
|
474
474
|
|
475
475
|
return result
|
476
476
|
|
@@ -492,7 +492,7 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
492
492
|
except Exception as e:
|
493
493
|
print(f"最终同步数据同步失败: {str(e)}")
|
494
494
|
|
495
|
-
async def
|
495
|
+
async def async_shutdown(self):
|
496
496
|
"""
|
497
497
|
关闭管理器并确保数据同步(异步版本)
|
498
498
|
|
@@ -514,12 +514,12 @@ class GoHumanLoopManager(DefaultHumanLoopManager):
|
|
514
514
|
|
515
515
|
async def __aenter__(self):
|
516
516
|
"""实现异步上下文管理器协议的进入方法"""
|
517
|
-
await self.
|
517
|
+
await self.async_start_sync_task()
|
518
518
|
return self
|
519
519
|
|
520
520
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
521
521
|
"""实现异步上下文管理器协议的退出方法"""
|
522
|
-
await self.
|
522
|
+
await self.async_shutdown()
|
523
523
|
|
524
524
|
def __enter__(self):
|
525
525
|
"""实现同步上下文管理器协议的进入方法"""
|
@@ -65,7 +65,7 @@ class APIProvider(BaseProvider):
|
|
65
65
|
api_info += f" Default Platform: {self.default_platform}\n"
|
66
66
|
return f"{api_info}{base_str}"
|
67
67
|
|
68
|
-
async def
|
68
|
+
async def _async_make_api_request(
|
69
69
|
self,
|
70
70
|
endpoint: str,
|
71
71
|
method: str = "POST",
|
@@ -146,7 +146,7 @@ class APIProvider(BaseProvider):
|
|
146
146
|
continue
|
147
147
|
raise
|
148
148
|
|
149
|
-
async def
|
149
|
+
async def async_request_humanloop(
|
150
150
|
self,
|
151
151
|
task_id: str,
|
152
152
|
conversation_id: str,
|
@@ -208,7 +208,7 @@ class APIProvider(BaseProvider):
|
|
208
208
|
|
209
209
|
try:
|
210
210
|
# Send API request
|
211
|
-
response = await self.
|
211
|
+
response = await self._async_make_api_request(
|
212
212
|
endpoint="v1/humanloop/request",
|
213
213
|
method="POST",
|
214
214
|
data=request_data
|
@@ -231,13 +231,13 @@ class APIProvider(BaseProvider):
|
|
231
231
|
|
232
232
|
# Create polling task
|
233
233
|
poll_task = asyncio.create_task(
|
234
|
-
self.
|
234
|
+
self._async_poll_request_status(conversation_id, request_id, platform)
|
235
235
|
)
|
236
236
|
self._poll_tasks[(conversation_id, request_id)] = poll_task
|
237
237
|
|
238
238
|
# Create timeout task if timeout is set
|
239
239
|
if timeout:
|
240
|
-
|
240
|
+
await self._async_create_timeout_task(conversation_id, request_id, timeout)
|
241
241
|
|
242
242
|
return HumanLoopResult(
|
243
243
|
conversation_id=conversation_id,
|
@@ -258,7 +258,7 @@ class APIProvider(BaseProvider):
|
|
258
258
|
status=HumanLoopStatus.ERROR,
|
259
259
|
error=str(e)
|
260
260
|
)
|
261
|
-
async def
|
261
|
+
async def async_check_request_status(
|
262
262
|
self,
|
263
263
|
conversation_id: str,
|
264
264
|
request_id: str
|
@@ -297,7 +297,7 @@ class APIProvider(BaseProvider):
|
|
297
297
|
return result
|
298
298
|
|
299
299
|
|
300
|
-
async def
|
300
|
+
async def async_cancel_request(
|
301
301
|
self,
|
302
302
|
conversation_id: str,
|
303
303
|
request_id: str
|
@@ -312,7 +312,7 @@ class APIProvider(BaseProvider):
|
|
312
312
|
bool: Whether cancellation was successful, True for success, False for failure
|
313
313
|
"""
|
314
314
|
# First call parent method to update local state
|
315
|
-
result = await super().
|
315
|
+
result = await super().async_cancel_request(conversation_id, request_id)
|
316
316
|
if not result:
|
317
317
|
return False
|
318
318
|
|
@@ -335,7 +335,7 @@ class APIProvider(BaseProvider):
|
|
335
335
|
platform=platform
|
336
336
|
).model_dump()
|
337
337
|
|
338
|
-
response = await self.
|
338
|
+
response = await self._async_make_api_request(
|
339
339
|
endpoint="v1/humanloop/cancel",
|
340
340
|
method="POST",
|
341
341
|
data=cancel_data
|
@@ -359,7 +359,7 @@ class APIProvider(BaseProvider):
|
|
359
359
|
logger.error(f"Cancel request failed: {str(e)}")
|
360
360
|
return False
|
361
361
|
|
362
|
-
async def
|
362
|
+
async def async_cancel_conversation(
|
363
363
|
self,
|
364
364
|
conversation_id: str
|
365
365
|
) -> bool:
|
@@ -372,7 +372,7 @@ class APIProvider(BaseProvider):
|
|
372
372
|
bool: Whether cancellation was successful
|
373
373
|
"""
|
374
374
|
# First call parent method to update local state
|
375
|
-
result = await super().
|
375
|
+
result = await super().async_cancel_conversation(conversation_id)
|
376
376
|
if not result:
|
377
377
|
return False
|
378
378
|
|
@@ -398,7 +398,7 @@ class APIProvider(BaseProvider):
|
|
398
398
|
platform=platform
|
399
399
|
).model_dump()
|
400
400
|
|
401
|
-
response = await self.
|
401
|
+
response = await self._async_make_api_request(
|
402
402
|
endpoint="v1/humanloop/cancel_conversation",
|
403
403
|
method="POST",
|
404
404
|
data=cancel_data
|
@@ -424,7 +424,7 @@ class APIProvider(BaseProvider):
|
|
424
424
|
return False
|
425
425
|
|
426
426
|
|
427
|
-
async def
|
427
|
+
async def async_continue_humanloop(
|
428
428
|
self,
|
429
429
|
conversation_id: str,
|
430
430
|
context: Dict[str, Any],
|
@@ -496,7 +496,7 @@ class APIProvider(BaseProvider):
|
|
496
496
|
|
497
497
|
try:
|
498
498
|
# Send API request
|
499
|
-
response = await self.
|
499
|
+
response = await self._async_make_api_request(
|
500
500
|
endpoint="v1/humanloop/continue",
|
501
501
|
method="POST",
|
502
502
|
data=continue_data
|
@@ -518,13 +518,13 @@ class APIProvider(BaseProvider):
|
|
518
518
|
|
519
519
|
# Create polling task
|
520
520
|
poll_task = asyncio.create_task(
|
521
|
-
self.
|
521
|
+
self._async_poll_request_status(conversation_id, request_id, platform)
|
522
522
|
)
|
523
523
|
self._poll_tasks[(conversation_id, request_id)] = poll_task
|
524
524
|
|
525
525
|
# Create timeout task if timeout is set
|
526
526
|
if timeout:
|
527
|
-
self.
|
527
|
+
await self._async_create_timeout_task(conversation_id, request_id, timeout)
|
528
528
|
|
529
529
|
return HumanLoopResult(
|
530
530
|
conversation_id=conversation_id,
|
@@ -546,7 +546,7 @@ class APIProvider(BaseProvider):
|
|
546
546
|
error=str(e)
|
547
547
|
)
|
548
548
|
|
549
|
-
async def
|
549
|
+
async def _async_poll_request_status(
|
550
550
|
self,
|
551
551
|
conversation_id: str,
|
552
552
|
request_id: str,
|
@@ -579,7 +579,7 @@ class APIProvider(BaseProvider):
|
|
579
579
|
platform=platform
|
580
580
|
).model_dump()
|
581
581
|
|
582
|
-
response = await self.
|
582
|
+
response = await self._async_make_api_request(
|
583
583
|
endpoint="v1/humanloop/status",
|
584
584
|
method="GET",
|
585
585
|
params=params
|
gohumanloop/providers/base.py
CHANGED
@@ -109,7 +109,7 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
109
109
|
"""Get all request IDs in the conversation"""
|
110
110
|
return self._conversation_requests.get(conversation_id, [])
|
111
111
|
|
112
|
-
async def
|
112
|
+
async def async_request_humanloop(
|
113
113
|
self,
|
114
114
|
task_id: str,
|
115
115
|
conversation_id: str,
|
@@ -134,8 +134,52 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
134
134
|
# Subclasses must implement this method
|
135
135
|
raise NotImplementedError("Subclasses must implement request_humanloop")
|
136
136
|
|
137
|
+
def request_humanloop(
|
138
|
+
self,
|
139
|
+
task_id: str,
|
140
|
+
conversation_id: str,
|
141
|
+
loop_type: HumanLoopType,
|
142
|
+
context: Dict[str, Any],
|
143
|
+
metadata: Optional[Dict[str, Any]] = None,
|
144
|
+
timeout: Optional[int] = None
|
145
|
+
) -> HumanLoopResult:
|
146
|
+
"""Request human-in-the-loop interaction (synchronous version)
|
137
147
|
|
138
|
-
|
148
|
+
Args:
|
149
|
+
task_id: Task identifier
|
150
|
+
conversation_id: Conversation ID for multi-turn dialogues
|
151
|
+
loop_type: Type of human loop interaction
|
152
|
+
context: Context information provided to human
|
153
|
+
metadata: Additional metadata
|
154
|
+
timeout: Request timeout in seconds
|
155
|
+
|
156
|
+
Returns:
|
157
|
+
HumanLoopResult: Result object containing request ID and initial status
|
158
|
+
"""
|
159
|
+
|
160
|
+
loop = asyncio.get_event_loop()
|
161
|
+
if loop.is_running():
|
162
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
163
|
+
new_loop = asyncio.new_event_loop()
|
164
|
+
asyncio.set_event_loop(new_loop)
|
165
|
+
loop = new_loop
|
166
|
+
|
167
|
+
try:
|
168
|
+
return loop.run_until_complete(
|
169
|
+
self.async_request_humanloop(
|
170
|
+
task_id=task_id,
|
171
|
+
conversation_id=conversation_id,
|
172
|
+
loop_type=loop_type,
|
173
|
+
context=context,
|
174
|
+
metadata=metadata,
|
175
|
+
timeout=timeout
|
176
|
+
))
|
177
|
+
finally:
|
178
|
+
if loop != asyncio.get_event_loop():
|
179
|
+
loop.close()
|
180
|
+
|
181
|
+
|
182
|
+
async def async_check_request_status(
|
139
183
|
self,
|
140
184
|
conversation_id: str,
|
141
185
|
request_id: str
|
@@ -163,7 +207,39 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
163
207
|
raise NotImplementedError("Subclasses must implement check_request_status")
|
164
208
|
|
165
209
|
|
166
|
-
|
210
|
+
def check_request_status(
|
211
|
+
self,
|
212
|
+
conversation_id: str,
|
213
|
+
request_id: str
|
214
|
+
) -> HumanLoopResult:
|
215
|
+
"""Check conversation status (synchronous version)
|
216
|
+
|
217
|
+
Args:
|
218
|
+
conversation_id: Conversation identifier
|
219
|
+
|
220
|
+
Returns:
|
221
|
+
HumanLoopResult: Result containing the status of the latest request in the conversation
|
222
|
+
"""
|
223
|
+
|
224
|
+
loop = asyncio.get_event_loop()
|
225
|
+
if loop.is_running():
|
226
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
227
|
+
new_loop = asyncio.new_event_loop()
|
228
|
+
asyncio.set_event_loop(new_loop)
|
229
|
+
loop = new_loop
|
230
|
+
|
231
|
+
try:
|
232
|
+
return loop.run_until_complete(
|
233
|
+
self.async_check_request_status(
|
234
|
+
conversation_id=conversation_id,
|
235
|
+
request_id=request_id
|
236
|
+
))
|
237
|
+
finally:
|
238
|
+
if loop != asyncio.get_event_loop():
|
239
|
+
loop.close()
|
240
|
+
|
241
|
+
|
242
|
+
async def async_check_conversation_status(
|
167
243
|
self,
|
168
244
|
conversation_id: str
|
169
245
|
) -> HumanLoopResult:
|
@@ -195,9 +271,40 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
195
271
|
error=f"No requests found in conversation '{conversation_id}'"
|
196
272
|
)
|
197
273
|
|
198
|
-
return await self.
|
274
|
+
return await self.async_check_request_status(conversation_id, latest_request_id)
|
275
|
+
|
276
|
+
|
277
|
+
def check_conversation_status(
|
278
|
+
self,
|
279
|
+
conversation_id: str
|
280
|
+
) -> HumanLoopResult:
|
281
|
+
"""Check conversation status (synchronous version)
|
199
282
|
|
200
|
-
|
283
|
+
Args:
|
284
|
+
conversation_id: Conversation identifier
|
285
|
+
|
286
|
+
Returns:
|
287
|
+
HumanLoopResult: Result containing the status of the latest request in the conversation
|
288
|
+
"""
|
289
|
+
|
290
|
+
loop = asyncio.get_event_loop()
|
291
|
+
if loop.is_running():
|
292
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
293
|
+
new_loop = asyncio.new_event_loop()
|
294
|
+
asyncio.set_event_loop(new_loop)
|
295
|
+
loop = new_loop
|
296
|
+
|
297
|
+
try:
|
298
|
+
return loop.run_until_complete(
|
299
|
+
self.async_check_conversation_status(
|
300
|
+
conversation_id=conversation_id
|
301
|
+
))
|
302
|
+
finally:
|
303
|
+
if loop != asyncio.get_event_loop():
|
304
|
+
loop.close()
|
305
|
+
|
306
|
+
|
307
|
+
async def async_cancel_request(
|
201
308
|
self,
|
202
309
|
conversation_id: str,
|
203
310
|
request_id: str
|
@@ -224,7 +331,38 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
224
331
|
return True
|
225
332
|
return False
|
226
333
|
|
227
|
-
|
334
|
+
def cancel_request(
|
335
|
+
self,
|
336
|
+
conversation_id: str,
|
337
|
+
request_id: str
|
338
|
+
) -> bool:
|
339
|
+
"""Cancel human-in-the-loop request (synchronous version)
|
340
|
+
|
341
|
+
Args:
|
342
|
+
conversation_id: Conversation identifier for multi-turn dialogues
|
343
|
+
request_id: Request identifier for specific interaction request
|
344
|
+
|
345
|
+
Returns:
|
346
|
+
bool: Whether cancellation was successful, True indicates success, False indicates failure
|
347
|
+
"""
|
348
|
+
loop = asyncio.get_event_loop()
|
349
|
+
if loop.is_running():
|
350
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
351
|
+
new_loop = asyncio.new_event_loop()
|
352
|
+
asyncio.set_event_loop(new_loop)
|
353
|
+
loop = new_loop
|
354
|
+
|
355
|
+
try:
|
356
|
+
return loop.run_until_complete(
|
357
|
+
self.async_cancel_request(
|
358
|
+
conversation_id=conversation_id,
|
359
|
+
request_id=request_id
|
360
|
+
))
|
361
|
+
finally:
|
362
|
+
if loop != asyncio.get_event_loop():
|
363
|
+
loop.close()
|
364
|
+
|
365
|
+
async def async_cancel_conversation(
|
228
366
|
self,
|
229
367
|
conversation_id: str
|
230
368
|
) -> bool:
|
@@ -258,7 +396,38 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
258
396
|
|
259
397
|
return success
|
260
398
|
|
261
|
-
|
399
|
+
|
400
|
+
def cancel_conversation(
|
401
|
+
self,
|
402
|
+
conversation_id: str
|
403
|
+
) -> bool:
|
404
|
+
"""Cancel the entire conversation (synchronous version)
|
405
|
+
|
406
|
+
Args:
|
407
|
+
conversation_id: Conversation identifier
|
408
|
+
|
409
|
+
Returns:
|
410
|
+
bool: Whether the cancellation was successful
|
411
|
+
"""
|
412
|
+
|
413
|
+
loop = asyncio.get_event_loop()
|
414
|
+
if loop.is_running():
|
415
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
416
|
+
new_loop = asyncio.new_event_loop()
|
417
|
+
asyncio.set_event_loop(new_loop)
|
418
|
+
loop = new_loop
|
419
|
+
|
420
|
+
try:
|
421
|
+
return loop.run_until_complete(
|
422
|
+
self.async_cancel_conversation(
|
423
|
+
conversation_id=conversation_id
|
424
|
+
))
|
425
|
+
finally:
|
426
|
+
if loop != asyncio.get_event_loop():
|
427
|
+
loop.close()
|
428
|
+
|
429
|
+
|
430
|
+
async def async_continue_humanloop(
|
262
431
|
self,
|
263
432
|
conversation_id: str,
|
264
433
|
context: Dict[str, Any],
|
@@ -290,7 +459,46 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
290
459
|
# Subclasses need to implement specific continuation logic
|
291
460
|
raise NotImplementedError("Subclasses must implement continue_humanloop")
|
292
461
|
|
293
|
-
|
462
|
+
|
463
|
+
def continue_humanloop(
|
464
|
+
self,
|
465
|
+
conversation_id: str,
|
466
|
+
context: Dict[str, Any],
|
467
|
+
metadata: Optional[Dict[str, Any]] = None,
|
468
|
+
timeout: Optional[int] = None,
|
469
|
+
) -> HumanLoopResult:
|
470
|
+
"""Continue human-in-the-loop interaction (synchronous version)
|
471
|
+
|
472
|
+
Args:
|
473
|
+
conversation_id: Conversation ID for multi-turn dialogues
|
474
|
+
context: Context information provided to human
|
475
|
+
metadata: Additional metadata
|
476
|
+
timeout: Request timeout in seconds
|
477
|
+
|
478
|
+
Returns:
|
479
|
+
HumanLoopResult: Result object containing request ID and status
|
480
|
+
"""
|
481
|
+
|
482
|
+
loop = asyncio.get_event_loop()
|
483
|
+
if loop.is_running():
|
484
|
+
# 如果事件循环已经在运行,创建一个新的事件循环
|
485
|
+
new_loop = asyncio.new_event_loop()
|
486
|
+
asyncio.set_event_loop(new_loop)
|
487
|
+
loop = new_loop
|
488
|
+
|
489
|
+
try:
|
490
|
+
return loop.run_until_complete(
|
491
|
+
self.async_continue_humanloop(
|
492
|
+
conversation_id=conversation_id,
|
493
|
+
context=context,
|
494
|
+
metadata=metadata,
|
495
|
+
timeout=timeout
|
496
|
+
))
|
497
|
+
finally:
|
498
|
+
if loop != asyncio.get_event_loop():
|
499
|
+
loop.close()
|
500
|
+
|
501
|
+
def async_get_conversation_history(self, conversation_id: str) -> List[Dict[str, Any]]:
|
294
502
|
"""Get complete history for the specified conversation
|
295
503
|
|
296
504
|
Args:
|
@@ -315,8 +523,30 @@ class BaseProvider(HumanLoopProvider, ABC):
|
|
315
523
|
})
|
316
524
|
return conversation_history
|
317
525
|
|
526
|
+
def get_conversation_history(self, conversation_id: str) -> List[Dict[str, Any]]:
|
527
|
+
"""Get complete history for the specified conversation (synchronous version)
|
528
|
+
|
529
|
+
Args:
|
530
|
+
conversation_id: Conversation identifier
|
531
|
+
|
532
|
+
Returns:
|
533
|
+
List[Dict[str, Any]]: List of conversation history records, each containing request ID,
|
534
|
+
status, context, response and other information
|
535
|
+
"""
|
536
|
+
loop = asyncio.get_event_loop()
|
537
|
+
if loop.is_running():
|
538
|
+
new_loop = asyncio.new_event_loop()
|
539
|
+
asyncio.set_event_loop(new_loop)
|
540
|
+
loop = new_loop
|
541
|
+
|
542
|
+
try:
|
543
|
+
return loop.run_until_complete(self.async_get_conversation_history(conversation_id))
|
544
|
+
finally:
|
545
|
+
if loop != asyncio.get_event_loop():
|
546
|
+
loop.close()
|
547
|
+
|
318
548
|
|
319
|
-
def
|
549
|
+
async def _async_create_timeout_task(
|
320
550
|
self,
|
321
551
|
conversation_id: str,
|
322
552
|
request_id: str,
|