langchain-agentx-python 1.2.0__py3-none-any.whl → 1.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__ = "1.2.0"
14
+ __version__ = "1.2.2"
15
15
 
16
16
  from .loop import ( # noqa: F401
17
17
  create_loop_agent,
@@ -69,7 +69,6 @@ from .models import (
69
69
  ToolResultEnvelope,
70
70
  )
71
71
  from .permission_orchestrator import aevaluate_permission, evaluate_permission
72
- from .policy import ensure_default_policy_engine
73
72
  from .override import enrich_blocked_deny_envelope
74
73
  from .denial_tracking_bridge import (
75
74
  attach_denial_tracking_meta,
@@ -730,7 +729,6 @@ class ToolExecutorPipeline:
730
729
  )
731
730
 
732
731
  # Step 4: check_permissions(PermissionOrchestrator 单入口)
733
- ensure_default_policy_engine(tool)
734
732
  auth = evaluate_permission(tool, parsed_data, ctx, headless=self._headless)
735
733
  if auth.behavior == "deny":
736
734
  logger.warning("tool permission denied tool=%s policy_id=%s", tool.name, auth.policy_id)
@@ -922,7 +920,6 @@ class ToolExecutorPipeline:
922
920
  )
923
921
 
924
922
  # Step 4: check_permissions(PermissionOrchestrator 单入口)
925
- ensure_default_policy_engine(tool)
926
923
  auth = await aevaluate_permission(tool, parsed_data, ctx, headless=self._headless)
927
924
 
928
925
  if auth.behavior == "deny":
@@ -23,6 +23,7 @@ import os
23
23
  import pathlib
24
24
  import sys
25
25
  import tempfile
26
+ from typing import Any
26
27
 
27
28
  from pydantic import BaseModel
28
29
 
@@ -46,6 +47,18 @@ from langchain_agentx.tool_runtime.registry import RuntimeToolRegistry
46
47
  from langchain_agentx.tool_runtime.session_store import AgentSessionStore
47
48
  from langchain_agentx.tool_runtime.state_bridge import ToolStateBridge
48
49
 
50
+ from tests._common.tool_policy_assembly import mirror_loader_policy_on_tool
51
+
52
+
53
+ def _pipeline_run(
54
+ pipeline: ToolExecutorPipeline,
55
+ tool: RuntimeTool,
56
+ raw_input: dict[str, Any],
57
+ ctx: ToolExecutionContext,
58
+ ) -> ToolResultEnvelope:
59
+ mirror_loader_policy_on_tool(tool, ctx)
60
+ return pipeline.run(tool=tool, raw_input=raw_input, ctx=ctx)
61
+
49
62
  # ---------------------------------------------------------------------------
50
63
  # 最小工具定义(所有测试共用)
51
64
  # ---------------------------------------------------------------------------
@@ -118,7 +131,7 @@ def test_normal_flow() -> None:
118
131
  _section("Test 1: 正常工具流转")
119
132
  pipeline = ToolExecutorPipeline()
120
133
  ctx = _make_ctx()
121
- env = pipeline.run(tool=EchoTool(), raw_input={"message": "hello runtime"}, ctx=ctx)
134
+ env = _pipeline_run(pipeline, EchoTool(), {"message": "hello runtime"}, ctx)
122
135
  assert env.status == "ok", f"got {env.status}"
123
136
  assert "hello runtime" in env.summary
124
137
  _pass(f"status=ok, summary={env.summary!r}")
@@ -129,7 +142,7 @@ def test_adapter_output() -> None:
129
142
  pipeline = ToolExecutorPipeline()
130
143
  adapter = LangChainAdapter()
131
144
  ctx = _make_ctx()
132
- env = pipeline.run(tool=EchoTool(), raw_input={"message": "hello"}, ctx=ctx)
145
+ env = _pipeline_run(pipeline, EchoTool(), {"message": "hello"}, ctx)
133
146
  output = adapter.envelope_to_tool_output(env)
