langchain-agentx-python 2.2.0__py3-none-any.whl → 2.2.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.
@@ -11,7 +11,7 @@ from langchain_agentx import create_loop_agent
11
11
  ```
12
12
  """
13
13
 
14
- __version__ = "2.2.0"
14
+ __version__ = "2.2.2"
15
15
 
16
16
  from .loop import ( # noqa: F401
17
17
  create_loop_agent,
@@ -51,6 +51,12 @@ from langchain_agentx.observability.events.agent_defaults import DEFAULT_AGENT_T
51
51
  from langchain_agentx.observability.events.subagent_window_text_guard import (
52
52
  SubagentWindowTextGuard,
53
53
  )
54
+ from langchain_agentx.observability.events.compact_event_gate import (
55
+ beneficial_light_stage_names,
56
+ extract_compaction_meta_from_chain_end_data,
57
+ is_user_visible_compact,
58
+ light_only_with_benefit,
59
+ )
54
60
  from langchain_agentx.observability.events.tool_call_id_resolver import (
55
61
  ToolCallIdResolver,
56
62
  )
@@ -121,8 +127,7 @@ class LangchainAgentEventType(Enum):
121
127
  FINISH_STEP = "finish-step"
122
128
  HOOK_PROGRESS = "hook-progress"
123
129
  HOOK_FINISHED = "hook-finished"
124
- COMPACT_START = "compact-start"
125
- COMPACT_END = "compact-end"
130
+ COMPACT_BOUNDARY = "compact-boundary"
126
131
  MEMORY_SAVED = "memory-saved"
127
132
  SUBAGENT_START = "subagent-start"
128
133
  SUBAGENT_END = "subagent-end"
@@ -396,12 +401,7 @@ class AgentEventProjector:
396
401
  step_index=self.state.step_index or None,
397
402
  )
398
403
 
399
- if self.enable_compact_events and self._is_compact_node(name):
400
- yield self._event(
401
- event_type=LangchainAgentEventType.COMPACT_START,
402
- data={},
403
- step_index=self.state.step_index or None,
404
- )
404
+ # D-CMP-EVT:不在 start 发 compact(CC 无 start/end;事后单边界)
405
405
 
406
406
  def _build_loop_observation_payload(self) -> Dict[str, Any]:
407
407
  snap = self.state.last_loop_snapshot or {}
@@ -752,7 +752,6 @@ class AgentEventProjector:
752
752
  result["tokens_freed"] = meta.get("tokens_freed_sum")
753
753
 
754
754
  stages = meta.get("stages")
755
- autocompact_found = False
756
755
  microcompact_found = False
757
756
 
758
757
  if isinstance(stages, list):
@@ -761,7 +760,6 @@ class AgentEventProjector:
761
760
  name = s.get("name")
762
761
  extra = s.get("extra") or {}
763
762
  if name == "autocompact":
764
- autocompact_found = True
765
763
  result["autocompact_mode"] = extra.get("autocompact_mode")
766
764
  result["folded_messages"] = extra.get("folded_messages")
767
765
  result["messages_summarized"] = extra.get("folded_messages")
@@ -782,10 +780,12 @@ class AgentEventProjector:
782
780
  break
783
781
 
784
782
  if "compact_type" not in result:
785
- if autocompact_found or not microcompact_found:
783
+ mode = result.get("autocompact_mode")
784
+ if isinstance(mode, str) and mode:
786
785
  result["compact_type"] = "autocompact"
787
- else:
786
+ elif microcompact_found:
788
787
  result["compact_type"] = "microcompact"
788
+ # 不再用「stages 出现过 autocompact 名」回落为 autocompact(假阳性)
789
789
 
790
790
  if "summary" not in result:
791
791
  messages = output.get("messages")
@@ -848,13 +848,30 @@ class AgentEventProjector:
848
848
  step_index=self.state.step_index or None,
849
849
  )
850
850
 
851
- if self.enable_compact_events and self._is_compact_node(name):
852
- compact_data = self._extract_compact_summary(data)
853
- yield self._event(
854
- event_type=LangchainAgentEventType.COMPACT_END,
855
- data=compact_data,
856
- step_index=self.state.step_index or None,
857
- )
851
+ if self._is_compact_node(name):
852
+ meta = extract_compaction_meta_from_chain_end_data(data)
853
+ if is_user_visible_compact(meta):
854
+ if self.enable_compact_events:
855
+ compact_data = self._extract_compact_summary(data)
856
+ if "trigger" not in compact_data:
857
+ compact_data["trigger"] = "auto"
858
+ yield self._event(
859
+ event_type=LangchainAgentEventType.COMPACT_BOUNDARY,
860
+ data=compact_data,
861
+ step_index=self.state.step_index or None,
862
+ )
863
+ elif light_only_with_benefit(meta):
864
+ # D-CMP-EVT-7:对齐 CC logForDebugging;不受 enable_compact_events 关闭影响
865
+ freed = None
866
+ if isinstance(meta, dict):
867
+ freed = meta.get("tokens_freed_sum")
868
+ stages = beneficial_light_stage_names(meta)
869
+ logger.debug(
870
+ "compact light-only: tokens_freed_sum=%s stages=%s "
871
+ "(no public compact-boundary; align CC logForDebugging)",
872
+ freed,
873
+ stages or None,
874
+ )
858
875
 
859
876
  if name == self.state.graph_name:
860
877
  if self.enable_reasoning_events and self.state.is_reasoning_active:
@@ -0,0 +1,152 @@
1
+ """
2
+ compact_event_gate.py — compact 公共事件门闩(对齐 CC compact_boundary)
3
+
4
+ 职责:
5
+ - 从 compaction_pipeline_meta 判定是否用户可见真压缩 / light-only 有收益
6
+ - 供 agent_event_projector 发射 compact-boundary 或 logger.debug
7
+
8
+ 链路位置:
9
+ - Layer 3: observability/events 投影门闩(不改 L0 压缩流水线)
10
+
11
+ 当前裁剪范围:
12
+ - 仅 meta 谓词;不创建 SSE 以外的事件类型
13
+ - session_memory applied 仅识别显式标记(字段可后续扩展)
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any, Optional
19
+
20
+ from langchain_agentx.loop.exit.query_source import QuerySource
21
+
22
+ # 实际折叠上下文的 autocompact_mode(不含仅 skipped)
23
+ APPLIED_AUTOCOMPACT_MODES: frozenset[str] = frozenset(
24
+ {
25
+ "llm",
26
+ "prune",
27
+ "prune_blocked_llm",
28
+ }
29
+ )
30
+
31
+ _LIGHT_STAGE_NAMES: frozenset[str] = frozenset(
32
+ {
33
+ "tool_result_budget",
34
+ "snip",
35
+ "microcompact",
36
+ "collapse",
37
+ }
38
+ )
39
+
40
+
41
+ def _as_dict(meta: Any) -> Optional[dict[str, Any]]:
42
+ return meta if isinstance(meta, dict) else None
43
+
44
+
45
+ def _stage_extra(stage: dict[str, Any]) -> dict[str, Any]:
46
+ extra = stage.get("extra")
47
+ return extra if isinstance(extra, dict) else {}
48
+
49
+
50
+ def _positive_number(value: Any) -> bool:
51
+ if value is None:
52
+ return False
53
+ try:
54
+ return float(value) > 0
55
+ except (TypeError, ValueError):
56
+ return False
57
+
58
+
59
+ def is_user_visible_compact(meta: Any) -> bool:
60
+ """真压缩已应用 → 应对齐 CC 发一条 compact-boundary。
61
+
62
+ 禁止用 tokens_freed_sum / stages 仅出现 autocompact 名 / compact_type 回落判定。
63
+ """
64
+ m = _as_dict(meta)
65
+ if m is None:
66
+ return False
67
+
68
+ # Session / 手动:L0 现网键(factory session_memory 路径无 stages[])
69
+ if m.get("session_memory_compact_applied") is True:
70
+ return True
71
+ if m.get("manual_compact_applied") is True:
72
+ return True
73
+ if m.get("session_memory_compaction") == "applied":
74
+ return True
75
+ if m.get("autocompact_mode") == QuerySource.SESSION_MEMORY:
76
+ return True
77
+
78
+ stages = m.get("stages")
79
+ if not isinstance(stages, list):
80
+ return False
81
+
82
+ for stage in stages:
83
+ if not isinstance(stage, dict):
84
+ continue
85
+ name = stage.get("name")
86
+ extra = _stage_extra(stage)
87
+ if name == "autocompact":
88
+ mode = extra.get("autocompact_mode")
89
+ if isinstance(mode, str) and mode in APPLIED_AUTOCOMPACT_MODES:
90
+ return True
91
+ if name == QuerySource.SESSION_MEMORY and extra.get("applied") is True:
92
+ return True
93
+ return False
94
+
95
+
96
+ def light_only_with_benefit(meta: Any) -> bool:
97
+ """非用户可见,但有轻量 stage(或 sum)释放 token → 应对齐 CC logForDebugging。"""
98
+ if is_user_visible_compact(meta):
99
+ return False
100
+ m = _as_dict(meta)
101
+ if m is None:
102
+ return False
103
+
104
+ stages = m.get("stages")
105
+ if isinstance(stages, list):
106
+ for stage in stages:
107
+ if not isinstance(stage, dict):
108
+ continue
109
+ if _positive_number(stage.get("tokens_freed")):
110
+ return True
111
+ # micro 规范化标记但 tokens 估计可能为 0:仍视为有 light 动作时可记
112
+ name = stage.get("name")
113
+ extra = _stage_extra(stage)
114
+ if name == "microcompact" and extra.get("microcompact_normalized"):
115
+ return True
116
+
117
+ return _positive_number(m.get("tokens_freed_sum"))
118
+
119
+
120
+ def beneficial_light_stage_names(meta: Any) -> list[str]:
121
+ """有收益的轻量 stage 名(供 debug 文案)。"""
122
+ m = _as_dict(meta)
123
+ if m is None:
124
+ return []
125
+ names: list[str] = []
126
+ stages = m.get("stages")
127
+ if not isinstance(stages, list):
128
+ return names
129
+ for stage in stages:
130
+ if not isinstance(stage, dict):
131
+ continue
132
+ name = stage.get("name")
133
+ if not isinstance(name, str):
134
+ continue
135
+ extra = _stage_extra(stage)
136
+ freed = _positive_number(stage.get("tokens_freed"))
137
+ micro = name == "microcompact" and bool(extra.get("microcompact_normalized"))
138
+ if freed or micro:
139
+ if name in _LIGHT_STAGE_NAMES or freed or micro:
140
+ names.append(name)
141
+ return names
142
+
143
+
144
+ def extract_compaction_meta_from_chain_end_data(data: Any) -> Optional[dict[str, Any]]:
145
+ """从 on_chain_end data 取出 compaction_pipeline_meta。"""
146
+ if not isinstance(data, dict):
147
+ return None
148
+ output = data.get("output")
149
+ if not isinstance(output, dict):
150
+ return None
151
+ meta = output.get("compaction_pipeline_meta")
152
+ return meta if isinstance(meta, dict) else None
@@ -3,8 +3,8 @@ scope_resolver.py — Workflow event adapter active scope 解析
3
3
 
4
4
  职责:
5
5
  - 根据 WorkflowStack.build_path() 从 flat scopes[path] registry 解析当前 active scope
6
- - public orphan path miss hard-fail
7
- - internal 尾段 path miss 时 warn + registered ancestor 回退(A00 P-LOSSY / P-EXEC
6
+ - miss 时按 D-SCOPE-A′ 降级到最近非 root / 非 workflow_root 已注册祖先
7
+ - 无非 root 祖先时 hard-fail(禁 blanket root
8
8
 
9
9
  链路位置:
10
10
  - Layer 3: Workflow 事件适配器
@@ -14,18 +14,18 @@ scope_resolver.py — Workflow event adapter active scope 解析
14
14
  - 仅 dict lookup,不扫描 workflow 实例或 graph
15
15
  - scope key 与 WorkflowStack.build_path() / RuntimeScopePath.key() 一致
16
16
  - legacy config 无 scopes 时由 root 字段合成仅含 root 的 registry
17
- - 禁止 blanket root 兜底;无 registered 祖先时仍 raise
17
+ - 禁止把 root degrade 目标;与 SessionRouter 共享 nearest_degrade_ancestor
18
18
  """
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
22
  import logging
23
+ from collections.abc import Callable
23
24
  from typing import Any
24
25
 
25
26
  from langchain_agentx.workflow.runtime_scope_registry import resolve_effective_scopes
26
27
  from langchain_agentx.workflow.structure_errors import WorkflowScopeResolutionError
27
28
 
28
- from .depth_resolver import LANGGRAPH_INTERNAL_LOOP_NODE_NAMES
29
29
  from .stack import WorkflowStack
30
30
 
31
31
  logger = logging.getLogger(__name__)
@@ -34,9 +34,30 @@ _SCOPE_METADATA_FIELDS = frozenset(
34
34
  {"workflow_id", "scope_key", "scope_kind", "scope_origin", "graph_key"}
35
35
  )
36
36
 
37
+ ScopeLookup = Callable[[str], dict[str, Any] | None]
37
38
 
38
- def _path_tail_segment(scope_key: str) -> str:
39
- return scope_key.rsplit(">", 1)[-1]
39
+
40
+ def nearest_degrade_ancestor(
41
+ path: str,
42
+ *,
43
+ root_scope: str,
44
+ lookup: ScopeLookup,
45
+ ) -> dict[str, Any] | None:
46
+ """沿 '>' 前缀向上;跳过 root_scope / workflow_root(D-SCOPE-A′ · 禁 blanket root)。"""
47
+ if ">" not in path:
48
+ return None
49
+ parts = path.split(">")
50
+ for depth in range(len(parts) - 1, 0, -1):
51
+ prefix = ">".join(parts[:depth])
52
+ if prefix == root_scope:
53
+ continue
54
+ entry = lookup(prefix)
55
+ if entry is None:
56
+ continue
57
+ if entry.get("scope_kind") == "workflow_root":
58
+ continue
59
+ return entry
60
+ return None
40
61
 
41
62
 
42
63
  class WorkflowScopeResolver:
@@ -51,6 +72,12 @@ class WorkflowScopeResolver:
51
72
  root_scope=self._root_scope,
52
73
  )
53
74
  self._scope_misses: list[str] = []
75
+ self._degrade_warned_paths: set[str] = set()
76
+
77
+ @property
78
+ def root_scope(self) -> str:
79
+ """开流 root_scope(SessionRouter 祖先 walk 唯一来源)。"""
80
+ return self._root_scope
54
81
 
55
82
  @property
56
83
  def scope_misses(self) -> tuple[str, ...]:
@@ -81,16 +108,13 @@ class WorkflowScopeResolver:
81
108
 
82
109
  self._record_scope_miss(scope_key)
83
110
 
84
- if not self._is_internal_path_miss(scope_key):
85
- raise self._build_scope_resolution_error(scope_key)
86
-
87
- ancestor = self._nearest_registered_ancestor_entry()
111
+ ancestor = nearest_degrade_ancestor(
112
+ scope_key,
113
+ root_scope=self._root_scope,
114
+ lookup=self.scope_entry_at,
115
+ )
88
116
  if ancestor is not None:
89
- logger.warning(
90
- "workflow scope miss degraded to ancestor: path=%r ancestor=%r",
91
- scope_key,
92
- ancestor.get("scope_key"),
93
- )
117
+ self._warn_degraded_once(scope_key, ancestor)
94
118
  return ancestor
95
119
 
96
120
  raise self._build_scope_resolution_error(scope_key)
@@ -103,22 +127,15 @@ class WorkflowScopeResolver:
103
127
  if key not in _SCOPE_METADATA_FIELDS
104
128
  }
105
129
 
106
- def _is_internal_path_miss(self, scope_key: str) -> bool:
107
- """miss path 末段为 internal loop 节点 → 视为 internal 误抬,可降级。"""
108
- if ">" not in scope_key:
109
- return False
110
- return _path_tail_segment(scope_key) in LANGGRAPH_INTERNAL_LOOP_NODE_NAMES
111
-
112
- def _nearest_registered_ancestor_entry(self) -> dict[str, Any] | None:
113
- """沿 build_path() 的 '>' 分段前缀向上 walk,返回首个 scope_entry_at 命中。"""
114
- scope_key = self.current_scope_key()
115
- parts = scope_key.split(">")
116
- for depth in range(len(parts) - 1, 0, -1):
117
- prefix = ">".join(parts[:depth])
118
- entry = self.scope_entry_at(prefix)
119
- if entry is not None:
120
- return entry
121
- return None
130
+ def _warn_degraded_once(self, scope_key: str, ancestor: dict[str, Any]) -> None:
131
+ if scope_key in self._degrade_warned_paths:
132
+ return
133
+ self._degrade_warned_paths.add(scope_key)
134
+ logger.warning(
135
+ "workflow scope miss degraded to ancestor: path=%r ancestor=%r",
136
+ scope_key,
137
+ ancestor.get("scope_key"),
138
+ )
122
139
 
123
140
  def _build_scope_resolution_error(self, scope_key: str) -> WorkflowScopeResolutionError:
124
141
  detail_parts = [
@@ -144,4 +161,8 @@ class WorkflowScopeResolver:
144
161
  )
145
162
 
146
163
 
147
- __all__ = ["WorkflowScopeResolver", "WorkflowScopeResolutionError"]
164
+ __all__ = [
165
+ "WorkflowScopeResolver",
166
+ "WorkflowScopeResolutionError",
167
+ "nearest_degrade_ancestor",
168
+ ]
@@ -13,6 +13,7 @@ session_router.py — Workflow 结构/agent 事件 session_id 路由
13
13
  当前裁剪范围:
14
14
  - 结构容器事件仍走 stack/path;agent/loop 事件优先无状态 resolve_loop_session_id_for_event
15
15
  - aggregate 使用 aggregate_key 作为 task_key,无 special case
16
+ - D-SCOPE-A-SESSION:ns path 精确 miss 时与 ScopeResolver 同 walk(排除 root)
16
17
  """
17
18
 
18
19
  from __future__ import annotations
@@ -20,7 +21,7 @@ from __future__ import annotations
20
21
  from typing import Any
21
22
 
22
23
  from .depth_resolver import DepthResolver
23
- from .scope_resolver import WorkflowScopeResolver
24
+ from .scope_resolver import WorkflowScopeResolver, nearest_degrade_ancestor
24
25
  from .stack import WorkflowStack
25
26
  from .types import WorkflowEvent, WorkflowEventType
26
27
 
@@ -130,6 +131,12 @@ class WorkflowSessionRouter:
130
131
  scope_path = self._scope_path_from_raw_event(raw_event)
131
132
  if scope_path:
132
133
  entry = self._scope_resolver.scope_entry_at(scope_path)
134
+ if entry is None:
135
+ entry = nearest_degrade_ancestor(
136
+ scope_path,
137
+ root_scope=self._scope_resolver.root_scope,
138
+ lookup=self._scope_resolver.scope_entry_at,
139
+ )
133
140
  if entry is not None:
134
141
  return self._loop_session_from_scope_entry(
135
142
  entry,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-agentx-python
3
- Version: 2.2.0
3
+ Version: 2.2.2
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=_jWRBw5rNM52V1JxowuR91v-mVr2N_1x-Adhgz-4XrU,1614
1
+ langchain_agentx/__init__.py,sha256=CeiwdY0JNT9SJDHhM5_WnrLFW0CaC3PjbVuO98Owi1o,1614
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
@@ -217,8 +217,9 @@ langchain_agentx/observability/evaluation/checkers/tool_behavior.py,sha256=o1nH8
217
217
  langchain_agentx/observability/events/__init__.py,sha256=Zr9Iguf9XsJQLsCJy13YFdBtXHPEnI9aSWXWmA2MisA,1497
218
218
  langchain_agentx/observability/events/accumulated_text_scope.py,sha256=M4OvuQTgReF8SFrOmr-M5vyOJpzfvxj_DKD5bVpGb70,3169
219
219
  langchain_agentx/observability/events/agent_defaults.py,sha256=gmX0P__lux5xbCb8dtAlVCb3wZ7avaqFleoW4Q5anw4,1187
220
- langchain_agentx/observability/events/agent_event_projector.py,sha256=eMri832yK_BZbwsB_APwUN9vu66zMpZVxTstChG5l0A,63010
220
+ langchain_agentx/observability/events/agent_event_projector.py,sha256=Rktmy2D3qizCejAChbuOiAa06Tnup2Z6cVNATfrrxkU,63995
221
221
  langchain_agentx/observability/events/api_retry_projection.py,sha256=XGb09sNOi6k1ZGW4YqMLBE8GDxNwNMprk62jV9TS9dQ,2433
222
+ langchain_agentx/observability/events/compact_event_gate.py,sha256=50RJemwB1lnQn_NFWOFSgU418ZUR8dbd_v0538PT7zM,4751
222
223
  langchain_agentx/observability/events/factory.py,sha256=gqMATIK9tBQzaPWSPhCCSPuCq-WF562ZDTnFUaMm9Qc,1570
223
224
  langchain_agentx/observability/events/finish_event_payload_composer.py,sha256=v7MyLNSZ_gR5u5WFxPJu_0MYNDvC9s9gI2iNNt9Vbr4,13189
224
225
  langchain_agentx/observability/events/finish_outcome.py,sha256=igoueAwduzuuGDwg6u9AbBB-T2UBiqbUfNoxWCBYc_g,10401
@@ -724,8 +725,8 @@ langchain_agentx/workflow/validation.py,sha256=3I2jrSgOLAufe3kIzftE_Tfq0ZS-74bIx
724
725
  langchain_agentx/workflow/event_adapter/__init__.py,sha256=PkG6dP5mAjukYOFEtNFVDn00q_zPmS506dapZxpDgG8,1736
725
726
  langchain_agentx/workflow/event_adapter/adapter.py,sha256=eoOgcSos_cu12BRg3a4P0lQvarwr9jCcgt3OrC68A58,25188
726
727
  langchain_agentx/workflow/event_adapter/depth_resolver.py,sha256=1xI44dNk9cPotmk1Up14s0QV12WpkRPAQPYnVDY3ZlQ,3991
727
- langchain_agentx/workflow/event_adapter/scope_resolver.py,sha256=8KzflPIy0Y7PgX8xjgvEQD6_zzYEDL0oqxquhuA3wHA,5510
728
- langchain_agentx/workflow/event_adapter/session_router.py,sha256=0ih5_VxVb1_CWeUvz_qQIT14Mo0Oq7KZ22x1W__8hys,8915
728
+ langchain_agentx/workflow/event_adapter/scope_resolver.py,sha256=J4duUIdMfNB87zq_0q2sGBgokg0t0UIaxlBGRYJEv7w,5813
729
+ langchain_agentx/workflow/event_adapter/session_router.py,sha256=v2MZieOXDpcioeskSFswnXGKtT_Aw0M0sY9W3oCFmUY,9292
729
730
  langchain_agentx/workflow/event_adapter/stack.py,sha256=VCpJekxlGOg0CU2Unxcq7-TeyAHUajPyakKoGnUlT7g,4396
730
731
  langchain_agentx/workflow/event_adapter/structure_lifecycle_guard.py,sha256=0inUI-fw-xgWQHuGVVoWRM3a_gpys9JgvOxG5P4bTdw,6658
731
732
  langchain_agentx/workflow/event_adapter/structure_utils.py,sha256=y2gS-Tj9FajAqP8kgygaxrosVIRYNjhEtpnp-OIccB8,2820
@@ -759,8 +760,8 @@ langchain_agentx/workspace/root_grant_manager.py,sha256=W3gy8HTevbERbXqIgRcjzOXO
759
760
  langchain_agentx/workspace/tool_boundary.py,sha256=UDwX6swpSLsx9HNkYuuRRiV5o7ZZG_Bru2Yn0c5kNX8,5724
760
761
  langchain_agentx/workspace/validators.py,sha256=tQt-6TOcL8Fw7Ig5ebA9S7vGWh1rby920eFW6x8Tk9E,1439
761
762
  langchain_agentx/workspace/view.py,sha256=PGasqTaqhlD03SXXazHuw4RHfV681AIdlsYqL70pEjc,4774
762
- langchain_agentx_python-2.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
763
- langchain_agentx_python-2.2.0.dist-info/METADATA,sha256=nn2x47UdjwxReSgREvpk012hKVMAXtw303b9JRhUdAM,24250
764
- langchain_agentx_python-2.2.0.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
765
- langchain_agentx_python-2.2.0.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
766
- langchain_agentx_python-2.2.0.dist-info/RECORD,,
763
+ langchain_agentx_python-2.2.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
764
+ langchain_agentx_python-2.2.2.dist-info/METADATA,sha256=YHgIChmc4fVyfDcUNs9faXXrRAdOrZ8CF3db6Wnw-JY,24250
765
+ langchain_agentx_python-2.2.2.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
766
+ langchain_agentx_python-2.2.2.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
767
+ langchain_agentx_python-2.2.2.dist-info/RECORD,,