langchain-agentx-python 0.2.6__py3-none-any.whl → 0.2.7__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.
@@ -461,6 +461,20 @@ class LoopControllerEdge:
461
461
  ) -> str | None:
462
462
  if terminal_reason != TERMINAL_REASON_MAX_STEPS:
463
463
  return None
464
+
465
+ # 防重入保护:如果已经给过机会(force_text_exit=True),直接终止
466
+ if state.get("force_text_exit"):
467
+ # 已经注入过 MAX_STEPS_PROMPT 且清空了工具,模型仍返回 tool_calls 或未正确退出
468
+ # 此时直接终止,避免无限循环
469
+ emit_loop_decision_event(
470
+ state=state,
471
+ decision="terminal",
472
+ selected_edge=self._task_reconcile_or_end(state),
473
+ reason_code="max_steps_force_text_exit_failed",
474
+ evidence={"step": state.get("step", 0), "reason": "model did not comply with force_text_exit"},
475
+ )
476
+ return self._task_reconcile_or_end(state)
477
+
464
478
  messages = list(state.get("messages") or [])
465
479
  messages.append(AIMessage(content=MAX_STEPS_PROMPT))
466
480
  state["messages"] = messages
@@ -358,9 +358,12 @@ class ModelNode(Runnable):
358
358
  SystemMessage(content=effective) if effective is not None else None
359
359
  )
360
360
 
361
+ # force_text_exit: max_steps 达限时,清空工具列表强制模型输出文本
362
+ tools = [] if state.get("force_text_exit") else self._default_tools
363
+
361
364
  return _ModelRequest(
362
365
  model=self._model,
363
- tools=self._default_tools,
366
+ tools=tools,
364
367
  system_message=system_message,
365
368
  response_format=self._initial_response_format,
366
369
  messages=state.get("messages", []),
@@ -260,9 +260,12 @@ class _ModelNodeBuilder:
260
260
  )
261
261
  system_message = _SystemMessage(content=effective) if effective is not None else None
262
262
 
