gohumanloop 0.0.1__py3-none-any.whl → 0.0.2__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.
File without changes
@@ -0,0 +1,29 @@
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+ import click
5
+
6
+ load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))
7
+
8
+
9
+ @click.group(name="gohumanloop")
10
+ def cli() -> None:
11
+ pass
12
+
13
+
14
+ @cli.command(
15
+ "check",
16
+ help="""Check if gohumanloop library is installed""",
17
+ )
18
+ def cli_check() -> None:
19
+ try:
20
+ import gohumanloop
21
+ click.echo("gohumanloop library is successfully installed!")
22
+ click.echo(f"Version: {gohumanloop.__version__ if hasattr(gohumanloop, '__version__') else 'Unknown'}")
23
+ except ImportError:
24
+ click.echo("Error: gohumanloop library is not installed or cannot be imported.")
25
+ click.echo("Please use 'pip install gohumanloop' to install the library.")
26
+
27
+
28
+ if __name__ == "__main__":
29
+ cli()
File without changes
@@ -0,0 +1,437 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Dict, Optional, Protocol, runtime_checkable, List, Union, Callable, Awaitable
3
+ from enum import Enum
4
+ from dataclasses import dataclass, field
5
+ from datetime import datetime
6
+
7
+ class HumanLoopStatus(Enum):
8
+ """Enumeration of human-in-the-loop states"""
9
+ PENDING = "pending"
10
+ APPROVED = "approved"
11
+ REJECTED = "rejected"
12
+ EXPIRED = "expired"
13
+ ERROR = "error"
14
+ COMPLETED = "completed" # For completing non-approval interactions
15
+ INPROGRESS = "inprogress" # Intermediate state for multi-turn dialogues, indicating ongoing conversation
16
+ CANCELLED = "cancelled" # For cancelled requests
17
+
18
+ class HumanLoopType(Enum):
19
+ """Enumeration of human-in-the-loop types"""
20
+ APPROVAL = "approval" # Approval type
21
+ INFORMATION = "information" # Information gathering type
22
+ CONVERSATION = "conversation" # Conversation type
23
+
24
+ """
25
+ ## Relationship between task_id, conversation_id and request_id
26
+ 1. Hierarchical relationship:
27
+
28
+ - task_id is at the highest level, representing business tasks
29
+ - conversation_id is at the middle level, representing a complete dialogue session
30
+ - request_id is at the lowest level, representing a single interaction request
31
+ 2. Mapping relationship:
32
+
33
+ - One task_id may correspond to multiple conversation_ids (a task may require multiple conversations)
34
+ - One conversation_id may correspond to multiple request_ids (a conversation may contain multiple rounds of interaction)
35
+ """
36
+ @dataclass
37
+ class HumanLoopRequest:
38
+ """人机循环请求的数据模型 / Human loop request data model"""
39
+ task_id: str # 任务ID / Task identifier
40
+ conversation_id: str# 用于关联多轮对话 / Used to associate multi-turn conversations
41
+ loop_type: HumanLoopType # 循环类型 / Loop type
42
+ context: Dict[str, Any] # 交互上下文信息 / Interaction context information
43
+ metadata: Dict[str, Any] = field(default_factory=dict) # 元数据信息 / Metadata information
44
+ request_id: Optional[str] = None # 请求ID / Request identifier
45
+ timeout: Optional[int] = None # 超时时间(秒) / Timeout duration (seconds)
46
+ created_at: Optional[datetime] = None # 将在请求创建时设置 / Will be set when request is created
47
+
48
+ @dataclass
49
+ class HumanLoopResult:
50
+ """人机循环结果的数据模型 / Human loop result data model"""
51
+ conversation_id: str # 用于关联多轮对话 / Used to associate multi-turn conversations
52
+ request_id: str # 请求ID / Request identifier
53
+ loop_type: HumanLoopType # 循环类型 / Loop type
54
+ status: HumanLoopStatus # 循环状态 / Loop status
55
+ response: Dict[str, Any] = field(default_factory=dict) # 人类提供的响应数据 / Response data provided by human
56
+ feedback: Dict[str, Any] = field(default_factory=dict) # 反馈信息 / Feedback information
57
+ responded_by: Optional[str] = None # 响应者 / Responder
58
+ responded_at: Optional[str] = None # 响应时间 / Response time
59
+ error: Optional[str] = None # 错误信息 / Error message
60
+
61
+ @runtime_checkable
62
+ class HumanLoopProvider(Protocol):
63
+ """Human-in-the-loop Provider Protocol"""
64
+
65
+ name: str # 提供者名称
66
+
67
+ @abstractmethod
68
+ async def request_humanloop(
69
+ self,
70
+ task_id: str,
71
+ conversation_id: str,
72
+ loop_type: HumanLoopType,
73
+ context: Dict[str, Any],
74
+ metadata: Optional[Dict[str, Any]] = None,
75
+ timeout: Optional[int] = None
76
+ ) -> HumanLoopResult:
77
+ """请求人机循环
78
+
79
+ Args:
80
+ task_id: 任务标识符
81
+ conversation_id: 对话ID,用于多轮对话
82
+ loop_type: 循环类型
83
+ context: 提供给人类的上下文信息
84
+ metadata: 附加元数据
85
+ timeout: 请求超时时间(秒)
86
+
87
+ Returns:
88
+ HumanLoopResult: 包含请求ID和初始状态的结果对象
89
+ """
90
+ pass
91
+
92
+ @abstractmethod
93
+ async def check_request_status(
94
+ self,
95
+ conversation_id: str,
96
+ request_id: str
97
+ ) -> HumanLoopResult:
98
+ """检查请求状态
99
+
100
+ Args:
101
+ conversation_id: 对话标识符,用于关联多轮对话
102
+ request_id: 请求标识符,用于标识具体的交互请求
103
+
104
+ Returns:
105
+ HumanLoopResult: 包含当前请求状态的结果对象,包括状态、响应数据等信息
106
+ """
107
+ pass
108
+ @abstractmethod
109
+ async def check_conversation_status(
110
+ self,
111
+ conversation_id: str
112
+ ) -> HumanLoopResult:
113
+ """检查对话状态
114
+
115
+ Args:
116
+ conversation_id: 对话标识符
117
+
118
+ Returns:
119
+ HumanLoopResult: 包含对话最新请求的状态
120
+ """
121
+ pass
122
+
123
+ @abstractmethod
124
+ async def cancel_request(
125
+ self,
126
+ conversation_id: str,
127
+ request_id: str
128
+ ) -> bool:
129
+ """取消人机循环请求
130
+
131
+ Args:
132
+ conversation_id: 对话标识符,用于关联多轮对话
133
+ request_id: 请求标识符,用于标识具体的交互请求
134
+
135
+ Returns:
136
+ bool: 取消是否成功,True表示取消成功,False表示取消失败
137
+ """
138
+ pass
139
+
140
+ @abstractmethod
141
+ async def cancel_conversation(
142
+ self,
143
+ conversation_id: str
144
+ ) -> bool:
145
+ """取消整个对话
146
+
147
+ Args:
148
+ conversation_id: 对话标识符
149
+
150
+ Returns:
151
+ bool: 取消是否成功
152
+ """
153
+ pass
154
+
155
+ @abstractmethod
156
+ async def continue_humanloop(
157
+ self,
158
+ conversation_id: str,
159
+ context: Dict[str, Any],
160
+ metadata: Optional[Dict[str, Any]] = None,
161
+ timeout: Optional[int] = None,
162
+ ) -> HumanLoopResult:
163
+ """继续人机循环
164
+
165
+ Args:
166
+ conversation_id: 对话ID,用于多轮对话
167
+ context: 提供给人类的上下文信息
168
+ metadata: 附加元数据
169
+ timeout: 请求超时时间(秒)
170
+
171
+ Returns:
172
+ HumanLoopResult: 包含请求ID和状态的结果对象
173
+ """
174
+ pass
175
+
176
+ class HumanLoopCallback(ABC):
177
+ """人机循环回调的抽象类"""
178
+
179
+ @abstractmethod
180
+ async def on_humanloop_update(
181
+ self,
182
+ provider: HumanLoopProvider,
183
+ result: HumanLoopResult
184
+ ):
185
+ """当请求更新时的回调
186
+
187
+ Args:
188
+ provider: 人机循环提供者实例
189
+ result: 循环结果
190
+ """
191
+ pass
192
+
193
+ @abstractmethod
194
+ async def on_humanloop_timeout(
195
+ self,
196
+ provider: HumanLoopProvider,
197
+ ):
198
+ """当请求超时时的回调
199
+
200
+ Args:
201
+ provider: 人机循环提供者实例
202
+ """
203
+ pass
204
+
205
+ @abstractmethod
206
+ async def on_humanloop_error(
207
+ self,
208
+ provider: HumanLoopProvider,
209
+ error: Exception
210
+ ):
211
+ """当请求发生错误时的回调
212
+
213
+ Args:
214
+ provider: 人机循环提供者实例
215
+ error: 错误信息
216
+ """
217
+ pass
218
+
219
+ class HumanLoopManager(ABC):
220
+ """人机循环管理器的抽象类"""
221
+
222
+ @abstractmethod
223
+ async def register_provider(
224
+ self,
225
+ provider: HumanLoopProvider,
226
+ provider_id: Optional[str] = None
227
+ ) -> str:
228
+ """注册人机循环提供者
229
+
230
+ Args:
231
+ provider: 人机循环提供者实例
232
+ provider_id: 提供者标识符(可选)
233
+
234
+ Returns:
235
+ str: 注册成功后的提供者ID
236
+ """
237
+ pass
238
+
239
+ @abstractmethod
240
+ async def request_humanloop(
241
+ self,
242
+ task_id: str,
243
+ conversation_id: str,
244
+ loop_type: HumanLoopType,
245
+ context: Dict[str, Any],
246
+ callback: Optional[HumanLoopCallback] = None,
247
+ metadata: Optional[Dict[str, Any]] = None,
248
+ provider_id: Optional[str] = None,
249
+ timeout: Optional[int] = None,
250
+ blocking: bool = False,
251
+ ) -> Union[str, HumanLoopResult]:
252
+ """请求人机循环
253
+
254
+ Args:
255
+ task_id: 任务标识符
256
+ conversation_id: 对话ID,用于多轮对话
257
+ loop_type: 循环类型
258
+ context: 提供给人类的上下文信息
259
+ callback: 回调对象(可选)
260
+ metadata: 附加元数据
261
+ provider_id: 使用特定提供者的ID(可选)
262
+ timeout: 请求超时时间(秒)
263
+ blocking: 是否阻塞等待结果
264
+
265
+ Returns:
266
+ Union[str, HumanLoopResult]: 如果blocking=False,返回请求ID;否则返回循环结果
267
+ """
268
+ pass
269
+
270
+ @abstractmethod
271
+ async def continue_humanloop(
272
+ self,
273
+ conversation_id: str,
274
+ context: Dict[str, Any],
275
+ callback: Optional[HumanLoopCallback] = None,
276
+ metadata: Optional[Dict[str, Any]] = None,
277
+ provider_id: Optional[str] = None,
278
+ timeout: Optional[int] = None,
279
+ blocking: bool = False,
280
+ ) -> Union[str, HumanLoopResult]:
281
+ """继续人机循环
282
+
283
+ Args:
284
+ conversation_id: 对话ID,用于多轮对话
285
+ context: 提供给人类的上下文信息
286
+ callback: 回调对象(可选)
287
+ metadata: 附加元数据
288
+ provider_id: 使用特定提供者的ID(可选)
289
+ timeout: 请求超时时间(秒)
290
+ blocking: 是否阻塞等待结果
291
+
292
+ Returns:
293
+ Union[str, HumanLoopResult]: 如果blocking=False,返回请求ID;否则返回循环结果
294
+ """
295
+ pass
296
+
297
+ @abstractmethod
298
+ async def check_request_status(
299
+ self,
300
+ conversation_id: str,
301
+ request_id: str,
302
+ provider_id: Optional[str] = None
303
+ ) -> HumanLoopResult:
304
+ """检查请求状态
305
+
306
+ Args:
307
+ conversation_id: 对话标识符
308
+ request_id: 请求标识符
309
+ provider_id: 使用特定提供者的ID(可选)
310
+
311
+ Returns:
312
+ HumanLoopResult: 包含当前请求状态的结果对象
313
+ """
314
+ pass
315
+
316
+ @abstractmethod
317
+ async def check_conversation_status(
318
+ self,
319
+ conversation_id: str,
320
+ provider_id: Optional[str] = None
321
+ ) -> HumanLoopResult:
322
+ """检查对话状态
323
+
324
+ Args:
325
+ conversation_id: 对话标识符
326
+ provider_id: 使用特定提供者的ID(可选)
327
+
328
+ Returns:
329
+ HumanLoopResult: 包含对话最新请求的状态
330
+ """
331
+ pass
332
+
333
+ @abstractmethod
334
+ async def cancel_request(
335
+ self,
336
+ conversation_id: str,
337
+ request_id: str,
338
+ provider_id: Optional[str] = None
339
+ ) -> bool:
340
+ """取消特定请求
341
+
342
+ Args:
343
+ conversation_id: 对话标识符
344
+ request_id: 请求标识符
345
+ provider_id: 使用特定提供者的ID(可选)
346
+
347
+ Returns:
348
+ bool: 取消是否成功
349
+ """
350
+ pass
351
+
352
+ @abstractmethod
353
+ async def cancel_conversation(
354
+ self,
355
+ conversation_id: str,
356
+ provider_id: Optional[str] = None
357
+ ) -> bool:
358
+ """取消整个对话
359
+
360
+ Args:
361
+ conversation_id: 对话标识符
362
+ provider_id: 使用特定提供者的ID(可选)
363
+
364
+ Returns:
365
+ bool: 取消是否成功
366
+ """
367
+ pass
368
+
369
+ @abstractmethod
370
+ async def get_provider(
371
+ self,
372
+ provider_id: Optional[str] = None
373
+ ) -> HumanLoopProvider:
374
+ """获取指定的提供者实例
375
+
376
+ Args:
377
+ provider_id: 提供者ID,如果为None则返回默认提供者
378
+
379
+ Returns:
380
+ HumanLoopProvider: 提供者实例
381
+
382
+ Raises:
383
+ ValueError: 如果指定的提供者不存在
384
+ """
385
+ pass
386
+
387
+ @abstractmethod
388
+ async def list_providers(self) -> Dict[str, HumanLoopProvider]:
389
+ """列出所有注册的提供者
390
+
391
+ Returns:
392
+ Dict[str, HumanLoopProvider]: 提供者ID到提供者实例的映射
393
+ """
394
+ pass
395
+
396
+ @abstractmethod
397
+ async def set_default_provider(
398
+ self,
399
+ provider_id: str
400
+ ) -> bool:
401
+ """设置默认提供者
402
+
403
+ Args:
404
+ provider_id: 提供者ID
405
+
406
+ Returns:
407
+ bool: 设置是否成功
408
+
409
+ Raises:
410
+ ValueError: 如果指定的提供者不存在
411
+ """
412
+ pass
413
+
414
+ @abstractmethod
415
+ async def check_conversation_exist(
416
+ self,
417
+ task_id: str,
418
+ conversation_id: str,
419
+ ) -> HumanLoopResult:
420
+ """检查对话状态
421
+
422
+ Args:
423
+ conversation_id: 对话标识符
424
+ Returns:
425
+ HumanLoopResult: 包含对话最新请求的状态
426
+ """
427
+ pass
428
+
429
+ @abstractmethod
430
+ async def ashutdown(self):
431
+ """关闭管理器(异步方法)"""
432
+ pass
433
+
434
+ @abstractmethod
435
+ def shutdown(self):
436
+ """关闭管理器(同步方法)"""
437
+ pass