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,24 @@
1
+ """
2
+ task_runtime/tasks/base/contracts.py — 任务语义契约基类
3
+
4
+ 职责:
5
+ 用不可变数据类描述「某一 TaskType 的终态集合与摘要前缀」,
6
+ 与具体 ``TaskExecutor`` 解耦,便于文档化与静态检查。
7
+
8
+ 与 CC 对比:
9
+ CC 在 ``TaskStateBase`` / 各 task 的 ``type`` 判别式中分散语义;
10
+ 本仓库用 ``TaskSemanticContract`` 收敛为可导入的单一事实来源(SSOT 子集)。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+
17
+ from ...core.types import TaskStatus, TaskType
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class TaskSemanticContract:
22
+ task_type: TaskType
23
+ terminal_statuses: tuple[TaskStatus, ...]
24
+ summary_prefix: str
@@ -0,0 +1,7 @@
1
+ """CUSTOM 语义包(扩展任务类型)。"""
2
+
3
+ from .executor import CustomTaskExecutor
4
+ from .semantics import CUSTOM_SEMANTIC
5
+ from .spec import CustomTaskInput
6
+
7
+ __all__ = ["CustomTaskExecutor", "CUSTOM_SEMANTIC", "CustomTaskInput"]
@@ -0,0 +1,60 @@
1
+ """
2
+ tasks/custom/executor.py — CUSTOM 执行器
3
+
4
+ 职责:
5
+ 解析 ``CustomTaskInput`` 后按 ``payload.handler`` / ``metadata.custom_handler`` 分发;
6
+ 未指定 handler 时回退为 ``CustomTaskNotificationFormatter`` 终态摘要。
7
+
8
+ 与 CC 对比:
9
+ CC 无独立 ``custom`` Task 类型;本枚举为扩展点,handler 名与 payload 由业务约定。
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from ...core.interfaces import TaskExecutor
15
+ from ...core.types import TaskExecutionResult, TaskStatus
16
+
17
+ from .notification import CustomTaskNotificationFormatter
18
+ from .spec import CustomTaskInput
19
+
20
+
21
+ def _handler_name(record, parsed: CustomTaskInput) -> str | None:
22
+ pl = parsed.payload
23
+ if isinstance(pl, dict):
24
+ h = pl.get("handler")
25
+ if isinstance(h, str) and h.strip():
26
+ return h.strip().lower()
27
+ meta = record.metadata or {}
28
+ h2 = meta.get("custom_handler")
29
+ if isinstance(h2, str) and h2.strip():
30
+ return h2.strip().lower()
31
+ return None
32
+
33
+
34
+ class CustomTaskExecutor(TaskExecutor):
35
+ def execute(self, record) -> TaskExecutionResult:
36
+ try:
37
+ parsed = CustomTaskInput.from_mapping(dict(record.input or {}))
38
+ except ValueError as e:
39
+ return TaskExecutionResult(status=TaskStatus.FAILED, summary=str(e))
40
+
41
+ name = _handler_name(record, parsed)
42
+ if name == "echo":
43
+ return TaskExecutionResult(
44
+ status=TaskStatus.COMPLETED,
45
+ summary=f"custom[echo]: {parsed.body}",
46
+ )
47
+ if name == "upper":
48
+ return TaskExecutionResult(
49
+ status=TaskStatus.COMPLETED,
50
+ summary=f"custom[upper]: {parsed.body.upper()}",
51
+ )
52
+ if name in ("fail", "failed"):
53
+ reason = ""
54
+ if isinstance(parsed.payload, dict):
55
+ reason = str(parsed.payload.get("reason") or "").strip()
56
+ summary = reason or "custom handler requested failure"
57
+ return TaskExecutionResult(status=TaskStatus.FAILED, summary=summary)
58
+
59
+ summary = CustomTaskNotificationFormatter.format_completion(body=parsed.body)
60
+ return TaskExecutionResult(status=TaskStatus.COMPLETED, summary=summary)
@@ -0,0 +1,7 @@
1
+ """tasks/custom/notification.py — 终态摘要(OOP)"""
2
+
3
+
4
+ class CustomTaskNotificationFormatter:
5
+ @classmethod
6
+ def format_completion(cls, *, body: str) -> str:
7
+ return f"custom task completed: {body[:280]}"
@@ -0,0 +1,13 @@
1
+ """tasks/custom/semantics.py — 语义契约绑定。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ...core.types import TaskStatus, TaskType
6
+ from ..base.contracts import TaskSemanticContract
7
+
8
+
9
+ CUSTOM_SEMANTIC = TaskSemanticContract(
10
+ task_type=TaskType.CUSTOM,
11
+ terminal_statuses=(TaskStatus.COMPLETED, TaskStatus.FAILED, TaskStatus.STOPPED),
12
+ summary_prefix="custom",
13
+ )
@@ -0,0 +1,33 @@
1
+ """
2
+ tasks/custom/spec.py — CUSTOM 输入契约(OOP)
3
+
4
+ 职责:
5
+ 扩展任务类型的最小结构化入口;业务侧应在 ``metadata`` 中标注 handler 版本。
6
+
7
+ 与 CC 对比:
8
+ CC ``types.ts`` 中未单独列 ``custom``;本仓库 ``TaskType.CUSTOM`` 对应「无法归入五类」
9
+ 的扩展点,输入必须显式包含 ``message`` 或 ``payload`` 之一。
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass
15
+ from typing import Any, Mapping
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class CustomTaskInput:
20
+ body: str
21
+ payload: dict[str, Any]
22
+
23
+ @classmethod
24
+ def from_mapping(cls, raw: Mapping[str, Any]) -> CustomTaskInput:
25
+ msg = raw.get("message")
26
+ if isinstance(msg, str) and msg.strip():
27
+ return cls(body=msg.strip(), payload=dict(raw.get("payload") or {}))
28
+ pl = raw.get("payload")
29
+ if isinstance(pl, Mapping) and pl:
30
+ text = str(pl.get("message") or pl.get("summary") or "").strip()
31
+ if text:
32
+ return cls(body=text, payload=dict(pl))
33
+ raise ValueError("CUSTOM requires non-empty 'message' or payload with message/summary")
@@ -0,0 +1,15 @@
1
+ """DREAM_TASK 语义包(CC ``DreamTask``)。"""
2
+
3
+ from .executor import DreamTaskExecutor
4
+ from .notification import DreamTaskNotificationFormatter
5
+ from .semantics import DREAM_TASK_SEMANTIC
6
+ from .spec import DreamTaskInput
7
+ from .state import DreamTaskState
8
+
9
+ __all__ = [
10
+ "DreamTaskExecutor",
11
+ "DreamTaskNotificationFormatter",
12
+ "DreamTaskInput",
13
+ "DreamTaskState",
14
+ "DREAM_TASK_SEMANTIC",
15
+ ]
@@ -0,0 +1,61 @@
1
+ """
2
+ tasks/dream_task/executor.py — DREAM_TASK 执行器
3
+
4
+ 职责:
5
+ 按 ``constraints.max_turns`` 驱动轻量 **phase / progress** 状态机(``starting`` →
6
+ ``updating`` → ``completed``),终态摘要由 ``DreamTaskNotificationFormatter`` 产出。
7
+
8
+ 与 CC 对比:
9
+ CC ``addDreamTurn`` / ``DreamTaskState`` 多轮 richer;本实现用同步循环模拟 turn,
10
+ 真 multi-turn LLM 可在循环体内替换为异步调度(保持 ``DreamTaskState`` 更新语义)。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from ...core.interfaces import TaskExecutor
16
+ from ...core.types import TaskExecutionResult, TaskStatus
17
+
18
+ from .notification import DreamTaskNotificationFormatter
19
+ from .spec import DreamTaskInput
20
+ from .state import DreamTaskState
21
+
22
+
23
+ def _clamp_turns(raw: object) -> int:
24
+ if raw is None:
25
+ return 1
26
+ try:
27
+ n = int(raw)
28
+ except (TypeError, ValueError):
29
+ return 1
30
+ return max(1, min(n, 48))
31
+
32
+
33
+ class DreamTaskExecutor(TaskExecutor):
34
+ def execute(self, record) -> TaskExecutionResult:
35
+ try:
36
+ parsed = DreamTaskInput.from_mapping(dict(record.input or {}))
37
+ except ValueError as e:
38
+ return TaskExecutionResult(status=TaskStatus.FAILED, summary=str(e))
39
+
40
+ max_turns = _clamp_turns(parsed.constraints.get("max_turns", 1))
41
+ state = DreamTaskState()
42
+
43
+ for turn in range(max_turns):
44
+ if turn == 0:
45
+ state.phase = "starting"
46
+ else:
47
+ state.phase = "updating"
48
+ state.progress = (turn + 1) / float(max_turns)
49
+ state.latest_note = (
50
+ f"turn {turn + 1}/{max_turns} goal={parsed.goal[:120]!r}"
51
+ )
52
+
53
+ state.phase = "completed"
54
+ state.progress = 1.0
55
+ ctx_hint = ""
56
+ if parsed.context_snapshot:
57
+ ctx_hint = f" ctx_keys={list(parsed.context_snapshot.keys())[:8]}"
58
+ state.latest_note = f"dream finished{ctx_hint}"
59
+
60
+ summary = DreamTaskNotificationFormatter.build_summary(state)
61
+ return TaskExecutionResult(status=TaskStatus.COMPLETED, summary=summary)
@@ -0,0 +1,19 @@
1
+ """
2
+ tasks/dream_task/notification.py — 进度/终态摘要(OOP)
3
+
4
+ 与 CC 对比:
5
+ CC ``DreamTaskState`` 含 ``turns``、``filesTouched``;本仓库 ``DreamTaskState``
6
+ 为轻量占位,由 ``DreamTaskNotificationFormatter`` 生成可读摘要。
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from .state import DreamTaskState
12
+
13
+
14
+ class DreamTaskNotificationFormatter:
15
+ @classmethod
16
+ def build_summary(cls, state: DreamTaskState) -> str:
17
+ pct = int(max(0.0, min(1.0, state.progress)) * 100)
18
+ note = state.latest_note.strip() or "running"
19
+ return f"dream_task phase={state.phase} progress={pct}% note={note}"
@@ -0,0 +1,13 @@
1
+ """tasks/dream_task/semantics.py — 语义契约绑定。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ...core.types import TaskStatus, TaskType
6
+ from ..base.contracts import TaskSemanticContract
7
+
8
+
9
+ DREAM_TASK_SEMANTIC = TaskSemanticContract(
10
+ task_type=TaskType.DREAM_TASK,
11
+ terminal_statuses=(TaskStatus.COMPLETED, TaskStatus.FAILED, TaskStatus.STOPPED),
12
+ summary_prefix="dream_task",
13
+ )
@@ -0,0 +1,35 @@
1
+ """
2
+ tasks/dream_task/spec.py — DREAM_TASK 输入契约(OOP)
3
+
4
+ 职责:
5
+ 约束 dream / 记忆整理类任务的 goal 与可选约束字典。
6
+
7
+ 与 CC 对比:
8
+ ``DreamTask/DreamTask.ts`` 中 ``DreamTaskState``(phase、turns 等)更丰富;
9
+ 本仓库用 ``DreamTaskInput.from_mapping`` 表达最小可执行字段,状态机分期扩展。
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass, field
15
+ from typing import Any, Mapping
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class DreamTaskInput:
20
+ goal: str
21
+ constraints: dict[str, Any] = field(default_factory=dict)
22
+ context_snapshot: dict[str, Any] = field(default_factory=dict)
23
+
24
+ @classmethod
25
+ def from_mapping(cls, raw: Mapping[str, Any]) -> DreamTaskInput:
26
+ goal = str(raw.get("goal") or "").strip()
27
+ if not goal:
28
+ raise ValueError("DREAM_TASK requires non-empty 'goal'")
29
+ cons = raw.get("constraints")
30
+ ctx = raw.get("context_snapshot")
31
+ return cls(
32
+ goal=goal,
33
+ constraints=dict(cons) if isinstance(cons, Mapping) else {},
34
+ context_snapshot=dict(ctx) if isinstance(ctx, Mapping) else {},
35
+ )
@@ -0,0 +1,17 @@
1
+ """
2
+ tasks/dream_task/state.py — 轻量状态占位
3
+
4
+ 与 CC 对比:
5
+ CC ``DreamPhase`` = starting | updating;此处用字符串 phase 占位。
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass
11
+
12
+
13
+ @dataclass
14
+ class DreamTaskState:
15
+ phase: str = "starting"
16
+ progress: float = 0.0
17
+ latest_note: str = ""
@@ -0,0 +1,12 @@
1
+ """IN_PROCESS_TEAMMATE 语义包(CC ``InProcessTeammateTask``)。"""
2
+
3
+ from .executor import InProcessTeammateExecutor
4
+ from .semantics import IN_PROCESS_TEAMMATE_SEMANTIC
5
+ from .spec import InProcessTeammateTaskInput, TeammateIdentity
6
+
7
+ __all__ = [
8
+ "InProcessTeammateExecutor",
9
+ "IN_PROCESS_TEAMMATE_SEMANTIC",
10
+ "InProcessTeammateTaskInput",
11
+ "TeammateIdentity",
12
+ ]
@@ -0,0 +1,36 @@
1
+ """
2
+ tasks/in_process_teammate/executor.py — IN_PROCESS_TEAMMATE 执行器
3
+
4
+ 职责:
5
+ 校验 identity + prompt,按 ``plan_mode_required`` 分支生成 CC 对齐的终态摘要
6
+ (协作者 pill / transcript 文案骨架)。
7
+
8
+ 与 CC 对比:
9
+ CC ``InProcessTeammateTask`` 含 ``runAgent``、权限与 plan 模式;此处将 **plan_mode**
10
+ 显式反映在通知字符串中,执行体仍保持进程内同步(不触碰主线程 messages)。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from ...core.interfaces import TaskExecutor
16
+ from ...core.types import TaskExecutionResult, TaskStatus
17
+
18
+ from .notification import InProcessTeammateNotificationFormatter
19
+ from .spec import InProcessTeammateTaskInput
20
+
21
+
22
+ class InProcessTeammateExecutor(TaskExecutor):
23
+ def execute(self, record) -> TaskExecutionResult:
24
+ try:
25
+ parsed = InProcessTeammateTaskInput.from_mapping(dict(record.input or {}))
26
+ except ValueError as e:
27
+ return TaskExecutionResult(status=TaskStatus.FAILED, summary=str(e))
28
+ i = parsed.identity
29
+ summary = InProcessTeammateNotificationFormatter.format_completion(
30
+ agent_name=i.agent_name,
31
+ team_name=i.team_name,
32
+ prompt=parsed.prompt,
33
+ plan_mode_required=i.plan_mode_required,
34
+ parent_session_id=i.parent_session_id,
35
+ )
36
+ return TaskExecutionResult(status=TaskStatus.COMPLETED, summary=summary)
@@ -0,0 +1,25 @@
1
+ """
2
+ tasks/in_process_teammate/notification.py — 终态摘要(OOP)
3
+
4
+ 与 CC 对比:
5
+ CC 协作者任务在 UI pill / transcript 中展示 identity + 进度;
6
+ 此处仅格式化完成摘要字符串。
7
+ """
8
+
9
+
10
+ class InProcessTeammateNotificationFormatter:
11
+ @classmethod
12
+ def format_completion(
13
+ cls,
14
+ *,
15
+ agent_name: str,
16
+ team_name: str,
17
+ prompt: str,
18
+ plan_mode_required: bool = False,
19
+ parent_session_id: str = "",
20
+ ) -> str:
21
+ excerpt = prompt[:160]
22
+ base = f"Teammate [{agent_name}@{team_name}] completed: {excerpt}"
23
+ sess = f" parent_session={parent_session_id}" if parent_session_id else ""
24
+ plan = " [plan_mode=required]" if plan_mode_required else ""
25
+ return f"{base}{sess}{plan}"
@@ -0,0 +1,13 @@
1
+ """tasks/in_process_teammate/semantics.py — 语义契约绑定。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ...core.types import TaskStatus, TaskType
6
+ from ..base.contracts import TaskSemanticContract
7
+
8
+
9
+ IN_PROCESS_TEAMMATE_SEMANTIC = TaskSemanticContract(
10
+ task_type=TaskType.IN_PROCESS_TEAMMATE,
11
+ terminal_statuses=(TaskStatus.COMPLETED, TaskStatus.FAILED, TaskStatus.STOPPED),
12
+ summary_prefix="in_process_teammate",
13
+ )
@@ -0,0 +1,63 @@
1
+ """
2
+ tasks/in_process_teammate/spec.py — IN_PROCESS_TEAMMATE 输入契约(OOP)
3
+
4
+ 职责:
5
+ 校验 ``identity`` 子对象与 ``prompt``;对齐 CC 持久化结构的最小字段集。
6
+
7
+ 与 CC 对比:
8
+ ``InProcessTeammateTask/types.ts`` 中 ``TeammateIdentity`` + ``prompt``;
9
+ 本仓库用 ``TeammateIdentity.from_mapping`` / ``InProcessTeammateTaskInput.from_mapping``
10
+ 表达,不包含 ``AbortController`` 等仅运行时字段。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from typing import Any, Mapping
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class TeammateIdentity:
21
+ agent_id: str
22
+ agent_name: str
23
+ team_name: str
24
+ parent_session_id: str
25
+ plan_mode_required: bool = False
26
+
27
+ @classmethod
28
+ def from_mapping(cls, raw: Mapping[str, Any]) -> TeammateIdentity:
29
+ return cls(
30
+ agent_id=str(raw.get("agent_id") or "").strip(),
31
+ agent_name=str(raw.get("agent_name") or "").strip(),
32
+ team_name=str(raw.get("team_name") or "").strip(),
33
+ parent_session_id=str(raw.get("parent_session_id") or "").strip(),
34
+ plan_mode_required=bool(raw.get("plan_mode_required", False)),
35
+ )
36
+
37
+ def validate(self) -> None:
38
+ for name, val in (
39
+ ("agent_id", self.agent_id),
40
+ ("agent_name", self.agent_name),
41
+ ("team_name", self.team_name),
42
+ ("parent_session_id", self.parent_session_id),
43
+ ):
44
+ if not val:
45
+ raise ValueError(f"identity.{name} is required")
46
+
47
+
48
+ @dataclass(frozen=True)
49
+ class InProcessTeammateTaskInput:
50
+ identity: TeammateIdentity
51
+ prompt: str
52
+
53
+ @classmethod
54
+ def from_mapping(cls, raw: Mapping[str, Any]) -> InProcessTeammateTaskInput:
55
+ ident_raw = raw.get("identity")
56
+ if not isinstance(ident_raw, Mapping):
57
+ raise ValueError("IN_PROCESS_TEAMMATE requires mapping 'identity'")
58
+ identity = TeammateIdentity.from_mapping(ident_raw)
59
+ identity.validate()
60
+ prompt = str(raw.get("prompt") or "").strip()
61
+ if not prompt:
62
+ raise ValueError("IN_PROCESS_TEAMMATE requires non-empty 'prompt'")
63
+ return cls(identity=identity, prompt=prompt)
@@ -0,0 +1,14 @@
1
+ """LOCAL_AGENT 语义包(CC ``LocalAgentTask`` / ``LocalMainSessionTask``)。"""
2
+
3
+ from .executor import LocalAgentExecutor
4
+ from .runner import DefaultLocalAgentRunner, LocalAgentRunner
5
+ from .semantics import LOCAL_AGENT_SEMANTIC
6
+ from .spec import LocalAgentTaskInput
7
+
8
+ __all__ = [
9
+ "DefaultLocalAgentRunner",
10
+ "LocalAgentExecutor",
11
+ "LocalAgentRunner",
12
+ "LOCAL_AGENT_SEMANTIC",
13
+ "LocalAgentTaskInput",
14
+ ]
@@ -0,0 +1,33 @@
1
+ """
2
+ tasks/local_agent/executor.py — LOCAL_AGENT 执行器
3
+
4
+ 职责:
5
+ 解析输入并委托 ``LocalAgentRunner``;默认 ``DefaultLocalAgentRunner`` 为 CC 对齐的
6
+ **单轮**终态路径。生产环境注入自定义 runner(子图 ``invoke`` / 线程池)即可。
7
+
8
+ 与 CC 对比:
9
+ CC 在 ``LocalAgentTask`` 内驱动完整 agent loop;本类不内置 loop,仅保证
10
+ ``TaskRuntime.spawn → run_task → mark_terminal`` 与 runner 契约稳定。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from typing import Optional
16
+
17
+ from ...core.interfaces import TaskExecutor
18
+ from ...core.types import TaskExecutionResult, TaskStatus
19
+
20
+ from .runner import DefaultLocalAgentRunner, LocalAgentRunner
21
+ from .spec import LocalAgentTaskInput
22
+
23
+
24
+ class LocalAgentExecutor(TaskExecutor):
25
+ def __init__(self, runner: Optional[LocalAgentRunner] = None) -> None:
26
+ self._runner: LocalAgentRunner = runner or DefaultLocalAgentRunner()
27
+
28
+ def execute(self, record) -> TaskExecutionResult:
29
+ try:
30
+ parsed = LocalAgentTaskInput.from_mapping(dict(record.input or {}))
31
+ except ValueError as e:
32
+ return TaskExecutionResult(status=TaskStatus.FAILED, summary=str(e))
33
+ return self._runner(record, parsed)
@@ -0,0 +1,21 @@
1
+ """
2
+ tasks/local_agent/notification.py — 终态摘要(OOP)
3
+
4
+ 与 CC 对比:
5
+ CC ``LocalAgentTask`` 使用 ``AgentProgress``、token 累计等;
6
+ 此处仅提供最小可测的摘要拼接类。
7
+ """
8
+
9
+
10
+ class LocalAgentNotificationFormatter:
11
+ @classmethod
12
+ def format_completion(
13
+ cls,
14
+ *,
15
+ prompt_excerpt: str,
16
+ agent_label: str | None,
17
+ task_id: str | None = None,
18
+ ) -> str:
19
+ label = f" [{agent_label}]" if agent_label else ""
20
+ tid = f" id={task_id}" if task_id else ""
21
+ return f"Local agent task completed{label}{tid}: {prompt_excerpt[:200]}"
@@ -0,0 +1,43 @@
1
+ """
2
+ tasks/local_agent/runner.py — LOCAL_AGENT 执行体(CC LocalAgentTask 单轮路径)
3
+
4
+ 职责:
5
+ 将「解析后的输入 → TaskExecutionResult」从 Executor 中抽出,便于注入真实
6
+ **子图 invoke / 线程化 runner**(生产),默认实现保持 **无外部依赖** 的可测单轮摘要。
7
+
8
+ 与 CC 对比:
9
+ CC ``LocalAgentTask`` 内嵌完整 agent loop;此处 ``DefaultLocalAgentRunner`` 仅产出
10
+ 与 ``LocalAgentNotificationFormatter`` 一致的终态摘要。接入 LangGraph 时实现
11
+ ``LocalAgentRunner`` 协议并传入 ``LocalAgentExecutor(runner=...)`` 即可。
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import Protocol, runtime_checkable
17
+
18
+ from ...core.types import TaskExecutionResult, TaskRecord, TaskStatus
19
+ from .notification import LocalAgentNotificationFormatter
20
+ from .spec import LocalAgentTaskInput
21
+
22
+
23
+ @runtime_checkable
24
+ class LocalAgentRunner(Protocol):
25
+ def __call__(
26
+ self, record: TaskRecord, parsed: LocalAgentTaskInput
27
+ ) -> TaskExecutionResult:
28
+ """由调用方实现:可同步调用子图或包装异步结果。"""
29
+ ...
30
+
31
+
32
+ class DefaultLocalAgentRunner:
33
+ """默认单轮 runner:结构化终态摘要(含 ``task_id`` 便于观测对齐 CC 轨迹)。"""
34
+
35
+ def __call__(
36
+ self, record: TaskRecord, parsed: LocalAgentTaskInput
37
+ ) -> TaskExecutionResult:
38
+ summary = LocalAgentNotificationFormatter.format_completion(
39
+ prompt_excerpt=parsed.prompt,
40
+ agent_label=parsed.agent_label,
41
+ task_id=record.task_id,
42
+ )
43
+ return TaskExecutionResult(status=TaskStatus.COMPLETED, summary=summary)
@@ -0,0 +1,13 @@
1
+ """tasks/local_agent/semantics.py — 语义契约绑定。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ...core.types import TaskStatus, TaskType
6
+ from ..base.contracts import TaskSemanticContract
7
+
8
+
9
+ LOCAL_AGENT_SEMANTIC = TaskSemanticContract(
10
+ task_type=TaskType.LOCAL_AGENT,
11
+ terminal_statuses=(TaskStatus.COMPLETED, TaskStatus.FAILED, TaskStatus.STOPPED),
12
+ summary_prefix="local_agent",
13
+ )
@@ -0,0 +1,31 @@
1
+ """
2
+ tasks/local_agent/spec.py — LOCAL_AGENT 输入契约(OOP)
3
+
4
+ 职责:
5
+ 解析子 agent / 后台会话类任务的输入;失败抛 ``ValueError``。
6
+
7
+ 与 CC 对比:
8
+ ``LocalAgentTask.tsx``、``LocalMainSessionTask.ts`` 使用更丰富的
9
+ AgentDefinition / 进度追踪;本仓库用 ``LocalAgentTaskInput.from_mapping``
10
+ 表达最小可执行契约,真子图/长会话在 executor 内分期替换实现。
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from typing import Any, Mapping
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class LocalAgentTaskInput:
21
+ prompt: str
22
+ agent_label: str | None = None
23
+
24
+ @classmethod
25
+ def from_mapping(cls, raw: Mapping[str, Any]) -> LocalAgentTaskInput:
26
+ prompt = str(raw.get("prompt") or "").strip()
27
+ if not prompt:
28
+ raise ValueError("LOCAL_AGENT requires non-empty 'prompt'")
29
+ label = raw.get("agent_label")
30
+ agent_label = str(label).strip() if label not in (None, "") else None
31
+ return cls(prompt=prompt, agent_label=agent_label)
@@ -0,0 +1,13 @@
1
+ """LOCAL_BASH 语义包(CC ``LocalShellTask``)。"""
2
+
3
+ from .executor import LocalBashExecutor
4
+ from .notification import LocalBashNotificationFormatter
5
+ from .semantics import LOCAL_BASH_SEMANTIC
6
+ from .spec import LocalBashTaskInput
7
+
8
+ __all__ = [
9
+ "LocalBashExecutor",
10
+ "LOCAL_BASH_SEMANTIC",
11
+ "LocalBashNotificationFormatter",
12
+ "LocalBashTaskInput",
13
+ ]