263
+ # force_text_exit: max_steps 达限时,清空工具列表强制模型输出文本
264
+ tools = [] if state.get("force_text_exit") else self._default_tools
265
+
263
266
  return _ModelRequest(
264
267
  model=self._model,
265
- tools=self._default_tools,
268
+ tools=tools,
266
269
  system_message=system_message,
267
270
  response_format=self._initial_response_format,
268
271
  messages=state["messages"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langchain-agentx-python
3
- Version: 0.2.6
3
+ Version: 0.2.7
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
@@ -42,7 +42,7 @@ langchain_agentx/loop/exit/reason_codes.py,sha256=vQcsqfute1_weyxtDDWm7CR6vvt6eP
42
42
  langchain_agentx/loop/graph/__init__.py,sha256=9pUUqn7G87n3lV45iYIU24j0wcTHyCD--SSdtv3urh4,136
43
43
  langchain_agentx/loop/graph/builtin_loop_control.py,sha256=bkf__SSMzmR_SvZWhH-QdfjWZEpnnrP29CjGjjcQPeY,6955
44
44
  langchain_agentx/loop/graph/factory.py,sha256=9CtxzlIM6iqWLGaHcUcf2SWZB9BulwVht7wiFu-LrVs,63529
45
- langchain_agentx/loop/graph/graph_edges.py,sha256=d_baPcRZNiEj1Cbeoieduj5fscNu4EpggajPDjtCJp8,31784
45
+ langchain_agentx/loop/graph/graph_edges.py,sha256=uUCcRyI5NpZMghV6T5QmcBEO2aHZQXhhYgzaBJwhY84,32503
46
46
  langchain_agentx/loop/hook/__init__.py,sha256=LS5AE6Flqg3btLe0MQ7qDZRjaf1AdHiZYdEgQ96vbOQ,1255
47
47
  langchain_agentx/loop/hook/async_hook_runner.py,sha256=UIrdpgAcUumyxs7ASeJh6ehK2NSo-FDQVj9ICpuPook,2146
48
48
  langchain_agentx/loop/hook/config.py,sha256=f8XtGGHtyjuRvZNhkU8ohbhyqOHD7mHZn_w0rVXMX_o,9157
@@ -59,8 +59,8 @@ langchain_agentx/loop/hook/executors/prompt.py,sha256=oYwOk-acH-dopzfzNUEjpPdXGk
59
59
  langchain_agentx/loop/injection/__init__.py,sha256=rEiAXYqdr_Ry8mhHBu6xZKLypnyJOxcxNe6sJns1rnc,362
60
60
  langchain_agentx/loop/injection/dedup.py,sha256=5wv-Tb8HUean9C82VazVIkTkQdIZi9gewMABukiclpI,2548
61
61
  langchain_agentx/loop/model/__init__.py,sha256=8wOiwa2Yvh7QdR6ilhk4faI7_iwNT6QSEFgewJNhhOw,57
62
- langchain_agentx/loop/model/model_node.py,sha256=iMJMtqF43nrHksnAWHf1fyabSju7NUDX4_mRpvfaYG4,28049
63
- langchain_agentx/loop/model/model_nodes.py,sha256=_pvAkdNrVi3pOd_51oJMKcgyP2LqPblBHCfhR6I2pIg,26800
62
+ langchain_agentx/loop/model/model_node.py,sha256=mKSQfA_ydRVz07J1s8_T2IlzkvFFOY2QZpjjPFbiCKY,28204
63
+ langchain_agentx/loop/model/model_nodes.py,sha256=4nctxTm3FHdMQ35Tp_y2hUm4q9AYa9HiMI9xXheFAYM,26955
64
64
  langchain_agentx/loop/model/orphan_tool_results.py,sha256=sQd2_Y0y9wSLsMZnkQybuEp1gSYGpMWYkwt19LVzY-8,1299
65
65
  langchain_agentx/loop/model/retrier.py,sha256=XGDTsTEJDs6z_tR5vN57szUR7Uw2EJgVY5qzQWf1Yas,10045
66
66
  langchain_agentx/loop/model/retry_bridge.py,sha256=L__s8_MWDKM7VXWaPRyhpR8Kj2luU46Hw5U-XX4g7kU,1701
@@ -426,8 +426,8 @@ langchain_agentx/workspace/config.py,sha256=K2XaAvlkBr5aA2mgH5zNxfAZg-LGmwwDVNcE
426
426
  langchain_agentx/workspace/path_key_normalizer.py,sha256=ICk9uGiiNFH-zaXJG3_vx91uOpgWmgOPIjJoSYevKOc,1113
427
427
  langchain_agentx/workspace/resolver.py,sha256=9-wRLLIC7KJCqu9i8nAL-gJ9lIWsTPOpjnZnZEGLunk,6281
428
428
  langchain_agentx/workspace/validators.py,sha256=tQt-6TOcL8Fw7Ig5ebA9S7vGWh1rby920eFW6x8Tk9E,1439
429
- langchain_agentx_python-0.2.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
430
- langchain_agentx_python-0.2.6.dist-info/METADATA,sha256=RFuBcDbK_VR4VNFrR96ZJGdtcNd4-oie-58TuX5EfIw,20832
431
- langchain_agentx_python-0.2.6.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
432
- langchain_agentx_python-0.2.6.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
433
- langchain_agentx_python-0.2.6.dist-info/RECORD,,
429
+ langchain_agentx_python-0.2.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
430
+ langchain_agentx_python-0.2.7.dist-info/METADATA,sha256=KrzGeFFyKrqzkLkslngHHJekkwNTpnpc5Qe5DnGcu90,20832
431
+ langchain_agentx_python-0.2.7.dist-info/WHEEL,sha256=51RkbunBAw4BWsgaQWTpPhg4Diwp3c9P5iaLk67Hdtg,92
432
+ langchain_agentx_python-0.2.7.dist-info/top_level.txt,sha256=Ge284pniNt8xea0OLk2o9o32GqVpDhOYk20fwE-0xxA,17
433
+ langchain_agentx_python-0.2.7.dist-info/RECORD,,