langchain-agentx-python 0.1__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.
Files changed (354) hide show
  1. langchain_agentx/__init__.py +46 -0
  2. langchain_agentx/command/__init__.py +28 -0
  3. langchain_agentx/command/builtin/__init__.py +25 -0
  4. langchain_agentx/command/builtin/clear.py +33 -0
  5. langchain_agentx/command/builtin/compact.py +33 -0
  6. langchain_agentx/command/builtin/memory.py +37 -0
  7. langchain_agentx/command/builtin/reload_plugins.py +42 -0
  8. langchain_agentx/command/context.py +30 -0
  9. langchain_agentx/command/dispatcher.py +183 -0
  10. langchain_agentx/command/registry.py +110 -0
  11. langchain_agentx/command/result.py +25 -0
  12. langchain_agentx/command/types.py +41 -0
  13. langchain_agentx/config/__init__.py +14 -0
  14. langchain_agentx/loop/__init__.py +47 -0
  15. langchain_agentx/loop/config/__init__.py +20 -0
  16. langchain_agentx/loop/config/agent_config.py +66 -0
  17. langchain_agentx/loop/config/agent_loop_config.py +72 -0
  18. langchain_agentx/loop/config/model_context_resolver.py +105 -0
  19. langchain_agentx/loop/config/runtime_settings.py +50 -0
  20. langchain_agentx/loop/config/token_estimator.py +133 -0
  21. langchain_agentx/loop/context/__init__.py +66 -0
  22. langchain_agentx/loop/context/blocking_guard.py +97 -0
  23. langchain_agentx/loop/context/compaction_service.py +60 -0
  24. langchain_agentx/loop/context/message_utils.py +56 -0
  25. langchain_agentx/loop/context/pipeline.py +127 -0
  26. langchain_agentx/loop/context/settings.py +103 -0
  27. langchain_agentx/loop/context/stages/__init__.py +29 -0
  28. langchain_agentx/loop/context/stages/autocompact.py +140 -0
  29. langchain_agentx/loop/context/stages/base.py +32 -0
  30. langchain_agentx/loop/context/stages/collapse.py +76 -0
  31. langchain_agentx/loop/context/stages/microcompact.py +76 -0
  32. langchain_agentx/loop/context/stages/noop.py +33 -0
  33. langchain_agentx/loop/context/stages/snip.py +71 -0
  34. langchain_agentx/loop/context/stages/tool_result_budget.py +69 -0
  35. langchain_agentx/loop/context/types.py +79 -0
  36. langchain_agentx/loop/exit/__init__.py +1 -0
  37. langchain_agentx/loop/exit/exit_logic.py +320 -0
  38. langchain_agentx/loop/exit/reason_codes.py +39 -0
  39. langchain_agentx/loop/graph/__init__.py +5 -0
  40. langchain_agentx/loop/graph/builtin_loop_control.py +197 -0
  41. langchain_agentx/loop/graph/factory.py +1409 -0
  42. langchain_agentx/loop/graph/graph_edges.py +820 -0
  43. langchain_agentx/loop/hook/__init__.py +48 -0
  44. langchain_agentx/loop/hook/async_hook_runner.py +62 -0
  45. langchain_agentx/loop/hook/config.py +280 -0
  46. langchain_agentx/loop/hook/engine.py +321 -0
  47. langchain_agentx/loop/hook/executors/__init__.py +9 -0
  48. langchain_agentx/loop/hook/executors/agent.py +107 -0
  49. langchain_agentx/loop/hook/executors/command.py +230 -0
  50. langchain_agentx/loop/hook/executors/http.py +114 -0
  51. langchain_agentx/loop/hook/executors/prompt.py +92 -0
  52. langchain_agentx/loop/hook/graph_wiring.py +134 -0
  53. langchain_agentx/loop/hook/registry.py +262 -0
  54. langchain_agentx/loop/hook/trust.py +43 -0
  55. langchain_agentx/loop/hook/types.py +110 -0
  56. langchain_agentx/loop/injection/__init__.py +13 -0
  57. langchain_agentx/loop/injection/dedup.py +74 -0
  58. langchain_agentx/loop/loop_abort.py +36 -0
  59. langchain_agentx/loop/model/__init__.py +1 -0
  60. langchain_agentx/loop/model/model_node.py +648 -0
  61. langchain_agentx/loop/model/model_nodes.py +661 -0
  62. langchain_agentx/loop/model/orphan_tool_results.py +38 -0
  63. langchain_agentx/loop/model/retrier.py +307 -0
  64. langchain_agentx/loop/model/retry_bridge.py +58 -0
  65. langchain_agentx/loop/model/retry_events.py +35 -0
  66. langchain_agentx/loop/model/retry_policy.py +56 -0
  67. langchain_agentx/loop/model/schema_and_format.py +153 -0
  68. langchain_agentx/loop/model/tool_and_model_binding.py +227 -0
  69. langchain_agentx/loop/model/tool_call_degradation_corrector.py +443 -0
  70. langchain_agentx/loop/model/tool_transcript_guard.py +225 -0
  71. langchain_agentx/loop/prompt/__init__.py +95 -0
  72. langchain_agentx/loop/prompt/builder.py +61 -0
  73. langchain_agentx/loop/prompt/builtin.py +218 -0
  74. langchain_agentx/loop/prompt/compact.py +408 -0
  75. langchain_agentx/loop/prompt/sections.py +120 -0
  76. langchain_agentx/loop/runtime/__init__.py +19 -0
  77. langchain_agentx/loop/runtime/context.py +34 -0
  78. langchain_agentx/loop/runtime/context_factory.py +107 -0
  79. langchain_agentx/loop/runtime/subagent_execution_paths.py +68 -0
  80. langchain_agentx/loop/subagent/__init__.py +53 -0
  81. langchain_agentx/loop/subagent/async_runner.py +215 -0
  82. langchain_agentx/loop/subagent/context.py +209 -0
  83. langchain_agentx/loop/subagent/fork_worktree_notice.py +25 -0
  84. langchain_agentx/loop/subagent/graph.py +72 -0
  85. langchain_agentx/loop/subagent/orchestrator.py +391 -0
  86. langchain_agentx/loop/subagent/progress.py +30 -0
  87. langchain_agentx/loop/subagent/prompt.py +52 -0
  88. langchain_agentx/loop/subagent/runner.py +504 -0
  89. langchain_agentx/loop/subagent/transcript.py +172 -0
  90. langchain_agentx/memory/__init__.py +2 -0
  91. langchain_agentx/memory/instruction/__init__.py +12 -0
  92. langchain_agentx/memory/instruction/loader.py +325 -0
  93. langchain_agentx/memory/instruction/resolver.py +24 -0
  94. langchain_agentx/memory/instruction/runtime.py +83 -0
  95. langchain_agentx/memory/instruction/sections.py +83 -0
  96. langchain_agentx/memory/instruction/types.py +59 -0
  97. langchain_agentx/memory/memdir/__init__.py +77 -0
  98. langchain_agentx/memory/memdir/age.py +36 -0
  99. langchain_agentx/memory/memdir/agent_memory.py +380 -0
  100. langchain_agentx/memory/memdir/extractor.py +309 -0
  101. langchain_agentx/memory/memdir/loader.py +187 -0
  102. langchain_agentx/memory/memdir/paths.py +63 -0
  103. langchain_agentx/memory/memdir/recall.py +45 -0
  104. langchain_agentx/memory/memdir/runtime.py +43 -0
  105. langchain_agentx/memory/memdir/scan.py +135 -0
  106. langchain_agentx/memory/memdir/types.py +104 -0
  107. langchain_agentx/memory/session/__init__.py +76 -0
  108. langchain_agentx/memory/session/compact_bridge.py +208 -0
  109. langchain_agentx/memory/session/prompts.py +172 -0
  110. langchain_agentx/memory/session/session_memory.py +282 -0
  111. langchain_agentx/observability/__init__.py +67 -0
  112. langchain_agentx/observability/evaluation/__init__.py +17 -0
  113. langchain_agentx/observability/evaluation/checkers/__init__.py +18 -0
  114. langchain_agentx/observability/evaluation/checkers/base.py +34 -0
  115. langchain_agentx/observability/evaluation/checkers/compaction.py +38 -0
  116. langchain_agentx/observability/evaluation/checkers/degradation.py +50 -0
  117. langchain_agentx/observability/evaluation/checkers/exit_quality.py +42 -0
  118. langchain_agentx/observability/evaluation/checkers/session_memory.py +45 -0
  119. langchain_agentx/observability/evaluation/checkers/tool_behavior.py +53 -0
  120. langchain_agentx/observability/evaluation/retention_scheduler.py +67 -0
  121. langchain_agentx/observability/evaluation/service.py +102 -0
  122. langchain_agentx/observability/evaluation/state.py +32 -0
  123. langchain_agentx/observability/evaluation/store.py +258 -0
  124. langchain_agentx/observability/events/__init__.py +15 -0
  125. langchain_agentx/observability/events/langchain_agentx_event_adapter.py +832 -0
  126. langchain_agentx/observability/logging/__init__.py +15 -0
  127. langchain_agentx/observability/logging/debug_burst.py +95 -0
  128. langchain_agentx/observability/logging/logging_config.py +178 -0
  129. langchain_agentx/observability/logging/logging_contract.py +65 -0
  130. langchain_agentx/observability/replay/__init__.py +35 -0
  131. langchain_agentx/observability/replay/cli.py +91 -0
  132. langchain_agentx/observability/replay/service.py +83 -0
  133. langchain_agentx/observability/replay/store.py +278 -0
  134. langchain_agentx/observability/replay/ui.py +47 -0
  135. langchain_agentx/observability/trace/__init__.py +25 -0
  136. langchain_agentx/observability/trace/collector.py +560 -0
  137. langchain_agentx/observability/trace/event_emitter.py +183 -0
  138. langchain_agentx/observability/trace/hook_event_emitter.py +49 -0
  139. langchain_agentx/observability/trace/models.py +144 -0
  140. langchain_agentx/observability/trace/sqlite_store.py +873 -0
  141. langchain_agentx/observability/trace/trace_callback.py +295 -0
  142. langchain_agentx/observability/trace/trace_lifecycle_collector.py +114 -0
  143. langchain_agentx/plugin/__init__.py +26 -0
  144. langchain_agentx/plugin/builtin.py +53 -0
  145. langchain_agentx/plugin/config.py +113 -0
  146. langchain_agentx/plugin/loader.py +386 -0
  147. langchain_agentx/plugin/manifest.py +154 -0
  148. langchain_agentx/plugin/registries.py +211 -0
  149. langchain_agentx/plugin/types.py +142 -0
  150. langchain_agentx/provider/__init__.py +27 -0
  151. langchain_agentx/provider/anthropic.py +121 -0
  152. langchain_agentx/provider/compatible_chat_openai.py +86 -0
  153. langchain_agentx/provider/env.py +45 -0
  154. langchain_agentx/provider/model_profile.py +156 -0
  155. langchain_agentx/provider/openai.py +89 -0
  156. langchain_agentx/session/__init__.py +17 -0
  157. langchain_agentx/session/agent_session.py +320 -0
  158. langchain_agentx/session/conversation_factory.py +87 -0
  159. langchain_agentx/session/conversation_recovery.py +156 -0
  160. langchain_agentx/session/conversation_session.py +198 -0
  161. langchain_agentx/session/factory.py +143 -0
  162. langchain_agentx/session/protocol.py +25 -0
  163. langchain_agentx/task_runtime/__init__.py +113 -0
  164. langchain_agentx/task_runtime/core/__init__.py +51 -0
  165. langchain_agentx/task_runtime/core/ids.py +33 -0
  166. langchain_agentx/task_runtime/core/interfaces.py +115 -0
  167. langchain_agentx/task_runtime/core/notification_priority.py +19 -0
  168. langchain_agentx/task_runtime/core/types.py +136 -0
  169. langchain_agentx/task_runtime/integrations/__init__.py +33 -0
  170. langchain_agentx/task_runtime/integrations/loop_adapter.py +91 -0
  171. langchain_agentx/task_runtime/integrations/loop_integration.py +61 -0
  172. langchain_agentx/task_runtime/integrations/prefetch_providers.py +108 -0
  173. langchain_agentx/task_runtime/integrations/provider_factory.py +103 -0
  174. langchain_agentx/task_runtime/integrations/queued_command_provider.py +184 -0
  175. langchain_agentx/task_runtime/integrations/sqlite_queued_command_provider.py +338 -0
  176. langchain_agentx/task_runtime/integrations/tool_use_summary_provider.py +254 -0
  177. langchain_agentx/task_runtime/orchestrator/__init__.py +5 -0
  178. langchain_agentx/task_runtime/orchestrator/runtime.py +386 -0
  179. langchain_agentx/task_runtime/output/__init__.py +5 -0
  180. langchain_agentx/task_runtime/output/sink.py +64 -0
  181. langchain_agentx/task_runtime/policy/__init__.py +11 -0
  182. langchain_agentx/task_runtime/policy/withhold_visibility.py +32 -0
  183. langchain_agentx/task_runtime/queue/__init__.py +5 -0
  184. langchain_agentx/task_runtime/queue/in_memory.py +55 -0
  185. langchain_agentx/task_runtime/skill_prefetch/__init__.py +4 -0
  186. langchain_agentx/task_runtime/skill_prefetch/attachments.py +46 -0
  187. langchain_agentx/task_runtime/skill_prefetch/models.py +37 -0
  188. langchain_agentx/task_runtime/skill_prefetch/provider.py +344 -0
  189. langchain_agentx/task_runtime/store/__init__.py +6 -0
  190. langchain_agentx/task_runtime/store/in_memory.py +81 -0
  191. langchain_agentx/task_runtime/store/sqlite_store.py +281 -0
  192. langchain_agentx/task_runtime/tasks/__init__.py +76 -0
  193. langchain_agentx/task_runtime/tasks/ai_analysis/__init__.py +15 -0
  194. langchain_agentx/task_runtime/tasks/ai_analysis/base.py +41 -0
  195. langchain_agentx/task_runtime/tasks/ai_analysis/evaluation.py +67 -0
  196. langchain_agentx/task_runtime/tasks/ai_analysis/registry.py +36 -0
  197. langchain_agentx/task_runtime/tasks/ai_analysis/scheduler.py +70 -0
  198. langchain_agentx/task_runtime/tasks/base/__init__.py +6 -0
  199. langchain_agentx/task_runtime/tasks/base/contracts.py +24 -0
  200. langchain_agentx/task_runtime/tasks/custom/__init__.py +7 -0
  201. langchain_agentx/task_runtime/tasks/custom/executor.py +60 -0
  202. langchain_agentx/task_runtime/tasks/custom/notification.py +7 -0
  203. langchain_agentx/task_runtime/tasks/custom/semantics.py +13 -0
  204. langchain_agentx/task_runtime/tasks/custom/spec.py +33 -0
  205. langchain_agentx/task_runtime/tasks/dream_task/__init__.py +15 -0
  206. langchain_agentx/task_runtime/tasks/dream_task/executor.py +61 -0
  207. langchain_agentx/task_runtime/tasks/dream_task/notification.py +19 -0
  208. langchain_agentx/task_runtime/tasks/dream_task/semantics.py +13 -0
  209. langchain_agentx/task_runtime/tasks/dream_task/spec.py +35 -0
  210. langchain_agentx/task_runtime/tasks/dream_task/state.py +17 -0
  211. langchain_agentx/task_runtime/tasks/in_process_teammate/__init__.py +12 -0
  212. langchain_agentx/task_runtime/tasks/in_process_teammate/executor.py +36 -0
  213. langchain_agentx/task_runtime/tasks/in_process_teammate/notification.py +25 -0
  214. langchain_agentx/task_runtime/tasks/in_process_teammate/semantics.py +13 -0
  215. langchain_agentx/task_runtime/tasks/in_process_teammate/spec.py +63 -0
  216. langchain_agentx/task_runtime/tasks/local_agent/__init__.py +14 -0
  217. langchain_agentx/task_runtime/tasks/local_agent/executor.py +33 -0
  218. langchain_agentx/task_runtime/tasks/local_agent/notification.py +21 -0
  219. langchain_agentx/task_runtime/tasks/local_agent/runner.py +43 -0
  220. langchain_agentx/task_runtime/tasks/local_agent/semantics.py +13 -0
  221. langchain_agentx/task_runtime/tasks/local_agent/spec.py +31 -0
  222. langchain_agentx/task_runtime/tasks/local_bash/__init__.py +13 -0
  223. langchain_agentx/task_runtime/tasks/local_bash/executor.py +95 -0
  224. langchain_agentx/task_runtime/tasks/local_bash/notification.py +22 -0
  225. langchain_agentx/task_runtime/tasks/local_bash/semantics.py +13 -0
  226. langchain_agentx/task_runtime/tasks/local_bash/spec.py +55 -0
  227. langchain_agentx/task_runtime/tasks/remote_agent/__init__.py +19 -0
  228. langchain_agentx/task_runtime/tasks/remote_agent/backend.py +76 -0
  229. langchain_agentx/task_runtime/tasks/remote_agent/executor.py +37 -0
  230. langchain_agentx/task_runtime/tasks/remote_agent/notification.py +22 -0
  231. langchain_agentx/task_runtime/tasks/remote_agent/semantics.py +13 -0
  232. langchain_agentx/task_runtime/tasks/remote_agent/spec.py +34 -0
  233. langchain_agentx/task_runtime/tasks/trace_cleanup/__init__.py +19 -0
  234. langchain_agentx/task_runtime/tasks/trace_cleanup/bootstrap.py +95 -0
  235. langchain_agentx/task_runtime/tasks/trace_cleanup/executor.py +66 -0
  236. langchain_agentx/task_runtime/tasks/trace_cleanup/scheduler.py +169 -0
  237. langchain_agentx/tool_runtime/__init__.py +90 -0
  238. langchain_agentx/tool_runtime/adapter.py +365 -0
  239. langchain_agentx/tool_runtime/base.py +319 -0
  240. langchain_agentx/tool_runtime/errors.py +190 -0
  241. langchain_agentx/tool_runtime/identical_call_cache.py +110 -0
  242. langchain_agentx/tool_runtime/loader.py +195 -0
  243. langchain_agentx/tool_runtime/models.py +260 -0
  244. langchain_agentx/tool_runtime/permission_context.py +78 -0
  245. langchain_agentx/tool_runtime/pipeline.py +621 -0
  246. langchain_agentx/tool_runtime/policy.py +447 -0
  247. langchain_agentx/tool_runtime/registry.py +81 -0
  248. langchain_agentx/tool_runtime/resolvers/__init__.py +27 -0
  249. langchain_agentx/tool_runtime/resolvers/agent_session.py +125 -0
  250. langchain_agentx/tool_runtime/resolvers/background.py +32 -0
  251. langchain_agentx/tool_runtime/resolvers/base.py +20 -0
  252. langchain_agentx/tool_runtime/resolvers/conversation.py +22 -0
  253. langchain_agentx/tool_runtime/resolvers/workflow.py +73 -0
  254. langchain_agentx/tool_runtime/session_store.py +132 -0
  255. langchain_agentx/tool_runtime/smoke_test_runtime.py +294 -0
  256. langchain_agentx/tool_runtime/state_bridge.py +164 -0
  257. langchain_agentx/tools/__init__.py +26 -0
  258. langchain_agentx/tools/agent/__init__.py +9 -0
  259. langchain_agentx/tools/agent/backend.py +53 -0
  260. langchain_agentx/tools/agent/built_in/__init__.py +19 -0
  261. langchain_agentx/tools/agent/built_in/agentx_guide.py +65 -0
  262. langchain_agentx/tools/agent/built_in/explore.py +80 -0
  263. langchain_agentx/tools/agent/built_in/general.py +57 -0
  264. langchain_agentx/tools/agent/built_in/plan.py +89 -0
  265. langchain_agentx/tools/agent/built_in/statusline_setup.py +64 -0
  266. langchain_agentx/tools/agent/built_in/verification.py +120 -0
  267. langchain_agentx/tools/agent/builtin_subagent_loader.py +89 -0
  268. langchain_agentx/tools/agent/cwd_resolution.py +119 -0
  269. langchain_agentx/tools/agent/limits.py +26 -0
  270. langchain_agentx/tools/agent/loader.py +270 -0
  271. langchain_agentx/tools/agent/models.py +85 -0
  272. langchain_agentx/tools/agent/prompt.py +120 -0
  273. langchain_agentx/tools/agent/registry/__init__.py +18 -0
  274. langchain_agentx/tools/agent/registry/config.py +29 -0
  275. langchain_agentx/tools/agent/registry/registry.py +47 -0
  276. langchain_agentx/tools/agent/scope.py +137 -0
  277. langchain_agentx/tools/agent/tool.py +256 -0
  278. langchain_agentx/tools/bash/__init__.py +9 -0
  279. langchain_agentx/tools/bash/ast_security.py +571 -0
  280. langchain_agentx/tools/bash/backend.py +1447 -0
  281. langchain_agentx/tools/bash/bash_hardening.py +734 -0
  282. langchain_agentx/tools/bash/bash_runtime_contract.py +41 -0
  283. langchain_agentx/tools/bash/cwd_reporter.py +95 -0
  284. langchain_agentx/tools/bash/limits.py +71 -0
  285. langchain_agentx/tools/bash/mode_validation.py +282 -0
  286. langchain_agentx/tools/bash/models.py +131 -0
  287. langchain_agentx/tools/bash/observability.py +148 -0
  288. langchain_agentx/tools/bash/output_utils.py +200 -0
  289. langchain_agentx/tools/bash/path_security.py +2429 -0
  290. langchain_agentx/tools/bash/prompt.py +68 -0
  291. langchain_agentx/tools/bash/read_only_validation.py +589 -0
  292. langchain_agentx/tools/bash/result_presenter.py +324 -0
  293. langchain_agentx/tools/bash/sandbox_decision.py +133 -0
  294. langchain_agentx/tools/bash/security.py +311 -0
  295. langchain_agentx/tools/bash/sed_edit_parser.py +243 -0
  296. langchain_agentx/tools/bash/sed_validation.py +163 -0
  297. langchain_agentx/tools/bash/semantics.py +111 -0
  298. langchain_agentx/tools/bash/session_manager.py +205 -0
  299. langchain_agentx/tools/bash/session_runtime.py +290 -0
  300. langchain_agentx/tools/bash/shell_locator.py +191 -0
  301. langchain_agentx/tools/bash/task_runtime.py +91 -0
  302. langchain_agentx/tools/bash/tool.py +939 -0
  303. langchain_agentx/tools/bash/windows_shell_quoting.py +45 -0
  304. langchain_agentx/tools/glob/__init__.py +9 -0
  305. langchain_agentx/tools/glob/models.py +57 -0
  306. langchain_agentx/tools/glob/pagination.py +30 -0
  307. langchain_agentx/tools/glob/prompt.py +24 -0
  308. langchain_agentx/tools/glob/rg_list_backend.py +139 -0
  309. langchain_agentx/tools/glob/rg_pattern.py +44 -0
  310. langchain_agentx/tools/glob/tool.py +327 -0
  311. langchain_agentx/tools/grep/__init__.py +7 -0
  312. langchain_agentx/tools/grep/backend.py +375 -0
  313. langchain_agentx/tools/grep/models.py +127 -0
  314. langchain_agentx/tools/grep/prompt.py +30 -0
  315. langchain_agentx/tools/grep/rg_subprocess_controller.py +114 -0
  316. langchain_agentx/tools/grep/tool.py +475 -0
  317. langchain_agentx/tools/read/__init__.py +9 -0
  318. langchain_agentx/tools/read/backend.py +415 -0
  319. langchain_agentx/tools/read/limits.py +67 -0
  320. langchain_agentx/tools/read/models.py +156 -0
  321. langchain_agentx/tools/read/prompt.py +73 -0
  322. langchain_agentx/tools/read/tool.py +494 -0
  323. langchain_agentx/tools/ripgrep_plugin_exclusions.py +137 -0
  324. langchain_agentx/tools/skill/__init__.py +4 -0
  325. langchain_agentx/tools/skill/argument_substitution.py +80 -0
  326. langchain_agentx/tools/skill/loader.py +196 -0
  327. langchain_agentx/tools/skill/models.py +88 -0
  328. langchain_agentx/tools/skill/policy.py +80 -0
  329. langchain_agentx/tools/skill/prompt.py +35 -0
  330. langchain_agentx/tools/skill/tool.py +222 -0
  331. langchain_agentx/utils/__init__.py +0 -0
  332. langchain_agentx/utils/cwd.py +124 -0
  333. langchain_agentx/utils/host_platform.py +112 -0
  334. langchain_agentx/utils/path_hierarchy.py +48 -0
  335. langchain_agentx/utils/path_user_input.py +66 -0
  336. langchain_agentx/utils/rg_executable.py +18 -0
  337. langchain_agentx/utils/subprocess_text.py +101 -0
  338. langchain_agentx/utils/temp_paths.py +77 -0
  339. langchain_agentx/utils/unc_path.py +25 -0
  340. langchain_agentx/utils/win_reserved_paths.py +51 -0
  341. langchain_agentx/workflow/__init__.py +7 -0
  342. langchain_agentx/workflow/base.py +97 -0
  343. langchain_agentx/workflow/batch.py +55 -0
  344. langchain_agentx/workflow/dag.py +54 -0
  345. langchain_agentx/workspace/__init__.py +13 -0
  346. langchain_agentx/workspace/config.py +140 -0
  347. langchain_agentx/workspace/path_key_normalizer.py +30 -0
  348. langchain_agentx/workspace/resolver.py +74 -0
  349. langchain_agentx/workspace/validators.py +41 -0
  350. langchain_agentx_python-0.1.dist-info/LICENSE +201 -0
  351. langchain_agentx_python-0.1.dist-info/METADATA +513 -0
  352. langchain_agentx_python-0.1.dist-info/RECORD +354 -0
  353. langchain_agentx_python-0.1.dist-info/WHEEL +5 -0
  354. langchain_agentx_python-0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,48 @@
