gohumanloop 0.0.6__py3-none-any.whl → 0.0.8__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/__init__.py +5 -0
- gohumanloop/adapters/__init__.py +6 -2
- gohumanloop/adapters/base_adapter.py +847 -0
- gohumanloop/adapters/langgraph_adapter.py +58 -691
- gohumanloop/core/interface.py +16 -5
- gohumanloop/core/manager.py +43 -1
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/METADATA +44 -5
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/RECORD +12 -11
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/WHEEL +1 -1
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/entry_points.txt +0 -0
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/licenses/LICENSE +0 -0
- {gohumanloop-0.0.6.dist-info → gohumanloop-0.0.8.dist-info}/top_level.txt +0 -0
gohumanloop/core/interface.py
CHANGED
@@ -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
|
-
) ->
|
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
|
-
|
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
|
-
) ->
|
333
|
+
) -> Any:
|
323
334
|
"""当请求发生错误时的回调
|
324
335
|
|
325
336
|
Args:
|
gohumanloop/core/manager.py
CHANGED
@@ -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(
|
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.
|
3
|
+
Version: 0.0.8
|
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
|
-
###
|
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
|
-
|
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
|
+

|
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
|
+

|
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
|
-
gohumanloop/__init__.py,sha256=
|
1
|
+
gohumanloop/__init__.py,sha256=KiY2ncM6OQvkBYcz5rsbob_GuV8hQHOARA-EsxAylEU,2134
|
2
2
|
gohumanloop/__main__.py,sha256=zdGKN92H9SgwZfL4xLqPkE1YaiRcHhVg_GqC-H1VurA,75
|
3
|
-
gohumanloop/adapters/__init__.py,sha256=
|
4
|
-
gohumanloop/adapters/
|
3
|
+
gohumanloop/adapters/__init__.py,sha256=_XqJ6eaUBLJJJyjfBQJykBZ4X9HvC3VYOVTn2KnBlqo,484
|
4
|
+
gohumanloop/adapters/base_adapter.py,sha256=snKd2GWE5SuFxqkNwdwS8YAhQzhMs9fpeOG6hT6VRhc,32600
|
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=
|
9
|
-
gohumanloop/core/manager.py,sha256=
|
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.
|
26
|
-
gohumanloop-0.0.
|
27
|
-
gohumanloop-0.0.
|
28
|
-
gohumanloop-0.0.
|
29
|
-
gohumanloop-0.0.
|
30
|
-
gohumanloop-0.0.
|
26
|
+
gohumanloop-0.0.8.dist-info/licenses/LICENSE,sha256=-U5tuCcSpndQwSKWtZbFbazb-_AtZcZL2kQgHbSLg-M,1064
|
27
|
+
gohumanloop-0.0.8.dist-info/METADATA,sha256=FvrBF4EDkQXWzC2Jg7A43zdvPPsdpR2BN035wgTMxOo,11216
|
28
|
+
gohumanloop-0.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
29
|
+
gohumanloop-0.0.8.dist-info/entry_points.txt,sha256=wM6jqRRD8bQXkvIduRVCuAJIlbyWg_F5EDXo5OZ_PwY,88
|
30
|
+
gohumanloop-0.0.8.dist-info/top_level.txt,sha256=LvOXBqS6Mspmcuqp81uz0Vjx_m_YI0w06DOPCiI1BfY,12
|
31
|
+
gohumanloop-0.0.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|