gohumanloop 0.0.6__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.
@@ -292,10 +292,22 @@ class HumanLoopProvider(Protocol):
292
292
  class HumanLoopCallback(ABC):
293
293
  """人机循环回调的抽象类"""
294
294
 
295
+ @abstractmethod
296
+ async def async_on_humanloop_request(
297
+ self, provider: HumanLoopProvider, request: HumanLoopRequest
298
+ ) -> Any:
299
+ """当人机循环请求开始时的回调
300
+
301
+ Args:
302
+ provider: 人机循环提供者实例
303
+ request: 循环请求
304
+ """
305
+ pass
306
+
295
307
  @abstractmethod
296
308
  async def async_on_humanloop_update(
297
309
  self, provider: HumanLoopProvider, result: HumanLoopResult
298
- ) -> None:
310
+ ) -> Any:
299
311
  """当请求更新时的回调
300
312
 
301
313
  Args:
@@ -306,9 +318,8 @@ class HumanLoopCallback(ABC):
306
318
 
307
319
  @abstractmethod
308
320
  async def async_on_humanloop_timeout(
309
- self,
310
- provider: HumanLoopProvider,
311
- ) -> None:
321
+ self, provider: HumanLoopProvider, result: HumanLoopResult
322
+ ) -> Any:
312
323
  """当请求超时时的回调
313
324
 
314
325
  Args:
@@ -319,7 +330,7 @@ class HumanLoopCallback(ABC):
319
330
  @abstractmethod