134
147
  assert "hello" in output
135
148
  _pass(f"output={output!r}")
@@ -147,7 +160,7 @@ def test_validate_input_short_circuit() -> None:
147
160
 
148
161
  pipeline = ToolExecutorPipeline()
149
162
  ctx = _make_ctx()
150
- env = pipeline.run(tool=StrictEcho(), raw_input={"message": "too long message"}, ctx=ctx)
163
+ env = _pipeline_run(pipeline, StrictEcho(), {"message": "too long message"}, ctx)
151
164
  assert env.status == "error"
152
165
  assert "too long" in env.summary
153
166
  _pass(f"status=error, summary={env.summary!r}")
@@ -168,7 +181,7 @@ def test_check_permissions_blocked() -> None:
168
181
 
169
182
  pipeline = ToolExecutorPipeline()
170
183
  ctx = _make_ctx()
171
- env = pipeline.run(tool=DeniedEcho(), raw_input={"message": "hi"}, ctx=ctx)
184
+ env = _pipeline_run(pipeline, DeniedEcho(), {"message": "hi"}, ctx)
172
185
  assert env.status == "blocked"
173
186
  assert "denied_echo" in env.summary
174
187
  _pass(f"status=blocked, summary prefix={env.summary[:60]!r}...")
@@ -183,7 +196,7 @@ def test_output_manager_truncation() -> None:
183
196
 
184
197
  pipeline = ToolExecutorPipeline()
185
198
  ctx = _make_ctx()
186
- env = pipeline.run(tool=TinyEcho(), raw_input={"message": "hello runtime 1234"}, ctx=ctx)
199
+ env = _pipeline_run(pipeline, TinyEcho(), {"message": "hello runtime 1234"}, ctx)
187
200
  assert env.truncated is True
188
201
  assert env.overflow_file is not None
189
202
  assert os.path.exists(env.overflow_file)
@@ -207,7 +220,7 @@ def test_registry_and_policy_no_path_field() -> None:
207
220
  assert lc_tools[0].name == "echo"
208
221
 
209
222
  ctx = _make_ctx()
210
- env = pipeline.run(tool=registry.get("echo"), raw_input={"message": "ok"}, ctx=ctx)
223
+ env = _pipeline_run(pipeline, registry.get("echo"), {"message": "ok"}, ctx)
211
224
  assert env.status == "ok"
212
225
  _pass("registry.register + to_langchain_tools OK, policy allow (no path field)")
213
226
 
@@ -248,7 +261,7 @@ def test_exception_captured_as_error_envelope() -> None:
248
261
 
249
262
  pipeline = ToolExecutorPipeline()
250
263
  ctx = _make_ctx()
251
- env = pipeline.run(tool=BrokenEcho(), raw_input={"message": "hi"}, ctx=ctx)
264
+ env = _pipeline_run(pipeline, BrokenEcho(), {"message": "hi"}, ctx)
252
265
  assert env.status == "error"
253
266
  assert "went wrong" in env.summary
254
267
  assert env.meta is not None and "traceback" in env.meta
@@ -260,7 +273,7 @@ def test_schema_parse_failure() -> None:
260
273
  pipeline = ToolExecutorPipeline()
261
274
  ctx = _make_ctx()
262
275
  # 传入错误类型(缺少必填 message 字段)
263
- env = pipeline.run(tool=EchoTool(), raw_input={}, ctx=ctx)
276
+ env = _pipeline_run(pipeline, EchoTool(), {}, ctx)
264
277
  assert env.status == "error"
265
278
  assert "schema" in env.summary.lower() or "message" in env.summary.lower()
266
279
  _pass(f"status=error on missing field: {env.summary!r}")
@@ -249,6 +249,9 @@ class BackgroundTask:
249
249
  pid: int
250
250
  """后台进程 PID。"""
251
251
 
252
+ command: str = ""
253
+ """原始命令(用于终态语义解析;亦持久化至 task_dir/command.txt)。"""
254
+
252
255
  sandboxed: bool = False
