langchain-agentx-python 0.3.2__py3-none-any.whl → 0.3.3__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.
@@ -20,6 +20,8 @@ from .stages import (
20
20
  ToolResultBudgetStage,
21
21
  )
22
22
  from .types import (
23
+ CompactProgress,
24
+ CompactProgressCallback,
23
25
  CompactionConfig,
24
26
  ContextCompactionContext,
25
27
  StageResult,
@@ -40,6 +42,8 @@ __all__ = [
40
42
  "active_compaction_settings",
41
43
  "AutocompactLlmPromptKind",
42
44
  "AutocompactStage",
45
+ "CompactProgress",
46
+ "CompactProgressCallback",
43
47
  "CompactionBlockingGuard",
44
48
  "CompactionConfig",
45
49
  "CompactionSettings",
@@ -11,6 +11,7 @@
11
11
 
12
12
  注意:
13
13
  - 不修改 `should_end` / `finish_reason` 等 exit 字段;只产出 `messages` 增量补丁。
14
+ - `arun` 方法为 async 版本,支持进度回调(供 /compact 命令使用)。
14
15
  """
15
16
 
16
17
  from __future__ import annotations
@@ -19,7 +20,7 @@ from typing import Any, Dict, Mapping
19
20
 
20
21
  from .pipeline import ContextPipeline
21
22
  from .settings import CompactionSettings
22
- from .types import ContextCompactionContext
23
+ from .types import CompactProgressCallback, ContextCompactionContext
23
24
 
24
25
 
25
26
  class LoopContextCompaction:
@@ -42,6 +43,26 @@ class LoopContextCompaction:
42
43
  ctx = ContextCompactionContext.from_state(state, model)
43
44
  return self._pipeline.run(state, ctx)
44
45
 
46
+ async def arun(
47
+ self,
48
+ state: Mapping[str, Any],
49
+ model: Any | None = None,
50
+ progress_callback: CompactProgressCallback = None,
51
+ ) -> Dict[str, Any]:
52
+ """Async 版本(供 /compact 命令使用),支持进度回调。
53
+
54
+ 参数:
55
+ state: LangGraph state
56
+ model: 可选的 LLM model(供 autocompact 使用)
57
+ progress_callback: 进度回调函数,接收 CompactProgress 对象
58
+
59
+ 返回:
60
+ 与 run() 相同的补丁格式
61
+ """
62
+ ctx = ContextCompactionContext.from_state(state, model)
63
+ ctx.progress_callback = progress_callback
64
+ return await self._pipeline.arun(state, ctx)
65
+
45
66
 
46
67
  _default_loop_context_compaction: LoopContextCompaction | None = None
47
68
 
@@ -30,7 +30,7 @@ from .stages import (
30
30
  ToolResultBudgetStage,
31
31
  )
32
32
  from .stages.base import CompactionStage
33
- from .types import ContextCompactionContext
33
+ from .types import CompactProgress, ContextCompactionContext
34
34
 
35
35
 
36
36
  class DefaultCompactionStages:
@@ -120,6 +120,86 @@ class ContextPipeline:
120
120
  return {}
121
121
  return patch
122
122
 
123
+ async def arun(
124
+ self,
125
+ state: dict[str, Any],
126
+ ctx: ContextCompactionContext,
127
+ ) -> dict[str, Any]:
128
+ """Async 版本:每个 stage 完成后 emit 进度(供 /compact 进度条使用)。
129
+
130
+ 与 run() 的区别:
131
+ - 走 async 路径,支持 AutocompactStage 的流式 LLM 调用。
132
+ - 通过 ctx.progress_callback 回调进度更新。
133
+ """
134
+ messages = state.get("messages")
135
+ if not isinstance(messages, list) or not messages:
136
+ return {}
137
+
138
+ s = self._settings_override or get_active_compaction_settings()
139
+ estimator = TokenEstimator(num_chars_per_token=s.num_chars_per_token)
140
+ original_input = list(messages)
141
+ current = original_input
142
+ guard = CompactionBlockingGuard(settings=s)
143
+ tw = guard.calculate_token_warning_state(original_input)
144
+ tokens_before = estimator.estimate_messages_tokens(original_input)
145
+ stages_meta: list[dict[str, Any]] = []
146
+ total_freed = 0
147
+ n = len(self._stages)
148
+
149
+ for i, stage in enumerate(self._stages):
150
+ if ctx.progress_callback:
151
+ ctx.progress_callback(
152
+ CompactProgress(
153
+ stage=stage.name,
154
+ stage_index=i,
155
+ total_stages=n,
156
+ percent=int(i / n * 100),
157
+ )
158
+ )
159
+ # autocompact 走 async(内部 streaming),其余走 sync
160
+ sr = await stage.arun(current, ctx)
161
+ total_freed += sr.tokens_freed
162
+ stages_meta.append(
163
+ {
164
+ "name": stage.name,
165
+ "tokens_freed": sr.tokens_freed,
166
+ "extra": dict(sr.extra),
167
+ }
168
+ )
169
+ current = sr.messages
170
+ ctx.snip_tokens_freed_carry += sr.tokens_freed
171
+
172
+ if ctx.progress_callback:
173
+ ctx.progress_callback(
174
+ CompactProgress(
175
+ stage="done",
176
+ stage_index=n,
177
+ total_stages=n,
178
+ percent=100,
179
+ )
180
+ )
181
+
182
+ patch: dict[str, Any] = {}
183
+ if current is not original_input:
184
+ patch["messages"] = current
185
+
186
+ tokens_after = estimator.estimate_messages_tokens(current)
187
+ if s.emit_compaction_pipeline_meta and (
188
+ "messages" in patch or total_freed > 0
189
+ ):
190
+ patch["compaction_pipeline_meta"] = {
191
+ "estimated_tokens_before": tokens_before,
192
+ "estimated_tokens_after": tokens_after,
193
+ "tokens_freed_sum": total_freed,
194
+ "snip_tokens_freed_carry_final": ctx.snip_tokens_freed_carry,
195
+ "token_warning_level": tw.level,
196
+ "stages": stages_meta,
197
+ }
198
+
199
+ if not patch:
200
+ return {}
201
+ return patch
202
+
123
203
 
124
204
  __all__ = [
125
205
  "ContextPipeline",
@@ -13,6 +13,7 @@ Autocompact 阶段:超阈值时折叠前缀消息(对齐 CC `deps.autocompac
13
13
 
14
14
  注意:
15
15
  - `query_source in autocompact_skip_query_sources`(如 `compact`)时跳过,防递归压缩。
16
+ - `arun()` 方法为 async 版本,支持流式 LLM 调用与进度回调。
16
17
  """
17
18
 
18
19
  from __future__ import annotations
@@ -25,7 +26,7 @@ from ..blocking_guard import CompactionBlockingGuard
25
26
  from ..message_utils import stringify_content, total_estimated_tokens_for_messages
26
27
  from ...prompt.compact import build_autocompact_llm_instruction_prompt, get_compact_user_summary_message
27
28
  from ..settings import CompactionSettings, get_active_compaction_settings
28
- from ..types import ContextCompactionContext, StageResult
29
+ from ..types import CompactProgress, ContextCompactionContext, StageResult
29
30
  from .base import CompactionStage
30
31
 
31
32
 
@@ -105,6 +106,70 @@ class AutocompactStage(CompactionStage):
105
106
  extra={"autocompact_mode": mode, "folded_messages": len(head)},
106
107
  )
107
108
 
109
+ async def arun(self, messages: list[Any], ctx: ContextCompactionContext) -> StageResult:
110
+ """Async 版本:LLM 摘要使用 astream 流式生成,支持进度回调。"""
111
+ s = self._effective_settings()
112
+ if ctx.query_source in s.autocompact_skip_query_sources:
113
+ return StageResult(messages=messages, tokens_freed=0, extra={"autocompact_skipped": "query_source"})
114
+
115
+ total = total_estimated_tokens_for_messages(messages, s.num_chars_per_token)
116
+ threshold = int(s.default_max_context_tokens * s.default_compress_trigger_fraction)
117
+ slack = ctx.snip_tokens_freed_carry if s.autocompact_snip_carry_threshold_slack else 0
118
+ if total <= threshold + slack:
119
+ return StageResult(messages=messages, tokens_freed=0)
120
+
121
+ # 跳过所有 SystemMessages(不保留),对齐 SystemMessage 单一来源原则
122
+ idx = 0
123
+ while idx < len(messages) and isinstance(messages[idx], SystemMessage):
124
+ idx += 1
125
+ rest = messages[idx:]
126
+ k = max(1, s.default_compress_keep_recent_messages)
127
+ if len(rest) <= k:
128
+ return StageResult(messages=messages, tokens_freed=0)
129
+
130
+ head = rest[:-k]
131
+ tail = rest[-k:]
132
+
133
+ block_llm = CompactionBlockingGuard(settings=s).should_block_compact_llm(messages)
134
+ if (
135
+ s.autocompact_use_llm_when_available
136
+ and ctx.model is not None
137
+ and not block_llm
138
+ ):
139
+ summary = await _astream_summary(ctx.model, s, head, ctx.progress_callback)
140
+ if summary:
141
+ folded = [
142
+ HumanMessage(
143
+ content=get_compact_user_summary_message(
144
+ summary,
145
+ recent_messages_preserved=True,
146
+ )
147
+ )
148
+ ] + tail
149
+ new_total = total_estimated_tokens_for_messages(folded, s.num_chars_per_token)
150
+ return StageResult(
151
+ messages=folded,
152
+ tokens_freed=max(0, total - new_total),
153
+ extra={"autocompact_mode": "llm", "folded_messages": len(head)},
154
+ )
155
+
156
+ # fallback: prune
157
+ folded = [
158
+ HumanMessage(
159
+ content=(
160
+ f"[Context autocompacted: {len(head)} earlier messages omitted; "
161
+ "details dropped for token budget.]"
162
+ )
163
+ )
164
+ ] + tail
165
+ new_total = total_estimated_tokens_for_messages(folded, s.num_chars_per_token)
166
+ mode = "prune_blocked_llm" if block_llm else "prune"
167
+ return StageResult(
168
+ messages=folded,
169
+ tokens_freed=max(0, total - new_total),
170
+ extra={"autocompact_mode": mode, "folded_messages": len(head)},
171
+ )
172
+
108
173
 
109
174
  def _resolve_autocompact_llm_instruction(s: CompactionSettings) -> str:
110
175
  if s.autocompact_llm_instructions_override is not None:
@@ -139,3 +204,50 @@ def _invoke_summary(model: Any, s: CompactionSettings, head: list[Any]) -> str |
139
204
  return None
140
205
  text = stringify_content(getattr(resp, "content", None))
141
206
  return text if text else None
207
+
208
+
209
+ async def _astream_summary(
210
+ model: Any, s: CompactionSettings, head: list[Any], progress_callback: Any = None
211
+ ) -> str | None:
212
+ """流式生成摘要,每个 chunk 触发 progress callback。
213
+
214
+ 进度计算:
215
+ - autocompact 占 80%-100%,用 chunk 数做粗略进度。
216
+ - 每收到约 10 个 chunk 增加 2%,上限 99%。
217
+ """
218
+ cap = max(256, s.autocompact_llm_excerpt_chars_per_message)
219
+ parts: list[str] = []
220
+ for m in head:
221
+ label = getattr(m, "type", type(m).__name__)
222
+ chunk = stringify_content(getattr(m, "content", None))[:cap]
223
+ parts.append(f"{label}: {chunk}")
224
+ body = "\n\n---\n\n".join(parts)
225
+ excerpt_msg = HumanMessage(
226
+ content="[Conversation excerpt to summarize]\n\n" + body
227
+ )
228
+ instruction = _resolve_autocompact_llm_instruction(s)
229
+ instruction_msg = HumanMessage(content=instruction)
230
+
231
+ try:
232
+ chunks: list[str] = []
233
+ async for chunk in model.astream([excerpt_msg, instruction_msg]):
234
+ token = stringify_content(getattr(chunk, "content", None))
235
+ if token:
236
+ chunks.append(token)
237
+ if progress_callback:
238
+ # autocompact 占 80%-100%,用 chunk 数做粗略进度
239
+ pct = min(80 + len(chunks) * 2 // 10, 99)
240
+ from ..types import CompactProgress
241
+
242
+ progress_callback(
243
+ CompactProgress(
244
+ stage="autocompact",
245
+ stage_index=4,
246
+ total_stages=5,
247
+ percent=pct,
248
+ detail="generating summary...",
249
+ )
250
+ )
251
+ return "".join(chunks) or None
252
+ except Exception:
253
+ return None
@@ -30,3 +30,12 @@ class CompactionStage(ABC):
30
30
  @abstractmethod
31
31
  def run(self, messages: list[Any], ctx: ContextCompactionContext) -> StageResult:
32
32
  """输入当前消息列表,返回更新后的列表与可选 tokens_freed。"""
33
+
34
+ async def arun(self, messages: list[Any], ctx: ContextCompactionContext) -> StageResult:
35
+ """Async 版本,默认委托 sync run()。AutocompactStage 覆盖此方法。
36
+
37
+ 子类覆盖说明:
38
+ - 仅 AutocompactStage 需要覆盖以支持流式 LLM 调用。
39
+ - 其他阶段继承此默认实现即可。
40
+ """
41
+ return self.run(messages, ctx)
@@ -11,10 +11,12 @@
11
11
 
12
12
  注意:
13
13
  - `TokenWarningState` 供 `blocking_guard` 与 `compaction_pipeline_meta` 观测对齐 CC token 告警语义。
14
+ - `CompactProgress` 用于 /compact 进度条回调,CLI 通过 progress_callback 接收进度更新。
14
15
  """
15
16
 
16
17
  from __future__ import annotations
17
18
 
19
+ from collections.abc import Callable
18
20
  from dataclasses import dataclass, field
19
21
  from typing import Any, Literal, Mapping
20
22
 
@@ -37,6 +39,7 @@ class ContextCompactionContext:
37
39
  snip_tokens_freed_carry: int = 0
38
40
  query_source: str | None = None
39
41
  config: CompactionConfig = field(default_factory=CompactionConfig)
42
+ progress_callback: CompactProgressCallback = None
40
43
 
41
44
  @classmethod
42
45
  def from_state(
@@ -70,8 +73,32 @@ class TokenWarningState:
70
73
  level: TokenWarningLevel
71
74
 
72
75
 
76
+ @dataclass(frozen=True)
77
+ class CompactProgress:
78
+ """压缩进度通知(供 CLI 进度条消费)。
79
+
80
+ 属性:
81
+ stage: 当前阶段名(tool_result_budget / snip / microcompact / collapse / autocompact / done)
82
+ stage_index: 0-based 阶段序号
83
+ total_stages: 总阶段数(默认 5)
84
+ percent: 0-100 整体进度百分比
85
+ detail: 可选描述(如 "generating summary...")
86
+ """
87
+
88
+ stage: str
89
+ stage_index: int
90
+ total_stages: int
91
+ percent: int
92
+ detail: str | None = None
93
+
94
+
95
+ CompactProgressCallback = Callable[[CompactProgress], None] | None
96
+
97
+
73
98
  __all__ = [
74
99
  "CompactionConfig",
100
+ "CompactProgress",
101
+ "CompactProgressCallback",
75
102
  "ContextCompactionContext",
76
103
  "StageResult",
77
104
  "TokenWarningLevel",
@@ -202,9 +202,25 @@ class AgentSession:
202
202
  def clear_context(self) -> None:
203
203
  self._messages.clear()
204
204
 
205
- async def compact_context(self) -> tuple[int, int]:
205
+ async def compact_context(
206
+ self, *, progress_callback: Any = None
207
+ ) -> tuple[int, int]:
208
+ """压缩会话上下文,可选传入进度回调。
209
+
210
+ 参数:
211
+ progress_callback: 可选的进度回调函数,接收 CompactProgress 对象
212
+
213
+ 返回:
214
+ (before_tokens, after_tokens) 元组
215
+ """
206
216
  before_tokens = total_estimated_tokens_for_messages(self._messages, num_chars_per_token=4)
207
- patch = default_loop_context_compaction().run({"messages": self._messages})
217
+ # 注意:model=None 表示不使用 LLM 摘要,仅走 prune 路径
218
+ # 如果需要 LLM 摘要,调用方需要通过其他方式提供 model
219
+ patch = await default_loop_context_compaction().arun(
220
+ {"messages": self._messages},
221
+ model=None,
222
+ progress_callback=progress_callback,
223
+ )
208
224
  if isinstance(patch.get("messages"), list):
209
225
  self._messages = list(patch["messages"])
210
226
  after_tokens = total_estimated_tokens_for_messages(self._messages, num_chars_per_token=4)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-agentx-python
3
- Version: 0.3.2
3
+ Version: 0.3.3
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
@@ -21,16 +21,16 @@ langchain_agentx/loop/config/agent_loop_config.py,sha256=ZzmrFO9nIVQst9-mAICTgG0
21
21
  langchain_agentx/loop/config/model_context_resolver.py,sha256=qZWDLyGlvr0YVZkvpDk72h6_Qbe0mvhWwlvTRsTfJ_E,3916
22
22
  langchain_agentx/loop/config/runtime_settings.py,sha256=uKkwyxgx5u34qbjP1DFrIRt0EygRCtsH8tMN0kWA0Yo,1551
23
23
  langchain_agentx/loop/config/token_estimator.py,sha256=2-Rp2Bdc5a-60D1nm88z4-sNzS25nv8hkKIfaBqE78E,4883
24
- langchain_agentx/loop/context/__init__.py,sha256=HUuKNwysY-RNCvenEhN5CuoHSInY94a16aC9hMAG-go,1896
24
+ langchain_agentx/loop/context/__init__.py,sha256=VMYkkJSqjLpkx_6MqGpiASQIW-QDF8L7OwffSn_CnoI,2000
25
25
  langchain_agentx/loop/context/blocking_guard.py,sha256=Rmt5qZdE8Zf0bt-Q6WwMSfG869772PE8w1mNPvBQRCQ,3789
26
- langchain_agentx/loop/context/compaction_service.py,sha256=dJG24qbJ2t93_UwrXoPacRazpGf2l429310PHzLAz9A,2183
26
+ langchain_agentx/loop/context/compaction_service.py,sha256=nvLG8dfEqoJouuE9BHczmIZEb7pxU5lcuhIJJ8Pi5Sg,3004
27
27
  langchain_agentx/loop/context/message_utils.py,sha256=6qIwtHeh63OlMqOnPUpEEWRknU9KJTGkcY1v3tz6feY,2010
28
- langchain_agentx/loop/context/pipeline.py,sha256=mQA5CcSrXaYb3kM3bO3MqrBPRzQebodmhRMG-9waIN8,4461
28
+ langchain_agentx/loop/context/pipeline.py,sha256=P_3oK_dfnx1BT5nCPYo3cmD94QhZP9xeiSOXv3-oCeU,7418
29
29
  langchain_agentx/loop/context/settings.py,sha256=cbfb5RyBupsIY1CF-QZ8OsuIrpdx9QzNwXRAezkMl8U,5918
30
- langchain_agentx/loop/context/types.py,sha256=imjo5mSxwkn7uGrwJzGDtAB9aH9M6DdfXyBAZTUvknE,2332
30
+ langchain_agentx/loop/context/types.py,sha256=HIiuNlOl47CmBlRr0yp-NCGaZ29omb3z2VRWq8mIsTI,3194
31
31
  langchain_agentx/loop/context/stages/__init__.py,sha256=wk9CFh8_Akw8qs3Dldnx14VE1MhyF5i9Cg3phTVChhg,892
32
- langchain_agentx/loop/context/stages/autocompact.py,sha256=P1XazrWL3YoH0gu8df5FMnRTb6d_XCJDpT9g8_H1bkM,7041
33
- langchain_agentx/loop/context/stages/base.py,sha256=iOWVR5NwmRcYq6fQAI6WEi-LMsuBeH5TfuOorN0luIg,982
32
+ langchain_agentx/loop/context/stages/autocompact.py,sha256=En8K7dkqAnueZH0mQ4eY6r8-wwY8oXikTKaXcri_Mhs,11784
33
+ langchain_agentx/loop/context/stages/base.py,sha256=LVfCp-DLySrTExy0J-M40tDJvzbOXxfZxXvi7XQayA8,1380
34
34
  langchain_agentx/loop/context/stages/collapse.py,sha256=yOf3nfWZr83rq2qnhUpuTCLFHcGvF7my8klMLmfZ7jc,2971
35
35
  langchain_agentx/loop/context/stages/microcompact.py,sha256=aTF3TjBkQ_fDx818Kfwr3d7hdx3dtAW8St3bAOiZTMg,2779
36
36
  langchain_agentx/loop/context/stages/noop.py,sha256=UKKPeKfyDoxd9NBzjIai6OGcr-9RrraKmx2E9Vpf3vc,1069
@@ -157,7 +157,7 @@ langchain_agentx/provider/env.py,sha256=bmELhixPGoJ3b0rtgEPCB512gJF2cVS00bRQfclk
157
157
  langchain_agentx/provider/model_profile.py,sha256=3m3iVtYYuBLMADRu-36L_JwODjH8vYe1BfkuEMNkKJc,6245
158
158
  langchain_agentx/provider/openai.py,sha256=mNPRPhxtkKRhBVnXqJD8r1Vmo22HNM-hT-Di_VNL-ng,2996
159
159
  langchain_agentx/session/__init__.py,sha256=UO-bRS9oYSzdYoavow4FSXdY7qzw5O3VoUH9_FTzGTI,497
160
- langchain_agentx/session/agent_session.py,sha256=iAlB7w9GFxlBh_eZiNCW7YPqPibLaCr1QiPWHgHEIHQ,13791
160
+ langchain_agentx/session/agent_session.py,sha256=jMc6vwsv8wNa0B_3HtTyXpJAH72xuR0D4rqQJwlPlRs,14352
161
161
  langchain_agentx/session/conversation_factory.py,sha256=Nhi_8iH0D8-NmfsJqgnKxIEa8Y32qfOFpjRNqWVksEQ,2992
162
162
  langchain_agentx/session/conversation_recovery.py,sha256=U0M3p4NKaSz6heEvNzlzehC8oTX9EB2Vz-QdYhhyk0U,5813
163
163
  langchain_agentx/session/conversation_session.py,sha256=phzXQZMfNCOzOa9dDlaA0zaPCOVuHiu6_EXmg3zpuok,8007
@@ -444,8 +444,8 @@ langchain_agentx/workspace/config.py,sha256=K2XaAvlkBr5aA2mgH5zNxfAZg-LGmwwDVNcE
444
444
  langchain_agentx/workspace/path_key_normalizer.py,sha256=ICk9uGiiNFH-zaXJG3_vx91uOpgWmgOPIjJoSYevKOc,1113
445
445
  langchain_agentx/workspace/resolver.py,sha256=9-wRLLIC7KJCqu9i8nAL-gJ9lIWsTPOpjnZnZEGLunk,6281
446
446
  langchain_agentx/workspace/validators.py,sha256=tQt-6TOcL8Fw7Ig5ebA9S7vGWh1rby920eFW6x8Tk9E,1439
447
- langchain_agentx_python-0.3.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
448
- langchain_agentx_python-0.3.2.dist-info/METADATA,sha256=TVN9m4gC_J5zfoi0NF5H_UcBWpMPHls6q9Om8wJdzkU,20832
449
- langchain_agentx_python-0.3.2.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
450
- langchain_agentx_python-0.3.2.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
451
- langchain_agentx_python-0.3.2.dist-info/RECORD,,
447
+ langchain_agentx_python-0.3.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
448
+ langchain_agentx_python-0.3.3.dist-info/METADATA,sha256=X1N_trdWuzlYm1XVrNWgIxTq1P2nsxiYjy-Bjdz91xo,20832
449
+ langchain_agentx_python-0.3.3.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
450
+ langchain_agentx_python-0.3.3.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
451
+ langchain_agentx_python-0.3.3.dist-info/RECORD,,