langchain-agentx-python 2.4.4__py3-none-any.whl → 2.4.5__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.
@@ -11,7 +11,7 @@ from langchain_agentx import create_loop_agent
11
11
  ```
12
12
  """
13
13
 
14
- __version__ = "2.4.4"
14
+ __version__ = "2.4.5"
15
15
 
16
16
  from .mcp.call import McpToolCaller
17
17
  from .mcp.client_manager import McpClientManager, McpConnectedClient
@@ -18,6 +18,7 @@ registry.py — HookRegistry 用户侧入口。
18
18
  from __future__ import annotations
19
19
 
20
20
  import copy
21
+ import types
21
22
  from dataclasses import replace
22
23
  from typing import Any, Callable
23
24
  from uuid import uuid4
@@ -25,6 +26,51 @@ from uuid import uuid4
25
26
  from .config import HookSpec, HooksConfigSnapshot
26
27
  from .types import HookEvent
27
28
 
29
+ # fresh_state 克隆时,同一父实例上的多个 bound method 共用一个克隆 self
30
+ _CallableSelfCloneMap = dict[int, Any]
31
+
32
+
33
+ def _clone_hook_callable(
34
+ fn: Any,
35
+ *,
36
+ self_clones: _CallableSelfCloneMap,
37
+ ) -> Any:
38
+ """克隆 hook 回调;bound method 按 ``id(__self__)`` 去重,再绑到同一克隆实例。"""
39
+ self_obj = getattr(fn, "__self__", None)
40
+ func = getattr(fn, "__func__", None)
41
+ if self_obj is None or func is None or isinstance(self_obj, type):
42
+ # 普通函数 / 静态 / 类方法:保持 deepcopy 语义(通常仍是同一对象)
43
+ try:
44
+ return copy.deepcopy(fn)
45
+ except Exception:
46
+ return fn
47
+
48
+ key = id(self_obj)
49
+ if key not in self_clones:
50
+ self_clones[key] = copy.deepcopy(self_obj)
51
+ cloned_self = self_clones[key]
52
+ name = getattr(func, "__name__", None)
53
+ if isinstance(name, str) and name and hasattr(cloned_self, name):
54
+ rebound = getattr(cloned_self, name)
55
+ if callable(rebound) and getattr(rebound, "__self__", None) is cloned_self:
56
+ return rebound
57
+ return types.MethodType(func, cloned_self)
58
+
59
+
60
+ def _clone_hook_config_fresh(
61
+ config: dict[str, Any],
62
+ *,
63
+ self_clones: _CallableSelfCloneMap,
64
+ ) -> dict[str, Any]:
65
+ """逐键深拷;``fn``/``callback`` 走 bound-method 去重克隆。"""
66
+ cloned: dict[str, Any] = {}
67
+ for key, value in config.items():
68
+ if key in ("fn", "callback") and callable(value):
69
+ cloned[key] = _clone_hook_callable(value, self_clones=self_clones)
70
+ else:
71
+ cloned[key] = copy.deepcopy(value)
72
+ return cloned
73
+
28
74
 
29
75
  # ── 任务完成 Hook 类型定义 ────────────────────────────────────────
30
76
 
@@ -326,13 +372,19 @@ class HookRegistry:
326
372
  *,
327
373
  fresh_state: bool = True,
328
374
  ) -> HookRegistry:
329
- """过滤 clone 父 registry specs 到子 loop(LOCK-2;fresh_state 预留计数器隔离扩展)。"""
375
+ """过滤 clone 父 registry specs 到子 loop(LOCK-2)。
376
+
377
+ ``fresh_state=True``:可变 config 深拷,且同一父实例上的 bound method
378
+ (PRE/POST/…)共用**一份**克隆 ``__self__``——子会话相对父隔离,
379
+ 子会话内跨事件状态机仍共享(见 bug hook-fork-bound-method-deepcopy-splits-state)。
380
+ """
330
381
  child = HookRegistry()
382
+ self_clones: _CallableSelfCloneMap = {}
331
383
  for spec in self._specs:
332
384
  if spec.event not in inherited_events:
333
385
  continue
334
386
  if fresh_state:
335
- config = copy.deepcopy(spec.config)
387
+ config = _clone_hook_config_fresh(spec.config, self_clones=self_clones)
336
388
  else:
337
389
  config = dict(spec.config)
338
390
  cloned = replace(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-agentx-python
3
- Version: 2.4.4
3
+ Version: 2.4.5
4
4
  Summary: LangChain/LangGraph-based agent utilities for CodeBaseX.
5
5
  Author-email: GoodMood2008 <GoodMood2008@users.noreply.github.com>
6
6
  License: Apache License
@@ -1,4 +1,4 @@
1
- langchain_agentx/__init__.py,sha256=gX9uh5HhQBKt0DLInVlFKZmLGU6UFTHBPQmjVNSMRKo,2014
1
+ langchain_agentx/__init__.py,sha256=pZsAuwiCt4PE3SIZy-8M2i69KqjY9ZHafj9Y8CUjpmA,2014
2
2
  langchain_agentx/command/__init__.py,sha256=Ej260S5uFQcmEtGZQG_NH7BYjHoStrpBLtGUsBTxyZk,631
3
3
  langchain_agentx/command/allowed_tools.py,sha256=TVA0VM8rm98H-QbLK_GRiX5RhEAZFxKawliMi4kk96A,3359
4
4
  langchain_agentx/command/context.py,sha256=DIGOGPBw5UGDBm0WNNJlKx1h_9rCRmcdROv4DT61Qug,731
@@ -83,7 +83,7 @@ langchain_agentx/loop/hook/engine.py,sha256=s18KUN1QY0eC5T01mG8yO2lNxLg-GDa8ZhIX
83
83
  langchain_agentx/loop/hook/graph_wiring.py,sha256=EvntU0VsqX-VIp9yQnKI3Qnz2-Scd-5-GviHh7xoZ1s,8769
84
84
  langchain_agentx/loop/hook/hook_projection.py,sha256=B2PgU2YPx6Mnpdpcac6g_8SlkmR1bllNNPIn8jp2hyU,5966
85
85
  langchain_agentx/loop/hook/progress_payload.py,sha256=bbNUEguw_cYbI3l0RJZ4VAtfgaRhD0jqwk3eE5AzgCE,4532
86
- langchain_agentx/loop/hook/registry.py,sha256=aL7v0--v_YPYBVlRbGUr76rSSswMAyHgr8AVHk0ho74,13350
86
+ langchain_agentx/loop/hook/registry.py,sha256=tRuVbwUsO7ELwmigJNkgcxczF1toOy27tavUhzczyoI,15348
87
87
  langchain_agentx/loop/hook/trust.py,sha256=4RlzQkleRO3xU1N4dZ5mPHgejDn_Xar2jOhwkLWKn4A,1236
88
88
  langchain_agentx/loop/hook/types.py,sha256=tkI5R5KwsUNBczJ9we3dRa7gbqNmOar6k4BQyXGqiGs,5510
89
89
  langchain_agentx/loop/hook/executors/__init__.py,sha256=rzRQ0_8-G1IUqNFMEVxAq7YTvvq2zTlZGENRabeU4_c,258
@@ -839,8 +839,8 @@ langchain_agentx/workspace/root_grant_manager.py,sha256=W3gy8HTevbERbXqIgRcjzOXO
839
839
  langchain_agentx/workspace/tool_boundary.py,sha256=UDwX6swpSLsx9HNkYuuRRiV5o7ZZG_Bru2Yn0c5kNX8,5724
840
840
  langchain_agentx/workspace/validators.py,sha256=tQt-6TOcL8Fw7Ig5ebA9S7vGWh1rby920eFW6x8Tk9E,1439
841
841
  langchain_agentx/workspace/view.py,sha256=PGasqTaqhlD03SXXazHuw4RHfV681AIdlsYqL70pEjc,4774
842
- langchain_agentx_python-2.4.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
843
- langchain_agentx_python-2.4.4.dist-info/METADATA,sha256=yKso1obM03vdYTdmgAAiSaPpXk2sVBOUFq8_CzLm9MQ,23971
844
- langchain_agentx_python-2.4.4.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
845
- langchain_agentx_python-2.4.4.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
846
- langchain_agentx_python-2.4.4.dist-info/RECORD,,
842
+ langchain_agentx_python-2.4.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
843
+ langchain_agentx_python-2.4.5.dist-info/METADATA,sha256=aK5l6-y3n1a8k25zAxJ8vlWQYMaMDiCH8ReZj9Faka8,23971
844
+ langchain_agentx_python-2.4.5.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
845
+ langchain_agentx_python-2.4.5.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
846
+ langchain_agentx_python-2.4.5.dist-info/RECORD,,