253
256
  """后台任务是否在沙箱模式下执行。"""
254
257
 
@@ -365,6 +368,7 @@ class LocalTmpdirSandboxBackend:
365
368
  task_id=task.task_id,
366
369
  output_path=task.output_path,
367
370
  pid=task.pid,
371
+ command=request.command,
368
372
  sandboxed=True,
369
373
  sandbox_temp_dir=temp_dir,
370
374
  )
@@ -1556,12 +1560,17 @@ class BashBackend:
1556
1560
  with open(pid_path, "w") as f:
1557
1561
  f.write(str(proc.pid))
1558
1562
 
1563
+ command_path = os.path.join(task_dir, "command.txt")
1564
+ with open(command_path, "w", encoding="utf-8") as f:
1565
+ f.write(command)
1566
+
1559
1567
  output_file.close()
1560
1568
 
1561
1569
  return BackgroundTask(
1562
1570
  task_id=task_id,
1563
1571
  output_path=output_path,
1564
1572
  pid=proc.pid,
1573
+ command=command,
1565
1574
  )
1566
1575
 
1567
1576
  def get_background_status(self, task: BackgroundTask) -> BackgroundTaskStatus:
@@ -1619,23 +1628,25 @@ class BashBackend:
1619
1628
  )
1620
1629
 
1621
1630
  @staticmethod
1622
- def build_foreground_snapshot(result: ExecuteResult) -> BashTaskSnapshot:
1631
+ def build_foreground_snapshot(
1632
+ result: ExecuteResult,
1633
+ *,
1634
+ terminal_status: str,
1635
+ ) -> BashTaskSnapshot:
1636
+ """构建 foreground 快照;终态由 semantics.resolve_terminal_task_status 决定。"""
1623
1637
  t0 = time.time()
1624
1638
  sm = BashTaskStateMachine(task_id="foreground", task_mode="foreground")
1625
1639
  sm.created_ts = t0
1626
1640
  sm.transition_to("running")
1627
1641
  sm.started_ts = time.time()
1628
- if result.interrupted:
1629
- sm.transition_to("interrupted")
1630
- elif result.exit_code == 0:
1631
- sm.transition_to("completed")
1632
- else:
1633
- sm.transition_to("failed")
1642
+ sm.transition_to(terminal_status)
1634
1643
  sm.ended_ts = time.time()
1635
1644
  sm.exit_code = result.exit_code
1636
1645
  return sm.to_snapshot()
1637
1646
 
1638
1647
  def build_background_snapshot(self, task: BackgroundTask) -> BashTaskSnapshot:
1648
+ from .semantics import resolve_background_terminal_status
1649
+
1639
1650
  status = self.get_background_status(task)
1640
1651
  sm = BashTaskStateMachine(task_id=task.task_id, task_mode="background")
1641
1652
  sm.created_ts = time.time()
@@ -1647,17 +1658,36 @@ class BashBackend:
1647
1658
  if status.running:
1648
1659
  return sm.to_snapshot()
1649
1660
  sm.ended_ts = time.time()
1650
- if status.exit_code == -2:
1651
- sm.transition_to("cancelled")
1652
- elif status.exit_code == 0:
1653
- sm.transition_to("completed")
1654
- elif status.exit_code is None:
1655
- sm.transition_to("interrupted")
1656
- else:
1657
- sm.transition_to("failed")
1661
+ command = task.command or self._read_persisted_background_command(task)
1662
+ stdout = self._read_background_output_text(task.output_path)
1663
+ terminal_status = resolve_background_terminal_status(
1664
+ exit_code=status.exit_code,
1665
+ command=command,
1666
+ stdout=stdout,
1667
+ )
1668
+ sm.transition_to(terminal_status)
1658
1669
  sm.exit_code = status.exit_code
1659
1670
  return sm.to_snapshot()
1660
1671
 