320
331
  async def async_on_humanloop_error(
321
332
  self, provider: HumanLoopProvider, error: Exception
322
- ) -> None:
333
+ ) -> Any:
323
334
  """当请求发生错误时的回调
324
335
 
325
336
  Args:
@@ -1,8 +1,10 @@
1
1
  from typing import Dict, Any, Optional, List, Union
2
2
  import asyncio
3
+ from datetime import datetime
3
4
  from gohumanloop.utils import run_async_safely
4
5
 
5
6
  from gohumanloop.core.interface import (
7
+ HumanLoopRequest,
6
8
  HumanLoopManager,
7
9
  HumanLoopProvider,
8
10
  HumanLoopCallback,
@@ -147,6 +149,25 @@ class DefaultHumanLoopManager(HumanLoopManager):
147
149
 
148
150
  # 如果提供了回调,存储它
149
151
  if callback:
152
+ try:
153
+ # 创建请求对象
154
+ request = HumanLoopRequest(
155
+ task_id=task_id,
156
+ conversation_id=conversation_id,
157
+ loop_type=loop_type,
158
+ context=context,
159
+ metadata=metadata or {},
160
+ timeout=timeout,
161
+ created_at=datetime.now(),
162
+ )
163
+ await callback.async_on_humanloop_request(provider, request)
164
+ except Exception as e:
165
+ # 处理回调执行过程中的异常
166
+ try:
167
+ await callback.async_on_humanloop_error(provider, e)
168
+ except Exception:
169
+ # 如果错误回调也失败,只能忽略
170
+ pass
150
171
  self._callbacks[(conversation_id, request_id)] = callback
151
172
 
152
173
  # 如果设置了超时,创建超时任务
@@ -266,6 +287,25 @@ class DefaultHumanLoopManager(HumanLoopManager):
266
287
 
267
288
  # 如果提供了回调,存储它
268
289
  if callback:
290
+ try:
291
+ # 创建请求对象
292
+ request = HumanLoopRequest(
293
+ task_id=task_id or "",
294
+ conversation_id=conversation_id,
295
+ loop_type=HumanLoopType.CONVERSATION,
296
+ context=context,
297
+ metadata=metadata or {},
298
+ timeout=timeout,
299
+ created_at=datetime.now(),
300
+ )
301
+ await callback.async_on_humanloop_request(provider, request)
302
+ except Exception as e:
303
+ # 处理回调执行过程中的异常
304
+ try:
305
+ await callback.async_on_humanloop_error(provider, e)
306
+ except Exception:
307
+ # 如果错误回调也失败,只能忽略
308
+ pass
269
309
  self._callbacks[(conversation_id, request_id)] = callback
270
310
 
271
311
  # 如果设置了超时,创建超时任务
@@ -613,7 +653,9 @@ class DefaultHumanLoopManager(HumanLoopManager):
613
653
  # INPROGRESS状态表示对话正在进行中,不应视为超时
614
654
  if result.status == HumanLoopStatus.PENDING:
615
655
  if callback:
616
- await callback.async_on_humanloop_timeout(provider=provider)
656
+ await callback.async_on_humanloop_timeout(
657
+ provider=provider, result=result
658
+ )
617
659
  # 如果状态是INPROGRESS,重置超时任务
618
660
  elif result.status == HumanLoopStatus.INPROGRESS:
619
661
  # 对于进行中的对话,我们可以选择延长超时时间
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gohumanloop
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Summary: Perfecting AI workflows with human intelligence
5
5
  Author-email: gohumanloop authors <baird0917@163.com>
6
6
  Project-URL: repository, https://github.com/ptonlix/gohumanloop
@@ -19,6 +19,8 @@ Requires-Dist: langgraph>=0.3.30; extra == "langgraph"
19
19
  Provides-Extra: apiservices
20
20
  Requires-Dist: fastapi>=0.115.12; extra == "apiservices"
21
21
  Requires-Dist: uvicorn>=0.34.2; extra == "apiservices"
22
+ Provides-Extra: agentops
23
+ Requires-Dist: agentops>=0.4.12; extra == "agentops"
22
24
  Dynamic: license-file
23
25
 
24
26
  <div align="center">
@@ -61,17 +63,15 @@ To get started, check out the following example or jump straight into one of the
61
63
 
62
64
  - 🦜⛓️ [LangGraph](./examples/langgraph/)
63
65
 
64
- ### Example
66
+ ### Installation
65
67
 
66
68
  **GoHumanLoop** currently supports `Python`.
67
69
 
68
- - Installation
69
-
70
70
  ```shell
71
71
  pip install gohumanloop
72
72
  ```
73
73
 
74
- - Example
74
+ ### Example
75
75
 
76
76
  The following example enhances [the official LangGraph example](https://langchain-ai.github.io/langgraph/tutorials/get-started/4-human-in-the-loop/#5-resume-execution) with `human-in-the-loop` functionality.
77
77
 
@@ -95,7 +95,9 @@ from langgraph.prebuilt import ToolNode, tools_condition
95
95
 
96
96
  from gohumanloop.adapters.langgraph_adapter import interrupt, create_resume_command
97
97
 
98
+ # Please replace with your Deepseek API Key from https://platform.deepseek.com/usage
98
99
  os.environ["DEEPSEEK_API_KEY"] = "sk-xxx"
100
+ # Please replace with your Tavily API Key from https://app.tavily.com/home
99
101
  os.environ["TAVILY_API_KEY"] = "tvly-xxx"
100
102
 
101
103
  llm = init_chat_model("deepseek:deepseek-chat")
@@ -169,6 +171,43 @@ for event in events:
169
171
 
170
172
  ```
171
173
 
174
+ - Deployment & Test
175
+
176
+ Run the above code with the following steps:
177
+
178
+ ```shell
179
+ # 1.Initialize environment
180
+ uv init gohumanloop-example
181
+ cd gohumanloop-example
182
+ uv venv .venv --python=3.10
183
+
184
+ # 2.Copy the above code to main.py
185
+
186
+ # 3.Deploy and test
187
+ uv pip install langchain
188
+ uv pip install langchain_tavily
189
+ uv pip install langgraph
190
+ uv pip install langchain-deepseek
191
+ uv pip install gohumanloop
192
+
193
+ python main.py
194
+
195
+ ```
196
+
197
+ - Interaction Demo
198
+
199
+ ![终端展示](http://cdn.oyster-iot.cloud/202505232244870.png)
200
+
201
+ Perform `human-in-the-loop` interaction by entering:
202
+
203
+ > We, the experts are here to help! We'd recommend you check out LangGraph to build your agent.It's much more reliable and extensible than simple autonomous agents.
204
+
205
+ ![输出结果](http://cdn.oyster-iot.cloud/202505232248390.png)
206
+
207
+ 🚀🚀🚀 Completed successfully ~
208
+
209
+ ➡️ Check out more examples in the [Examples Directory](./examples/) and we look foward to your contributions!
210
+
172
211
  ## 🎵 Why GoHumanloop?
173
212
 
174
213
  ### Human-in-the-loop
@@ -1,12 +1,13 @@
1
1
  gohumanloop/__init__.py,sha256=oJqVOtRRDHNxwxZ2Blw7ycBRwcTBMTURUCx-XcL2YJ0,1969
2
2
  gohumanloop/__main__.py,sha256=zdGKN92H9SgwZfL4xLqPkE1YaiRcHhVg_GqC-H1VurA,75
3
- gohumanloop/adapters/__init__.py,sha256=cFXd9qzyR0oZg8mR912PShj2b_3BAM_RO_cIVMXVdWQ,390
4
- gohumanloop/adapters/langgraph_adapter.py,sha256=il_zsQMdgbJrwIn_ucQiH1ku3JhozxIQ7RH82KqTLwA,36750
3
+ gohumanloop/adapters/__init__.py,sha256=GTEonjk1NogjtUVtgiLWciWR_e9-PbAlZfQUdA8paik,390
4
+ gohumanloop/adapters/base_adapter.py,sha256=LTnjVnownYqJCQQeD3V53STEOvIm9n9cNYPaENULMJQ,32244
5
+ gohumanloop/adapters/langgraph_adapter.py,sha256=AHJv_b6g8xjeq_9X2cGiW76pSGlfgCGBUvjrZQcbR9s,11621
5
6
  gohumanloop/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
7
  gohumanloop/cli/main.py,sha256=Txjk31MlkiX9zeHZfFEXEu0s2IBESY8sxrxBEzZKk2U,767
7
8
  gohumanloop/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- gohumanloop/core/interface.py,sha256=D59FR4Bj-7gCFXw_55pPcFBjG2bY-EI5sYZl46tBaB0,21476
9
- gohumanloop/core/manager.py,sha256=xyJJItJvt5ZPudAa3kWy282jn-I5yCsLJYNPaJyIQLI,29906
9
+ gohumanloop/core/interface.py,sha256=uzV3xG08DDItgB9TgMvskcKVDSIFTx2qv8HXjVBtJcI,21810
10
+ gohumanloop/core/manager.py,sha256=imeDVuQlyBRyVR5-PFwxNaFQYaZaAQ69ZGtmsiUpUDg,31790
10
11
  gohumanloop/manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
12
  gohumanloop/manager/ghl_manager.py,sha256=rmbfaS5mAb9c8RPr9Id24vO5DJT9ZC4D282dHZ26SJE,22695
12
13
  gohumanloop/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -22,9 +23,9 @@ gohumanloop/utils/__init__.py,sha256=l0e3lnOVrt6HwaxidNGFXORX4awCKemhJZ_t3k-5u-s
22
23
  gohumanloop/utils/context_formatter.py,sha256=sAWrKJpxmsHga6gsyBwFBlAsHW8bjR1hkaGhk1PoE1M,2064
23
24
  gohumanloop/utils/threadsafedict.py,sha256=9uyewnwmvS3u1fCx3SK0YWFxHMcyIwlye1Ev7WW7WHA,9588
24
25
  gohumanloop/utils/utils.py,sha256=-bti65OaVh5dlvc5BIgiTw6dqxmqdKnOQHE0V-LKjek,2107
25
- gohumanloop-0.0.6.dist-info/licenses/LICENSE,sha256=-U5tuCcSpndQwSKWtZbFbazb-_AtZcZL2kQgHbSLg-M,1064
26
- gohumanloop-0.0.6.dist-info/METADATA,sha256=waWXbFIFOXC9loVTl4OJUTB-UbjSae_TZcXLIrMek8k,10057
27
- gohumanloop-0.0.6.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
28
- gohumanloop-0.0.6.dist-info/entry_points.txt,sha256=wM6jqRRD8bQXkvIduRVCuAJIlbyWg_F5EDXo5OZ_PwY,88
29
- gohumanloop-0.0.6.dist-info/top_level.txt,sha256=LvOXBqS6Mspmcuqp81uz0Vjx_m_YI0w06DOPCiI1BfY,12
30
- gohumanloop-0.0.6.dist-info/RECORD,,
26
+ gohumanloop-0.0.7.dist-info/licenses/LICENSE,sha256=-U5tuCcSpndQwSKWtZbFbazb-_AtZcZL2kQgHbSLg-M,1064
27
+ gohumanloop-0.0.7.dist-info/METADATA,sha256=3TYk0bxxF9ynRetWwdi_IOlmjb30W1ZI4yTxzpv69WI,11216
28
+ gohumanloop-0.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
+ gohumanloop-0.0.7.dist-info/entry_points.txt,sha256=wM6jqRRD8bQXkvIduRVCuAJIlbyWg_F5EDXo5OZ_PwY,88
30
+ gohumanloop-0.0.7.dist-info/top_level.txt,sha256=LvOXBqS6Mspmcuqp81uz0Vjx_m_YI0w06DOPCiI1BfY,12
31
+ gohumanloop-0.0.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5