1
+ """
2
+ loop.hook — Hook 子系统(P1/P2)。
3
+
4
+ 职责:
5
+ 提供 Hook 定义、配置快照与执行引擎的公共导出。
6
+
7
+ 链路位置:
8
+ 由 loop 图装配层调用,用于替代历史中间件机制。
9
+
10
+ 当前裁剪范围:
11
+ 已包含 P1 + P2 基础执行器导出;并行聚合与治理细节见 HookEngine/规划文档。
12
+ """
13
+
14
+ from .config import HookCandidate, HookCandidateDecision, HookSpec, HooksConfigSnapshot
15
+ from .async_hook_runner import AsyncHookRunner
16
+ from .engine import HookEngine
17
+ from .executors import AgentExecutor, CommandExecutor, HttpExecutor, PromptExecutor
18
+ from .graph_wiring import HookGraphWiring
19
+ from .registry import HookRegistry
20
+ from .trust import WorkspaceTrustChecker
21
+ from .types import (
22
+ AggregatedHookResult,
23
+ HookContext,
24
+ HookEvent,
25
+ HookExecutionRecord,
26
+ HookResult,
27
+ )
28
+
29
+ __all__ = [
30
+ "AggregatedHookResult",
31
+ "AsyncHookRunner",
32
+ "HookCandidate",
33
+ "HookCandidateDecision",
34
+ "HookContext",
35
+ "HookEngine",
36
+ "HookEvent",
37
+ "HookExecutionRecord",
38
+ "HookGraphWiring",
39
+ "HookRegistry",
40
+ "HookResult",
41
+ "HookSpec",
42
+ "HooksConfigSnapshot",
43
+ "CommandExecutor",
44
+ "HttpExecutor",
45
+ "PromptExecutor",
46
+ "AgentExecutor",
47
+ "WorkspaceTrustChecker",
48
+ ]
@@ -0,0 +1,62 @@
1
+ """
2
+ async_hook_runner.py — Hook 同步入口的异步执行协作者。
3
+
4
+ 职责:
5
+ 为同步节点提供统一的 async hook 执行策略,避免 event loop 存在时退化跳过。
6
+
7
+ 链路位置:
8
+ HookGraphWiring 与 graph_edges 通过本协作者调用 HookEngine.execute()。
9
+
10
+ 当前裁剪范围:
11
+ P1 仅实现线程桥接执行;不引入 nest_asyncio,不修改外部事件循环。
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import asyncio
17
+ from concurrent.futures import ThreadPoolExecutor
18
+ from threading import Lock
19
+
20
+ from .engine import HookEngine
21
+ from .types import AggregatedHookResult, HookContext
22
+
23
+
24
+ class AsyncHookRunner:
25
+ """同步调用场景下的 Hook 执行器。"""
26
+
27
+ def __init__(self) -> None:
28
+ self._executor: ThreadPoolExecutor | None = None
29
+ self._executor_lock = Lock()
30
+
31
+ def run(self, hook_engine: HookEngine, ctx: HookContext) -> AggregatedHookResult:
32
+ """统一执行 HookEngine.execute,兼容有无运行中事件循环两种场景。"""
33
+ try:
34
+ asyncio.get_running_loop()
35
+ except RuntimeError:
36
+ return asyncio.run(hook_engine.execute(ctx))
37
+ return self._run_in_thread(hook_engine, ctx)
38
+
39
+ def _run_in_thread(self, hook_engine: HookEngine, ctx: HookContext) -> AggregatedHookResult:
40
+ """在独立线程内创建事件循环执行 hook。"""
41
+ executor = self._get_or_create_executor()
42
+ future = executor.submit(self._thread_entry, hook_engine, ctx)
43
+ return future.result()
44
+
45
+ def _get_or_create_executor(self) -> ThreadPoolExecutor:
46
+ with self._executor_lock:
47
+ if self._executor is None:
48
+ self._executor = ThreadPoolExecutor(max_workers=1)
49
+ return self._executor
50
+
51
+ def close(self) -> None:
52
+ with self._executor_lock:
53
+ if self._executor is not None:
54
+ self._executor.shutdown(wait=True)
55
+ self._executor = None
56
+
57
+ @staticmethod
58
+ def _thread_entry(hook_engine: HookEngine, ctx: HookContext) -> AggregatedHookResult:
59
+ return asyncio.run(hook_engine.execute(ctx))
60
+
61
+
62
+ __all__ = ["AsyncHookRunner"]
@@ -0,0 +1,280 @@
1
+ """
2
+ config.py — Hook 配置快照与候选集构建(P1/P2)。
3
+
4
+ 职责:
5
+ 定义 HookSpec,维护 HooksConfigSnapshot,并产出可执行候选列表。
6
+
7
+ 链路位置:
8
+ HookEngine 在每次事件执行前通过 snapshot 拉取 candidates。
9
+
10
+ 当前裁剪范围:
11
+ 已支持 P1/P2 执行器候选构建(matcher/condition/policy/dedup/type-order);
12
+ 与执行器并行策略由 HookEngine 协同完成。
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from dataclasses import dataclass, field
18
+ from fnmatch import fnmatch
19
+ import json
20
+ from threading import Lock
21
+ from typing import Any, Callable, Literal
22
+ from uuid import uuid4
23
+
24
+ from .types import HookContext, HookEvent, HookSource
25
+
26
+ ExecutorType = Literal["function", "callback", "command", "http", "prompt", "agent"]
27
+ HTTP_UNSUPPORTED_EVENTS = {HookEvent.SESSION_START}
28
+ TYPE_ORDER: dict[ExecutorType, int] = {
29
+ "command": 0,
30
+ "prompt": 1,
31
+ "agent": 2,
32
+ "http": 3,
33
+ "callback": 4,
34
+ "function": 5,
35
+ }
36
+
37
+
38
+ @dataclass
39
+ class HookSpec:
40
+ """单条 Hook 配置。"""
41
+
42
+ event: HookEvent
43
+ executor_type: ExecutorType
44
+ config: dict[str, Any] = field(default_factory=dict)
45
+ matcher: str = "*"
46
+ timeout: float = 30.0
47
+ managed: bool = False
48
+ source: HookSource = "settings"
49
+ plugin_source: str | None = None
50
+ once: bool = False
51
+ on_success: Callable[[], None] | None = None
52
+ hook_id: str = field(default_factory=lambda: uuid4().hex)
53
+
54
+ def matches(self, ctx: HookContext) -> bool:
55
+ """根据 matcher 判断是否命中当前上下文。"""
56
+ if self.event != ctx.event:
57
+ return False
58
+ if self.matcher == "*":
59
+ return True
60
+ if ctx.tool_name is None:
61
+ return False
62
+ return fnmatch(ctx.tool_name, self.matcher)
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class HookCandidate:
67
+ """可执行候选(带稳定顺序键)。"""
68
+
69
+ spec: HookSpec
70
+ stable_key: str
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class HookCandidateDecision:
75
+ """候选筛选决策记录(用于可观测跳过原因)。"""
76
+
77
+ spec: HookSpec
78
+ stable_key: str
79
+ matched: bool
80
+ skip_reason: str | None
81
+
82
+
83
+ class HooksConfigSnapshot:
84
+ """多来源 Hook 配置快照。"""
85
+
86
+ def __init__(self) -> None:
87
+ self.snapshot_id: str = uuid4().hex
88
+ self._specs: list[HookSpec] = []
89
+ self._lock = Lock()
90
+ self._disable_all: bool = False
91
+ self._allow_managed_only: bool = False
92
+ self._policy_source: str | None = None
93
+
94
+ @property
95
+ def disable_all(self) -> bool:
96
+ return self._disable_all
97
+
98
+ @property
99
+ def allow_managed_only(self) -> bool:
100
+ return self._allow_managed_only
101
+
102
+ @property
103
+ def policy_source(self) -> str | None:
104
+ return self._policy_source
105
+
106
+ def add_spec(self, spec: HookSpec) -> None:
107
+ self._specs.append(spec)
108
+
109
+ def load_from_settings(self, settings: dict[str, Any]) -> None:
110
+ self._disable_all = bool(settings.get("disable_all_hooks", False))
111
+ self._allow_managed_only = bool(settings.get("allow_managed_hooks_only", False))
112
+ self._policy_source = settings.get("policy_source")
113
+
114
+ def register_session_hook(self, spec: HookSpec) -> str:
115
+ session_spec = HookSpec(
116
+ event=spec.event,
117
+ executor_type=spec.executor_type,
118
+ config=dict(spec.config),
119
+ matcher=spec.matcher,
120
+ timeout=spec.timeout,
121
+ managed=spec.managed,
122
+ source="session",
123
+ once=spec.once,
124
+ on_success=spec.on_success,
125
+ )
126
+ self._specs.append(session_spec)
127
+ return session_spec.hook_id
128
+
129
+ def unregister_session_hook(self, hook_id: str) -> None:
130
+ self._specs = [spec for spec in self._specs if spec.hook_id != hook_id]
131
+
132
+ def replace_plugin_hooks_atomic(self, specs: list[HookSpec]) -> None:
133
+ """原子替换所有插件来源 hook(仅影响 source == "plugin")。"""
134
+ with self._lock:
135
+ self._specs = [spec for spec in self._specs if spec.source != "plugin"]
136
+ self._specs.extend(specs)
137
+
138
+ def remove_plugin_hooks(self, plugin_source: str) -> None:
139
+ """移除指定插件来源 hook(仅影响 source == "plugin")。"""
140
+ with self._lock:
141
+ self._specs = [
142
+ spec
143
+ for spec in self._specs
144
+ if not (
145
+ spec.source == "plugin" and spec.plugin_source == plugin_source
146
+ )
147
+ ]
148
+
149
+ def get_candidates(self, ctx: HookContext) -> list[HookCandidate]:
150
+ """构建候选集:matcher -> last-wins 去重 -> 类型重排序。"""
151
+ candidates, _ = self.get_candidates_with_decisions(ctx)
152
+ return candidates
153
+
154
+ def get_candidates_with_decisions(
155
+ self, ctx: HookContext
156
+ ) -> tuple[list[HookCandidate], list[HookCandidateDecision]]:
157
+ """构建候选集并返回被跳过的决策记录。"""
158
+ skipped: list[HookCandidateDecision] = []
159
+ dedup: dict[str, HookSpec] = {}
160
+
161
+ for spec in self._specs:
162
+ if spec.event != ctx.event:
163
+ continue
164
+ key = self._dedup_key(spec)
165
+ if not spec.matches(ctx):
166
+ skipped.append(
167
+ HookCandidateDecision(
168
+ spec=spec,
169
+ stable_key=key,
170
+ matched=False,
171
+ skip_reason="matcher_not_matched",
172
+ )
173
+ )
174
+ continue
175
+ if spec.executor_type == "http" and ctx.event in HTTP_UNSUPPORTED_EVENTS:
176
+ skipped.append(
177
+ HookCandidateDecision(
178
+ spec=spec,
179
+ stable_key=key,
180
+ matched=True,
181
+ skip_reason="http_unsupported_event",
182
+ )
183
+ )
184
+ continue
185
+ condition = str(spec.config.get("if") or "").strip() or None
186
+ if not evaluate_condition(condition, ctx):
187
+ skipped.append(
188
+ HookCandidateDecision(
189
+ spec=spec,
190
+ stable_key=key,
191
+ matched=True,
192
+ skip_reason="condition_not_matched",
193
+ )
194
+ )
195
+ continue
196
+ policy_skip = self._policy_skip_reason(spec)
197
+ if policy_skip is not None:
198
+ skipped.append(
199
+ HookCandidateDecision(
200
+ spec=spec,
201
+ stable_key=key,
202
+ matched=True,
203
+ skip_reason=policy_skip,
204
+ )
205
+ )
206
+ continue
207
+ if key in dedup:
208
+ skipped.append(
209
+ HookCandidateDecision(
210
+ spec=dedup[key],
211
+ stable_key=key,
212
+ matched=True,
213
+ skip_reason="dedup_overridden",
214
+ )
215
+ )
216
+ dedup[key] = spec
217
+
218
+ deduped = list(dedup.items())
219
+ deduped.sort(key=lambda kv: (TYPE_ORDER[kv[1].executor_type], kv[0]))
220
+ candidates = [HookCandidate(spec=spec, stable_key=key) for key, spec in deduped]
221
+ return candidates, skipped
222
+
223
+ def _policy_skip_reason(self, spec: HookSpec) -> str | None:
224
+ if self._disable_all and not spec.managed:
225
+ return "disable_all"
226
+ if self._allow_managed_only and not spec.managed:
227
+ return "managed_only"
228
+ return None
229
+
230
+ @staticmethod
231
+ def _dedup_key(spec: HookSpec) -> str:
232
+ name = str(spec.config.get("name") or spec.config.get("id") or spec.hook_id)
233
+ return f"{spec.event.value}:{spec.matcher}:{name}"
234
+
235
+
236
+ def resolve_executor_callable(spec: HookSpec) -> Callable[..., Any]:
237
+ """从 HookSpec config 解析可执行对象。"""
238
+ fn = spec.config.get("fn") or spec.config.get("callback")
239
+ if not callable(fn):
240
+ raise TypeError(f"HookSpec {spec.hook_id} missing callable 'fn/callback'")
241
+ return fn
242
+
243
+
244
+ def evaluate_condition(condition: str | None, ctx: HookContext) -> bool:
245
+ """评估 Hook `if` 条件,支持 `tool_name(arg_glob)` 简化语法。"""
246
+ if condition is None:
247
+ return True
248
+ text = condition.strip()
249
+ if not text:
250
+ return True
251
+ if text == "*":
252
+ return True
253
+
254
+ open_idx = text.find("(")
255
+ if open_idx == -1:
256
+ return bool(ctx.tool_name) and fnmatch(ctx.tool_name, text)
257
+
258
+ if not text.endswith(")") or open_idx == 0:
259
+ return False
260
+
261
+ tool_pattern = text[:open_idx].strip()
262
+ arg_pattern = text[open_idx + 1 : -1].strip()
263
+ if not ctx.tool_name or not fnmatch(ctx.tool_name, tool_pattern):
264
+ return False
265
+ if not arg_pattern:
266
+ return True
267
+
268
+ tool_input_json = json.dumps(ctx.tool_input or {}, ensure_ascii=False)
269
+ return fnmatch(tool_input_json, arg_pattern)
270
+
271
+
272
+ __all__ = [
273
+ "ExecutorType",
274
+ "HookCandidate",
275
+ "HookCandidateDecision",
276
+ "HookSpec",
277
+ "HooksConfigSnapshot",
278
+ "evaluate_condition",
279
+ "resolve_executor_callable",
280
+ ]