1672
+ @staticmethod
1673
+ def _read_persisted_background_command(task: BackgroundTask) -> str:
1674
+ command_path = os.path.join(os.path.dirname(task.output_path), "command.txt")
1675
+ try:
1676
+ with open(command_path, encoding="utf-8") as f:
1677
+ return f.read().strip()
1678
+ except OSError:
1679
+ return ""
1680
+
1681
+ @staticmethod
1682
+ def _read_background_output_text(output_path: str) -> str:
1683
+ if not os.path.exists(output_path):
1684
+ return ""
1685
+ try:
1686
+ with open(output_path, encoding="utf-8", errors="replace") as f:
1687
+ return f.read()
1688
+ except OSError:
1689
+ return ""
1690
+
1661
1691
  def cancel_background_task(self, task: BackgroundTask) -> bool:
1662
1692
  """
1663
1693
  取消后台任务:发信号终止进程,并标记为 cancelled(exit_code 文件写 -2)。
@@ -143,16 +143,10 @@ class BashResultPresenter:
143
143
  )
144
144
 
145
145
  summary = description_text or f"Ran: {command[:60]}"
146
- # 构建 payload:合并 stdout 和 stderr(与 CC mapToolResultToToolResultBlockParam 对齐)
147
146
  stdout_text = result.stdout or ""
148
147
  stderr_text = result.stderr or ""
149
- if stdout_text and stderr_text:
150
- payload = f"{stdout_text}\n{stderr_text}"
151
- elif stderr_text:
152
- payload = stderr_text
153
- else:
154
- payload = stdout_text or "(No output)"
155
- hints = self._build_hints(result)
148
+ payload, skip_interpretation_hint = self._resolve_foreground_payload(result)
149
+ hints = self._build_hints(result, skip_interpretation=skip_interpretation_hint)
156
150
  if result.output_truncated and result.overflow_file:
157
151
  import os
158
152
 
@@ -200,14 +194,7 @@ class BashResultPresenter:
200
194
  tool_name=tool_name,
201
195
  summary=summary,
202
196
  payload=payload,
203
- blocks=[
204
- ToolContentBlock(
205
- type="status",
206
- text=f"task:{result.task_status}",
207
- meta={"task_mode": result.task_mode, "task_exit_code": result.task_exit_code},
208
- ),
209
- ToolContentBlock(type="text", text=payload),
210
- ],
197
+ blocks=[ToolContentBlock(type="text", text=payload)],
211
198
  hints=hints or None,
212
199
  meta=self._attach_observability({
213
200
  "exit_code": result.exit_code,
@@ -316,10 +303,36 @@ class BashResultPresenter:
316
303
  meta=self._attach_observability({"exit_code": result.exit_code, "command": command}, result),
317
304
  )
318
305
 
319
- def _build_hints(self, result: BashToolOutput) -> list[ToolHint]:
320
- hints: list[ToolHint] = []
306
+ def _resolve_foreground_payload(self, result: BashToolOutput) -> tuple[str, bool]:
307
+ """
308
+ CC BashToolResultMessage:空输出时优先展示 returnCodeInterpretation。
321
309
 
310
+ Returns:
311
+ (payload, skip_interpretation_hint) — payload 已含 interpretation 时不再重复 hint。
312
+ """
313
+ stdout_text = result.stdout or ""
314
+ stderr_text = result.stderr or ""
315
+ if stdout_text.strip() or stderr_text.strip():
316
+ if stdout_text and stderr_text:
317
+ return f"{stdout_text}\n{stderr_text}", False
318
+ if stderr_text:
319
+ return stderr_text, False
320
+ return stdout_text, False
322
321
  if result.return_code_interpretation:
322
+ return result.return_code_interpretation, True
323
+ if result.no_output_expected:
324
+ return "Done", False
325
+ return "(No output)", False
326
+
327
+ def _build_hints(
328
+ self,
329
+ result: BashToolOutput,
330
+ *,
331
+ skip_interpretation: bool = False,
332
+ ) -> list[ToolHint]:
333
+ hints: list[ToolHint] = []
334
+
335
+ if result.return_code_interpretation and not skip_interpretation:
323
336
  hints.append(ToolHint(message=result.return_code_interpretation))
324
337
 
325
338
  if result.destructive_warning:
@@ -17,7 +17,8 @@ from __future__ import annotations
17
17
  import re
18
18
  from dataclasses import dataclass
19
19
 
20
- # tree/find/ls 在 Windows Git Bash 等环境常不可用(exit 127);CC 引导用 Glob 专用工具。
20
+ # tree/find/ls 在 Windows Git Bash 等环境常不可用(exit 127)。
21
+ # SDK 扩展(相对 CC DEFAULT_SEMANTIC 硬失败):软成功 + Glob hint,便于跨平台引导。
21
22
  _FILE_LISTING_COMMANDS = re.compile(r"^(?:tree|find|ls)\b")
22
23
  _FILE_LISTING_EXIT_127_HINT = (
23
24
  "Command not found (exit 127). "
@@ -86,6 +87,46 @@ class CommandResult:
86
87
  message: str | None = None
87
88
 
88
89
 
90
+ def resolve_terminal_task_status(
91
+ *,
92
+ interrupted: bool,
93
+ exit_code: int,
94
+ semantic: CommandResult,
95
+ ) -> str:
96
+ """
97
+ 由 interpret_command_result 派生任务终态(SSOT)。
98
+
99
+ 对应 CC BashTool.call:interpretCommandResult → throw ShellError 或成功返回;
100
+ SDK 额外保留 task_status 供 observability,但不得再用 raw exit_code 独立判定。
101
+ """
102
+ if interrupted:
103
+ return "interrupted"
104
+ if semantic.is_error and exit_code != 0:
105
+ return "failed"
106
+ return "completed"
107
+
108
+
109
+ def resolve_background_terminal_status(
110
+ *,
111
+ exit_code: int | None,
112
+ command: str,
113
+ stdout: str = "",
114
+ ) -> str:
115
+ """
116
+ 后台任务终态:cancelled/interrupted 走协议码;其余与 foreground 共用 semantics SSOT。
117
+ """
118
+ if exit_code == -2:
119
+ return "cancelled"
120
+ if exit_code is None:
121
+ return "interrupted"
122
+ semantic = interpret_command_result(command, exit_code, stdout)
123
+ return resolve_terminal_task_status(
124
+ interrupted=False,
125
+ exit_code=exit_code,
126
+ semantic=semantic,
127
+ )
128
+
129
+
89
130
  def interpret_command_result(
90
131
  command: str,
91
132
  exit_code: int,
@@ -67,7 +67,7 @@ from .security import (
67
67
  detect_infinite_output,
68
68
  detect_sleep_block,
69
69
  )
70
- from .semantics import interpret_command_result
70
+ from .semantics import interpret_command_result, resolve_terminal_task_status
71
71
 
72
72
 
73
73
  def _as_bash_input_dict(data: dict[str, Any] | BashToolInput) -> dict[str, Any]:
@@ -728,12 +728,20 @@ class BashRuntimeTool(RuntimeTool):
728
728
 
729
729
  # 危险命令警告(非阻断)
730
730
  destructive_warning = detect_destructive_patterns(command)
731
- snapshot = self._backend.build_foreground_snapshot(result)
732
731
 
733
- # 退出码语义解析
732
+ # 退出码语义(SSOT:与 CC interpretCommandResult 一致,驱动 ok/error 与 task_status)
734
733
  cmd_result = interpret_command_result(
735
734
  command, result.exit_code, result.stdout
736
735
  )
736
+ terminal_status = resolve_terminal_task_status(
737
+ interrupted=result.interrupted,
738
+ exit_code=result.exit_code,
739
+ semantic=cmd_result,
740
+ )
741
+ snapshot = self._backend.build_foreground_snapshot(
742
+ result,
743
+ terminal_status=terminal_status,
744
+ )
737
745
 
738
746
  # 真正错误时抛异常(pipeline 捕获 → error envelope)
739
747
  if cmd_result.is_error and result.exit_code != 0 and not result.sandbox_violation_message:
@@ -881,6 +889,8 @@ class BashRuntimeTool(RuntimeTool):
881
889
  "interrupted": result.interrupted,
882
890
  "task_mode": result.task_mode,
883
891
  "task_status": result.task_status,
892
+ "return_code_interpretation": result.return_code_interpretation,
893
+ "no_output_expected": result.no_output_expected,
884
894
  }
885
895
 
886
896
  def to_auto_classifier_input(self, data: dict[str, Any]) -> str | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-agentx-python
3
- Version: 1.2.0
3
+ Version: 1.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=eShUyRBarEtTSEEDpas-_32s-g_j774Nm6m5Ie-mAEY,1678
1
+ langchain_agentx/__init__.py,sha256=gLxjoC92OvVi3mha5vefLza8Zsq5gQWFey0SROZ93nQ,1678
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
@@ -371,7 +371,7 @@ langchain_agentx/tool_runtime/permission_rules.py,sha256=ev6-Hm3N8YtbJO3SLGpoGMU
371
371
  langchain_agentx/tool_runtime/permission_settings_loader.py,sha256=Xu6dso0ghh4pb7Puf8nj20nXxjGeQvL4kIGycavwG_o,5624
372
372
  langchain_agentx/tool_runtime/permission_settings_sync.py,sha256=g6TvjWwa7D0kw5rDznPsoMv7xylESPOyWA2vZW4HDm0,4590
373
373
  langchain_agentx/tool_runtime/permission_snapshot.py,sha256=xFoi9fIcZjSw_zrIoyglneM-vJsDOLCEjiVoazr5Ack,1947
374
- langchain_agentx/tool_runtime/pipeline.py,sha256=GA77Cf_Q4o5Dfr-1VTS2r7rlbInWelIR4cMmkgBBXiw,53020
374
+ langchain_agentx/tool_runtime/pipeline.py,sha256=KiWYJJicYHlt2cVrVKQe0dnewLcrMXsKwGZ-Vsqk9pY,52885
375
375
  langchain_agentx/tool_runtime/policy.py,sha256=V0cd1GGxxxlLdReYWNEWu4L0hTIy2RCUhLF5NJ9WVhA,25975
376
376
  langchain_agentx/tool_runtime/policy_decorator.py,sha256=30tseo18ALkUINnRTZP8leTluQwkd0wPwiFCkj7A9d0,2334
377
377
  langchain_agentx/tool_runtime/process_loader.py,sha256=1YMn6ntnpdbIHJbO7wF1xuz7gNKYxK0UJAOxq96dZX4,6166
@@ -382,7 +382,7 @@ langchain_agentx/tool_runtime/registry.py,sha256=MsWqpbK4yx5pY7fi7DjspSlTbdoPwYt
382
382
  langchain_agentx/tool_runtime/session_hints.py,sha256=TyoNdSw5GsE5AvYDPHJKsrto9YXZtbAdihI8YKHdRxA,3004
383
383
  langchain_agentx/tool_runtime/session_store.py,sha256=o03ydnOzOo7HcUsu6F6AwoLgNFuRo1JpUodAl8Sx33Y,14262
384
384
  langchain_agentx/tool_runtime/shell_error.py,sha256=gi2i0sc4qHcUiLD5B2yk-wIvyVaOpLFKyf4ZnnKmAuE,2198
385
- langchain_agentx/tool_runtime/smoke_test_runtime.py,sha256=7cv8Dqha6XsqPLJhOZVTK-jxxfrHq-FuV5nixzrR8IQ,11534
385
+ langchain_agentx/tool_runtime/smoke_test_runtime.py,sha256=vOdoYdFwsWjq8k7rHD7hkgtgM5noGr9a6Wn1hHZ7354,11846
386
386
  langchain_agentx/tool_runtime/state_bridge.py,sha256=8F7jG8Uk4EVJaAB8rwKpNmbWrNZtIHYJO5RFBiwSRhs,6011
387
387
  langchain_agentx/tool_runtime/tool_message_status.py,sha256=ECJLsIEvUY5NyivZS17Zd8dDk3PfQC1lkJjgmOZXUck,2067
388
388
  langchain_agentx/tool_runtime/tool_name_constants.py,sha256=JXwKOn1ZjULgD7k3-1DEUmaGYJcw_NrQcCTQjqVSDBk,1769
@@ -477,7 +477,7 @@ langchain_agentx/tools/ask_user_question/validators.py,sha256=gUYuuKJNrExWGvhFlm
477
477
  langchain_agentx/tools/bash/__init__.py,sha256=molPHFDylE2wWG_aQx7fb0ciAx3wWpdXzIixTZV5ne4,214
478
478
  langchain_agentx/tools/bash/ast_security.py,sha256=-MlvQ559dR3vCactzAEnNAFEJB-QhZDXmDIqpPPpqR0,20874
479
479
  langchain_agentx/tools/bash/auto_mode_adapter.py,sha256=7-yb_kGmpytBYkD2Hn5YWPIceo_YN4PatEKj8O7HKsM,4243
480
- langchain_agentx/tools/bash/backend.py,sha256=_F1KEyEbNP20F9l2jzEFwEtm8KEgke2V4WTb1fETyss,62651
480
+ langchain_agentx/tools/bash/backend.py,sha256=6aTUefDv-z743kmlkVyt7mwtSiSJQFMue7f6FYcsl_I,63767
481
481
  langchain_agentx/tools/bash/bash_hardening.py,sha256=KEYKRC7kS_to4mzXuChvCmOIIb4dSUkOb9K1MBDtWDc,29296
482
482
  langchain_agentx/tools/bash/bash_runtime_contract.py,sha256=s8vrvMl7405KLGw2hPFbzlzWohm5JX3c9cImMBgqh8I,1511
483
483
  langchain_agentx/tools/bash/boundary_check.py,sha256=3B_Epe2NEJtLcNM3anNiCdOJdyNj_B3mOZ0mT_0bnpY,8010
@@ -494,17 +494,17 @@ langchain_agentx/tools/bash/output_utils.py,sha256=WYU2vVOjo9HQKSeQ_z88KxJsrvlFm
494
494
  langchain_agentx/tools/bash/path_security.py,sha256=L7zFXoyBDYLtd2bVLIeMg-xuCkSD7-Tt2EKlvKR_ssI,94984
495
495
  langchain_agentx/tools/bash/prompt.py,sha256=28WBRLt5G6e-OUildOFbeEyw7eL3iI8T40pEwmWVYxo,12527
496
496
  langchain_agentx/tools/bash/read_only_validation.py,sha256=rtNW6nK7sQMzR6LGc420kUd5wE30DnYX8jjuW7hUFWA,24822
497
- langchain_agentx/tools/bash/result_presenter.py,sha256=bUqpvcP2mo0FfOnI2v3Gu9mQGBATQQrHRL5dDYiv-yU,14420
497
+ langchain_agentx/tools/bash/result_presenter.py,sha256=OkJid40AmrAsRxhY7jSaw_PgRMoIfMcj6BNXaqcryTo,14946
498
498
  langchain_agentx/tools/bash/sandbox_decision.py,sha256=T_JaTfPADDcH2mRtrpKTBbIVo2Q6CHkzg_aUXCuDhLQ,4612
499
499
  langchain_agentx/tools/bash/security.py,sha256=YM34IUvNMDskoEA-WTG7hiuziY90DAFqQngpntGOtEc,7807
500
500
  langchain_agentx/tools/bash/sed_edit_parser.py,sha256=tTDLMj5f5C4nkcf1Ykn9uMKJtEQNm3ejrKQOal2sI9s,7855
501
501
  langchain_agentx/tools/bash/sed_validation.py,sha256=HA-zWe8Wo4LbgC9x8ZMQLzkd73i4IFeay0GhNb2qM20,5704
502
502
  langchain_agentx/tools/bash/semantic_matrix.py,sha256=rWO31jB2TxOSmCAMYKe3bkQ6YOHU7pCMX0--OABP5kM,3184
503
- langchain_agentx/tools/bash/semantics.py,sha256=JCewxOYCTGgYUsXXuCrc92ZWcIVyuqJZXTZzmN9xSGk,4602
503
+ langchain_agentx/tools/bash/semantics.py,sha256=pkf4URTulAOVL7m04Rq9JJF7z0J2mTEsGWrjyoY9r6o,5769
504
504
  langchain_agentx/tools/bash/shell_locator.py,sha256=AUnCZS8gmZurCs8rL4y0MMOS9UZimfg5rQ5At38mZKU,6296
505
505
  langchain_agentx/tools/bash/shell_quoting.py,sha256=K4JLVGwU8VpdQzfQB1o3xsq4HoCKHew1pry8hHChcoA,4498
506
506
  langchain_agentx/tools/bash/task_runtime.py,sha256=hikVC9YugtvpLf4nDaPlX_GFem1YQvDRwN0ShRflUYU,3568
507
- langchain_agentx/tools/bash/tool.py,sha256=U5iMC7ey9mDVWDSpk4cqn_u6fUWDi7A1mjeyiPBdSZU,44480
507
+ langchain_agentx/tools/bash/tool.py,sha256=OWPEyJQdqw2h2Abr9ZzLN0Vk0tS-2gIAGQt58CCXBms,44976
508
508
  langchain_agentx/tools/bash/windows_shell_quoting.py,sha256=0RzLnTKyFrJ536QzqPZvSyUcQWN794XRlAq2RdHeKHo,1615
509
509
  langchain_agentx/tools/edit/__init__.py,sha256=PiiOHUODUzTRQxxPdE7ZMTjd3vfdzm9LEcn1lpVtg8o,203
510
510
  langchain_agentx/tools/edit/backend.py,sha256=JrikYafZDGMQ2JjXRxbnv1VSHVGRUdLmZN__nnqkM9o,3159
@@ -651,8 +651,8 @@ langchain_agentx/workspace/root_grant_manager.py,sha256=W3gy8HTevbERbXqIgRcjzOXO
651
651
  langchain_agentx/workspace/tool_boundary.py,sha256=UDwX6swpSLsx9HNkYuuRRiV5o7ZZG_Bru2Yn0c5kNX8,5724
652
652
  langchain_agentx/workspace/validators.py,sha256=tQt-6TOcL8Fw7Ig5ebA9S7vGWh1rby920eFW6x8Tk9E,1439
653
653
  langchain_agentx/workspace/view.py,sha256=Ip02CZNI-ZjF5k0OYT3q7RUR_auMEw83VJ6rQsaBcYU,4588
654
- langchain_agentx_python-1.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
655
- langchain_agentx_python-1.2.0.dist-info/METADATA,sha256=IN82e5NR5TnofjYdnjcpl4kcww4N-TVy7kKECC4uFRg,24846
656
- langchain_agentx_python-1.2.0.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
657
- langchain_agentx_python-1.2.0.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
658
- langchain_agentx_python-1.2.0.dist-info/RECORD,,
654
+ langchain_agentx_python-1.2.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
655
+ langchain_agentx_python-1.2.2.dist-info/METADATA,sha256=SFntj7m8EPCZwMIFq8WVSfPi55YiHnr5WHpCc87QU9M,24846
656
+ langchain_agentx_python-1.2.2.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
657
+ langchain_agentx_python-1.2.2.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
658
+ langchain_agentx_python-1.2.2.dist-info/RECORD,,