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.
- langchain_agentx/__init__.py +46 -0
- langchain_agentx/command/__init__.py +28 -0
- langchain_agentx/command/builtin/__init__.py +25 -0
- langchain_agentx/command/builtin/clear.py +33 -0
- langchain_agentx/command/builtin/compact.py +33 -0
- langchain_agentx/command/builtin/memory.py +37 -0
- langchain_agentx/command/builtin/reload_plugins.py +42 -0
- langchain_agentx/command/context.py +30 -0
- langchain_agentx/command/dispatcher.py +183 -0
- langchain_agentx/command/registry.py +110 -0
- langchain_agentx/command/result.py +25 -0
- langchain_agentx/command/types.py +41 -0
- langchain_agentx/config/__init__.py +14 -0
- langchain_agentx/loop/__init__.py +47 -0
- langchain_agentx/loop/config/__init__.py +20 -0
- langchain_agentx/loop/config/agent_config.py +66 -0
- langchain_agentx/loop/config/agent_loop_config.py +72 -0
- langchain_agentx/loop/config/model_context_resolver.py +105 -0
- langchain_agentx/loop/config/runtime_settings.py +50 -0
- langchain_agentx/loop/config/token_estimator.py +133 -0
- langchain_agentx/loop/context/__init__.py +66 -0
- langchain_agentx/loop/context/blocking_guard.py +97 -0
- langchain_agentx/loop/context/compaction_service.py +60 -0
- langchain_agentx/loop/context/message_utils.py +56 -0
- langchain_agentx/loop/context/pipeline.py +127 -0
- langchain_agentx/loop/context/settings.py +103 -0
- langchain_agentx/loop/context/stages/__init__.py +29 -0
- langchain_agentx/loop/context/stages/autocompact.py +140 -0
- langchain_agentx/loop/context/stages/base.py +32 -0
- langchain_agentx/loop/context/stages/collapse.py +76 -0
- langchain_agentx/loop/context/stages/microcompact.py +76 -0
- langchain_agentx/loop/context/stages/noop.py +33 -0
- langchain_agentx/loop/context/stages/snip.py +71 -0
- langchain_agentx/loop/context/stages/tool_result_budget.py +69 -0
- langchain_agentx/loop/context/types.py +79 -0
- langchain_agentx/loop/exit/__init__.py +1 -0
- langchain_agentx/loop/exit/exit_logic.py +320 -0
- langchain_agentx/loop/exit/reason_codes.py +39 -0
- langchain_agentx/loop/graph/__init__.py +5 -0
- langchain_agentx/loop/graph/builtin_loop_control.py +197 -0
- langchain_agentx/loop/graph/factory.py +1409 -0
- langchain_agentx/loop/graph/graph_edges.py +820 -0
- langchain_agentx/loop/hook/__init__.py +48 -0
- langchain_agentx/loop/hook/async_hook_runner.py +62 -0
- langchain_agentx/loop/hook/config.py +280 -0
- langchain_agentx/loop/hook/engine.py +321 -0
- langchain_agentx/loop/hook/executors/__init__.py +9 -0
- langchain_agentx/loop/hook/executors/agent.py +107 -0
- langchain_agentx/loop/hook/executors/command.py +230 -0
- langchain_agentx/loop/hook/executors/http.py +114 -0
- langchain_agentx/loop/hook/executors/prompt.py +92 -0
- langchain_agentx/loop/hook/graph_wiring.py +134 -0
- langchain_agentx/loop/hook/registry.py +262 -0
- langchain_agentx/loop/hook/trust.py +43 -0
- langchain_agentx/loop/hook/types.py +110 -0
- langchain_agentx/loop/injection/__init__.py +13 -0
- langchain_agentx/loop/injection/dedup.py +74 -0
- langchain_agentx/loop/loop_abort.py +36 -0
- langchain_agentx/loop/model/__init__.py +1 -0
- langchain_agentx/loop/model/model_node.py +648 -0
- langchain_agentx/loop/model/model_nodes.py +661 -0
- langchain_agentx/loop/model/orphan_tool_results.py +38 -0
- langchain_agentx/loop/model/retrier.py +307 -0
- langchain_agentx/loop/model/retry_bridge.py +58 -0
- langchain_agentx/loop/model/retry_events.py +35 -0
- langchain_agentx/loop/model/retry_policy.py +56 -0
- langchain_agentx/loop/model/schema_and_format.py +153 -0
- langchain_agentx/loop/model/tool_and_model_binding.py +227 -0
- langchain_agentx/loop/model/tool_call_degradation_corrector.py +443 -0
- langchain_agentx/loop/model/tool_transcript_guard.py +225 -0
- langchain_agentx/loop/prompt/__init__.py +95 -0
- langchain_agentx/loop/prompt/builder.py +61 -0
- langchain_agentx/loop/prompt/builtin.py +218 -0
- langchain_agentx/loop/prompt/compact.py +408 -0
- langchain_agentx/loop/prompt/sections.py +120 -0
- langchain_agentx/loop/runtime/__init__.py +19 -0
- langchain_agentx/loop/runtime/context.py +34 -0
- langchain_agentx/loop/runtime/context_factory.py +107 -0
- langchain_agentx/loop/runtime/subagent_execution_paths.py +68 -0
- langchain_agentx/loop/subagent/__init__.py +53 -0
- langchain_agentx/loop/subagent/async_runner.py +215 -0
- langchain_agentx/loop/subagent/context.py +209 -0
- langchain_agentx/loop/subagent/fork_worktree_notice.py +25 -0
- langchain_agentx/loop/subagent/graph.py +72 -0
- langchain_agentx/loop/subagent/orchestrator.py +391 -0
- langchain_agentx/loop/subagent/progress.py +30 -0
- langchain_agentx/loop/subagent/prompt.py +52 -0
- langchain_agentx/loop/subagent/runner.py +504 -0
- langchain_agentx/loop/subagent/transcript.py +172 -0
- langchain_agentx/memory/__init__.py +2 -0
- langchain_agentx/memory/instruction/__init__.py +12 -0
- langchain_agentx/memory/instruction/loader.py +325 -0
- langchain_agentx/memory/instruction/resolver.py +24 -0
- langchain_agentx/memory/instruction/runtime.py +83 -0
- langchain_agentx/memory/instruction/sections.py +83 -0
- langchain_agentx/memory/instruction/types.py +59 -0
- langchain_agentx/memory/memdir/__init__.py +77 -0
- langchain_agentx/memory/memdir/age.py +36 -0
- langchain_agentx/memory/memdir/agent_memory.py +380 -0
- langchain_agentx/memory/memdir/extractor.py +309 -0
- langchain_agentx/memory/memdir/loader.py +187 -0
- langchain_agentx/memory/memdir/paths.py +63 -0
- langchain_agentx/memory/memdir/recall.py +45 -0
- langchain_agentx/memory/memdir/runtime.py +43 -0
- langchain_agentx/memory/memdir/scan.py +135 -0
- langchain_agentx/memory/memdir/types.py +104 -0
- langchain_agentx/memory/session/__init__.py +76 -0
- langchain_agentx/memory/session/compact_bridge.py +208 -0
- langchain_agentx/memory/session/prompts.py +172 -0
- langchain_agentx/memory/session/session_memory.py +282 -0
- langchain_agentx/observability/__init__.py +67 -0
- langchain_agentx/observability/evaluation/__init__.py +17 -0
- langchain_agentx/observability/evaluation/checkers/__init__.py +18 -0
- langchain_agentx/observability/evaluation/checkers/base.py +34 -0
- langchain_agentx/observability/evaluation/checkers/compaction.py +38 -0
- langchain_agentx/observability/evaluation/checkers/degradation.py +50 -0
- langchain_agentx/observability/evaluation/checkers/exit_quality.py +42 -0
- langchain_agentx/observability/evaluation/checkers/session_memory.py +45 -0
- langchain_agentx/observability/evaluation/checkers/tool_behavior.py +53 -0
- langchain_agentx/observability/evaluation/retention_scheduler.py +67 -0
- langchain_agentx/observability/evaluation/service.py +102 -0
- langchain_agentx/observability/evaluation/state.py +32 -0
- langchain_agentx/observability/evaluation/store.py +258 -0
- langchain_agentx/observability/events/__init__.py +15 -0
- langchain_agentx/observability/events/langchain_agentx_event_adapter.py +832 -0
- langchain_agentx/observability/logging/__init__.py +15 -0
- langchain_agentx/observability/logging/debug_burst.py +95 -0
- langchain_agentx/observability/logging/logging_config.py +178 -0
- langchain_agentx/observability/logging/logging_contract.py +65 -0
- langchain_agentx/observability/replay/__init__.py +35 -0
- langchain_agentx/observability/replay/cli.py +91 -0
- langchain_agentx/observability/replay/service.py +83 -0
- langchain_agentx/observability/replay/store.py +278 -0
- langchain_agentx/observability/replay/ui.py +47 -0
- langchain_agentx/observability/trace/__init__.py +25 -0
- langchain_agentx/observability/trace/collector.py +560 -0
- langchain_agentx/observability/trace/event_emitter.py +183 -0
- langchain_agentx/observability/trace/hook_event_emitter.py +49 -0
- langchain_agentx/observability/trace/models.py +144 -0
- langchain_agentx/observability/trace/sqlite_store.py +873 -0
- langchain_agentx/observability/trace/trace_callback.py +295 -0
- langchain_agentx/observability/trace/trace_lifecycle_collector.py +114 -0
- langchain_agentx/plugin/__init__.py +26 -0
- langchain_agentx/plugin/builtin.py +53 -0
- langchain_agentx/plugin/config.py +113 -0
- langchain_agentx/plugin/loader.py +386 -0
- langchain_agentx/plugin/manifest.py +154 -0
- langchain_agentx/plugin/registries.py +211 -0
- langchain_agentx/plugin/types.py +142 -0
- langchain_agentx/provider/__init__.py +27 -0
- langchain_agentx/provider/anthropic.py +121 -0
- langchain_agentx/provider/compatible_chat_openai.py +86 -0
- langchain_agentx/provider/env.py +45 -0
- langchain_agentx/provider/model_profile.py +156 -0
- langchain_agentx/provider/openai.py +89 -0
- langchain_agentx/session/__init__.py +17 -0
- langchain_agentx/session/agent_session.py +320 -0
- langchain_agentx/session/conversation_factory.py +87 -0
- langchain_agentx/session/conversation_recovery.py +156 -0
- langchain_agentx/session/conversation_session.py +198 -0
- langchain_agentx/session/factory.py +143 -0
- langchain_agentx/session/protocol.py +25 -0
- langchain_agentx/task_runtime/__init__.py +113 -0
- langchain_agentx/task_runtime/core/__init__.py +51 -0
- langchain_agentx/task_runtime/core/ids.py +33 -0
- langchain_agentx/task_runtime/core/interfaces.py +115 -0
- langchain_agentx/task_runtime/core/notification_priority.py +19 -0
- langchain_agentx/task_runtime/core/types.py +136 -0
- langchain_agentx/task_runtime/integrations/__init__.py +33 -0
- langchain_agentx/task_runtime/integrations/loop_adapter.py +91 -0
- langchain_agentx/task_runtime/integrations/loop_integration.py +61 -0
- langchain_agentx/task_runtime/integrations/prefetch_providers.py +108 -0
- langchain_agentx/task_runtime/integrations/provider_factory.py +103 -0
- langchain_agentx/task_runtime/integrations/queued_command_provider.py +184 -0
- langchain_agentx/task_runtime/integrations/sqlite_queued_command_provider.py +338 -0
- langchain_agentx/task_runtime/integrations/tool_use_summary_provider.py +254 -0
- langchain_agentx/task_runtime/orchestrator/__init__.py +5 -0
- langchain_agentx/task_runtime/orchestrator/runtime.py +386 -0
- langchain_agentx/task_runtime/output/__init__.py +5 -0
- langchain_agentx/task_runtime/output/sink.py +64 -0
- langchain_agentx/task_runtime/policy/__init__.py +11 -0
- langchain_agentx/task_runtime/policy/withhold_visibility.py +32 -0
- langchain_agentx/task_runtime/queue/__init__.py +5 -0
- langchain_agentx/task_runtime/queue/in_memory.py +55 -0
- langchain_agentx/task_runtime/skill_prefetch/__init__.py +4 -0
- langchain_agentx/task_runtime/skill_prefetch/attachments.py +46 -0
- langchain_agentx/task_runtime/skill_prefetch/models.py +37 -0
- langchain_agentx/task_runtime/skill_prefetch/provider.py +344 -0
- langchain_agentx/task_runtime/store/__init__.py +6 -0
- langchain_agentx/task_runtime/store/in_memory.py +81 -0
- langchain_agentx/task_runtime/store/sqlite_store.py +281 -0
- langchain_agentx/task_runtime/tasks/__init__.py +76 -0
- langchain_agentx/task_runtime/tasks/ai_analysis/__init__.py +15 -0
- langchain_agentx/task_runtime/tasks/ai_analysis/base.py +41 -0
- langchain_agentx/task_runtime/tasks/ai_analysis/evaluation.py +67 -0
- langchain_agentx/task_runtime/tasks/ai_analysis/registry.py +36 -0
- langchain_agentx/task_runtime/tasks/ai_analysis/scheduler.py +70 -0
- langchain_agentx/task_runtime/tasks/base/__init__.py +6 -0
- langchain_agentx/task_runtime/tasks/base/contracts.py +24 -0
- langchain_agentx/task_runtime/tasks/custom/__init__.py +7 -0
- langchain_agentx/task_runtime/tasks/custom/executor.py +60 -0
- langchain_agentx/task_runtime/tasks/custom/notification.py +7 -0
- langchain_agentx/task_runtime/tasks/custom/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/custom/spec.py +33 -0
- langchain_agentx/task_runtime/tasks/dream_task/__init__.py +15 -0
- langchain_agentx/task_runtime/tasks/dream_task/executor.py +61 -0
- langchain_agentx/task_runtime/tasks/dream_task/notification.py +19 -0
- langchain_agentx/task_runtime/tasks/dream_task/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/dream_task/spec.py +35 -0
- langchain_agentx/task_runtime/tasks/dream_task/state.py +17 -0
- langchain_agentx/task_runtime/tasks/in_process_teammate/__init__.py +12 -0
- langchain_agentx/task_runtime/tasks/in_process_teammate/executor.py +36 -0
- langchain_agentx/task_runtime/tasks/in_process_teammate/notification.py +25 -0
- langchain_agentx/task_runtime/tasks/in_process_teammate/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/in_process_teammate/spec.py +63 -0
- langchain_agentx/task_runtime/tasks/local_agent/__init__.py +14 -0
- langchain_agentx/task_runtime/tasks/local_agent/executor.py +33 -0
- langchain_agentx/task_runtime/tasks/local_agent/notification.py +21 -0
- langchain_agentx/task_runtime/tasks/local_agent/runner.py +43 -0
- langchain_agentx/task_runtime/tasks/local_agent/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/local_agent/spec.py +31 -0
- langchain_agentx/task_runtime/tasks/local_bash/__init__.py +13 -0
- langchain_agentx/task_runtime/tasks/local_bash/executor.py +95 -0
- langchain_agentx/task_runtime/tasks/local_bash/notification.py +22 -0
- langchain_agentx/task_runtime/tasks/local_bash/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/local_bash/spec.py +55 -0
- langchain_agentx/task_runtime/tasks/remote_agent/__init__.py +19 -0
- langchain_agentx/task_runtime/tasks/remote_agent/backend.py +76 -0
- langchain_agentx/task_runtime/tasks/remote_agent/executor.py +37 -0
- langchain_agentx/task_runtime/tasks/remote_agent/notification.py +22 -0
- langchain_agentx/task_runtime/tasks/remote_agent/semantics.py +13 -0
- langchain_agentx/task_runtime/tasks/remote_agent/spec.py +34 -0
- langchain_agentx/task_runtime/tasks/trace_cleanup/__init__.py +19 -0
- langchain_agentx/task_runtime/tasks/trace_cleanup/bootstrap.py +95 -0
- langchain_agentx/task_runtime/tasks/trace_cleanup/executor.py +66 -0
- langchain_agentx/task_runtime/tasks/trace_cleanup/scheduler.py +169 -0
- langchain_agentx/tool_runtime/__init__.py +90 -0
- langchain_agentx/tool_runtime/adapter.py +365 -0
- langchain_agentx/tool_runtime/base.py +319 -0
- langchain_agentx/tool_runtime/errors.py +190 -0
- langchain_agentx/tool_runtime/identical_call_cache.py +110 -0
- langchain_agentx/tool_runtime/loader.py +195 -0
- langchain_agentx/tool_runtime/models.py +260 -0
- langchain_agentx/tool_runtime/permission_context.py +78 -0
- langchain_agentx/tool_runtime/pipeline.py +621 -0
- langchain_agentx/tool_runtime/policy.py +447 -0
- langchain_agentx/tool_runtime/registry.py +81 -0
- langchain_agentx/tool_runtime/resolvers/__init__.py +27 -0
- langchain_agentx/tool_runtime/resolvers/agent_session.py +125 -0
- langchain_agentx/tool_runtime/resolvers/background.py +32 -0
- langchain_agentx/tool_runtime/resolvers/base.py +20 -0
- langchain_agentx/tool_runtime/resolvers/conversation.py +22 -0
- langchain_agentx/tool_runtime/resolvers/workflow.py +73 -0
- langchain_agentx/tool_runtime/session_store.py +132 -0
- langchain_agentx/tool_runtime/smoke_test_runtime.py +294 -0
- langchain_agentx/tool_runtime/state_bridge.py +164 -0
- langchain_agentx/tools/__init__.py +26 -0
- langchain_agentx/tools/agent/__init__.py +9 -0
- langchain_agentx/tools/agent/backend.py +53 -0
- langchain_agentx/tools/agent/built_in/__init__.py +19 -0
- langchain_agentx/tools/agent/built_in/agentx_guide.py +65 -0
- langchain_agentx/tools/agent/built_in/explore.py +80 -0
- langchain_agentx/tools/agent/built_in/general.py +57 -0
- langchain_agentx/tools/agent/built_in/plan.py +89 -0
- langchain_agentx/tools/agent/built_in/statusline_setup.py +64 -0
- langchain_agentx/tools/agent/built_in/verification.py +120 -0
- langchain_agentx/tools/agent/builtin_subagent_loader.py +89 -0
- langchain_agentx/tools/agent/cwd_resolution.py +119 -0
- langchain_agentx/tools/agent/limits.py +26 -0
- langchain_agentx/tools/agent/loader.py +270 -0
- langchain_agentx/tools/agent/models.py +85 -0
- langchain_agentx/tools/agent/prompt.py +120 -0
- langchain_agentx/tools/agent/registry/__init__.py +18 -0
- langchain_agentx/tools/agent/registry/config.py +29 -0
- langchain_agentx/tools/agent/registry/registry.py +47 -0
- langchain_agentx/tools/agent/scope.py +137 -0
- langchain_agentx/tools/agent/tool.py +256 -0
- langchain_agentx/tools/bash/__init__.py +9 -0
- langchain_agentx/tools/bash/ast_security.py +571 -0
- langchain_agentx/tools/bash/backend.py +1447 -0
- langchain_agentx/tools/bash/bash_hardening.py +734 -0
- langchain_agentx/tools/bash/bash_runtime_contract.py +41 -0
- langchain_agentx/tools/bash/cwd_reporter.py +95 -0
- langchain_agentx/tools/bash/limits.py +71 -0
- langchain_agentx/tools/bash/mode_validation.py +282 -0
- langchain_agentx/tools/bash/models.py +131 -0
- langchain_agentx/tools/bash/observability.py +148 -0
- langchain_agentx/tools/bash/output_utils.py +200 -0
- langchain_agentx/tools/bash/path_security.py +2429 -0
- langchain_agentx/tools/bash/prompt.py +68 -0
- langchain_agentx/tools/bash/read_only_validation.py +589 -0
- langchain_agentx/tools/bash/result_presenter.py +324 -0
- langchain_agentx/tools/bash/sandbox_decision.py +133 -0
- langchain_agentx/tools/bash/security.py +311 -0
- langchain_agentx/tools/bash/sed_edit_parser.py +243 -0
- langchain_agentx/tools/bash/sed_validation.py +163 -0
- langchain_agentx/tools/bash/semantics.py +111 -0
- langchain_agentx/tools/bash/session_manager.py +205 -0
- langchain_agentx/tools/bash/session_runtime.py +290 -0
- langchain_agentx/tools/bash/shell_locator.py +191 -0
- langchain_agentx/tools/bash/task_runtime.py +91 -0
- langchain_agentx/tools/bash/tool.py +939 -0
- langchain_agentx/tools/bash/windows_shell_quoting.py +45 -0
- langchain_agentx/tools/glob/__init__.py +9 -0
- langchain_agentx/tools/glob/models.py +57 -0
- langchain_agentx/tools/glob/pagination.py +30 -0
- langchain_agentx/tools/glob/prompt.py +24 -0
- langchain_agentx/tools/glob/rg_list_backend.py +139 -0
- langchain_agentx/tools/glob/rg_pattern.py +44 -0
- langchain_agentx/tools/glob/tool.py +327 -0
- langchain_agentx/tools/grep/__init__.py +7 -0
- langchain_agentx/tools/grep/backend.py +375 -0
- langchain_agentx/tools/grep/models.py +127 -0
- langchain_agentx/tools/grep/prompt.py +30 -0
- langchain_agentx/tools/grep/rg_subprocess_controller.py +114 -0
- langchain_agentx/tools/grep/tool.py +475 -0
- langchain_agentx/tools/read/__init__.py +9 -0
- langchain_agentx/tools/read/backend.py +415 -0
- langchain_agentx/tools/read/limits.py +67 -0
- langchain_agentx/tools/read/models.py +156 -0
- langchain_agentx/tools/read/prompt.py +73 -0
- langchain_agentx/tools/read/tool.py +494 -0
- langchain_agentx/tools/ripgrep_plugin_exclusions.py +137 -0
- langchain_agentx/tools/skill/__init__.py +4 -0
- langchain_agentx/tools/skill/argument_substitution.py +80 -0
- langchain_agentx/tools/skill/loader.py +196 -0
- langchain_agentx/tools/skill/models.py +88 -0
- langchain_agentx/tools/skill/policy.py +80 -0
- langchain_agentx/tools/skill/prompt.py +35 -0
- langchain_agentx/tools/skill/tool.py +222 -0
- langchain_agentx/utils/__init__.py +0 -0
- langchain_agentx/utils/cwd.py +124 -0
- langchain_agentx/utils/host_platform.py +112 -0
- langchain_agentx/utils/path_hierarchy.py +48 -0
- langchain_agentx/utils/path_user_input.py +66 -0
- langchain_agentx/utils/rg_executable.py +18 -0
- langchain_agentx/utils/subprocess_text.py +101 -0
- langchain_agentx/utils/temp_paths.py +77 -0
- langchain_agentx/utils/unc_path.py +25 -0
- langchain_agentx/utils/win_reserved_paths.py +51 -0
- langchain_agentx/workflow/__init__.py +7 -0
- langchain_agentx/workflow/base.py +97 -0
- langchain_agentx/workflow/batch.py +55 -0
- langchain_agentx/workflow/dag.py +54 -0
- langchain_agentx/workspace/__init__.py +13 -0
- langchain_agentx/workspace/config.py +140 -0
- langchain_agentx/workspace/path_key_normalizer.py +30 -0
- langchain_agentx/workspace/resolver.py +74 -0
- langchain_agentx/workspace/validators.py +41 -0
- langchain_agentx_python-0.1.dist-info/LICENSE +201 -0
- langchain_agentx_python-0.1.dist-info/METADATA +513 -0
- langchain_agentx_python-0.1.dist-info/RECORD +354 -0
- langchain_agentx_python-0.1.dist-info/WHEEL +5 -0
- langchain_agentx_python-0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"""
|
|
2
|
+
loop/subagent/orchestrator.py — SubagentOrchestrator 子代理启动编排
|
|
3
|
+
|
|
4
|
+
职责:接管 AgentRuntimeTool.invoke 中的子代理启动逻辑:
|
|
5
|
+
异步决策 → 工具池组装 → 上下文派生 → run_subagent / register_background_agent 调用。
|
|
6
|
+
在整体链路中的位置:AgentRuntimeTool.invoke() → SubagentOrchestrator.invoke_subagent()
|
|
7
|
+
CC 对照:src/tools/AgentTool/AgentTool.tsx call() 中 runAgent / registerAsyncAgent 分支。
|
|
8
|
+
当前裁剪范围:v1 三路异步决策 + plain/fork/coordinate 执行路径;
|
|
9
|
+
fork + worktree 时注入 CC 等价 ``buildWorktreeNotice`` user 消息(见 ``fork_worktree_notice``)。
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
import time
|
|
17
|
+
import uuid
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import TYPE_CHECKING, Any
|
|
20
|
+
|
|
21
|
+
from langchain_agentx.loop.runtime import RuntimeContextFactory, SubagentContextOverrides
|
|
22
|
+
from langchain_agentx.loop.runtime.subagent_execution_paths import (
|
|
23
|
+
PreparedSubagentPaths,
|
|
24
|
+
SubagentExecutionPaths,
|
|
25
|
+
)
|
|
26
|
+
from langchain_agentx.loop.subagent.context import create_subagent_context
|
|
27
|
+
from langchain_agentx.loop.subagent.prompt import enhance_system_prompt_with_env
|
|
28
|
+
from langchain_agentx.utils.cwd import get_cwd, run_with_cwd_override
|
|
29
|
+
from langchain_agentx.tools.agent.backend import assemble_tool_pool, should_run_async
|
|
30
|
+
from langchain_agentx.loop.subagent.runner import (
|
|
31
|
+
BackgroundLaunchedResult,
|
|
32
|
+
_run_coroutine_sync,
|
|
33
|
+
run_subagent,
|
|
34
|
+
run_subagent_with_background_signal,
|
|
35
|
+
)
|
|
36
|
+
from langchain_agentx.loop.subagent.async_runner import register_background_agent
|
|
37
|
+
from langchain_agentx.observability.logging import ObservabilityLoggerAdapter, build_log_context
|
|
38
|
+
from langchain_agentx.workspace import resolve_agent_workspace_config
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from langchain_agentx.loop.runtime import AgentLoopConfig
|
|
42
|
+
from langchain_agentx.tool_runtime.models import ToolExecutionContext
|
|
43
|
+
from langchain_agentx.tools.agent.models import AgentToolInput, AgentToolOutput
|
|
44
|
+
from langchain_agentx.tools.agent.registry.config import SubagentConfig
|
|
45
|
+
|
|
46
|
+
logger = logging.getLogger(__name__)
|
|
47
|
+
|
|
48
|
+
def _make_progress_handler(subagent_type: str, started_at: float):
|
|
49
|
+
"""构造 on_progress 回调(2s hint 阈值 + stderr 单行覆写)。"""
|
|
50
|
+
import sys
|
|
51
|
+
hint_shown = False
|
|
52
|
+
|
|
53
|
+
def _on_progress(event: Any) -> None:
|
|
54
|
+
nonlocal hint_shown
|
|
55
|
+
if not hint_shown and time.monotonic() - started_at > 2.0:
|
|
56
|
+
hint_shown = True
|
|
57
|
+
print(
|
|
58
|
+
f"\r[Agent:{subagent_type}] task is running... (Ctrl+C to interrupt)",
|
|
59
|
+
file=sys.stderr,
|
|
60
|
+
flush=True,
|
|
61
|
+
)
|
|
62
|
+
if getattr(event, "summary", ""):
|
|
63
|
+
print(
|
|
64
|
+
f"\r[{subagent_type}] {event.summary:<80}",
|
|
65
|
+
file=sys.stderr,
|
|
66
|
+
end="",
|
|
67
|
+
flush=True,
|
|
68
|
+
)
|
|
69
|
+
if getattr(event, "type", "") == "completed":
|
|
70
|
+
print("", file=sys.stderr)
|
|
71
|
+
|
|
72
|
+
return _on_progress
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class SubagentOrchestrator:
|
|
76
|
+
"""子代理启动编排器。
|
|
77
|
+
|
|
78
|
+
职责边界:
|
|
79
|
+
- 继承规则委托给 RuntimeContextFactory.derive()
|
|
80
|
+
- 工具池组装委托给 assemble_tool_pool()
|
|
81
|
+
- 执行委托给 run_subagent() / register_background_agent()
|
|
82
|
+
- 不承载 present / validate 等 RuntimeTool 生命周期钩子
|
|
83
|
+
|
|
84
|
+
CC 对照:AgentTool.tsx call() 中 runAgent / registerAsyncAgent 的分支逻辑。
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def __init__(
|
|
88
|
+
self,
|
|
89
|
+
mode: str = "plain",
|
|
90
|
+
background_output_dir: str | None = None,
|
|
91
|
+
) -> None:
|
|
92
|
+
self._mode = mode
|
|
93
|
+
self._background_output_dir = background_output_dir
|
|
94
|
+
|
|
95
|
+
def invoke_subagent(
|
|
96
|
+
self,
|
|
97
|
+
inp: "AgentToolInput",
|
|
98
|
+
ctx: "ToolExecutionContext",
|
|
99
|
+
subagent_config: "SubagentConfig",
|
|
100
|
+
) -> "AgentToolOutput":
|
|
101
|
+
"""执行子代理:派生上下文 → 组装工具池 → 按异步策略执行。
|
|
102
|
+
|
|
103
|
+
继承规则单点在 RuntimeContextFactory.derive(),不在此处散落。
|
|
104
|
+
"""
|
|
105
|
+
from langchain_agentx.tools.agent.models import AgentToolOutput
|
|
106
|
+
|
|
107
|
+
log = self._build_logger(ctx)
|
|
108
|
+
child_agent_id = str(uuid.uuid4())
|
|
109
|
+
overrides, runtime_ctx, prepared = self._derive_runtime_context(
|
|
110
|
+
inp=inp,
|
|
111
|
+
ctx=ctx,
|
|
112
|
+
subagent_config=subagent_config,
|
|
113
|
+
child_agent_id=child_agent_id,
|
|
114
|
+
)
|
|
115
|
+
is_async = self._decide_async(inp=inp, ctx=ctx)
|
|
116
|
+
|
|
117
|
+
log.info(
|
|
118
|
+
"agent invoke mode=%s subagent_type=%s async=%s",
|
|
119
|
+
self._mode, inp.subagent_type or "general-purpose", is_async,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
parent_registry = getattr(ctx, "tool_registry", None)
|
|
123
|
+
if parent_registry is None or not hasattr(parent_registry, "list"):
|
|
124
|
+
raise RuntimeError(
|
|
125
|
+
"tool_registry missing in ToolExecutionContext; "
|
|
126
|
+
"please construct the parent agent with ToolRuntimeLoader(loader=...)."
|
|
127
|
+
)
|
|
128
|
+
parent_loader = getattr(ctx, "tool_loader", None)
|
|
129
|
+
if parent_loader is None or not hasattr(parent_loader, "fork_with_tools"):
|
|
130
|
+
raise RuntimeError(
|
|
131
|
+
"tool_loader missing in ToolExecutionContext; "
|
|
132
|
+
"please construct the parent agent with ToolRuntimeLoader(loader=...)."
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
runtime_tools = list(parent_registry.list())
|
|
136
|
+
runtime_tools = assemble_tool_pool(runtime_tools, subagent_config, is_async=is_async)
|
|
137
|
+
allowed_tool_names: set[str] = {getattr(t, "name", "") for t in runtime_tools if getattr(t, "name", "")}
|
|
138
|
+
child_loader = parent_loader.fork_with_tools(runtime_tools)
|
|
139
|
+
|
|
140
|
+
system_prompt = enhance_system_prompt_with_env(
|
|
141
|
+
subagent_config.system_prompt_factory(),
|
|
142
|
+
runtime_ctx.cwd,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
effective_cwd = runtime_ctx.cwd or get_cwd()
|
|
146
|
+
# CC:buildWorktreeNotice(getCwd(), …) 在子 cwd 覆盖生效之前取父工作目录
|
|
147
|
+
parent_notice_cwd = getattr(ctx, "cwd", None) or get_cwd()
|
|
148
|
+
inject_fork_wt = self._mode == "fork" and prepared.worktree_dir is not None
|
|
149
|
+
with run_with_cwd_override(effective_cwd):
|
|
150
|
+
output_dir = self._resolve_background_output_dir(runtime_ctx)
|
|
151
|
+
subagent_ctx = create_subagent_context(
|
|
152
|
+
parent_ctx=ctx,
|
|
153
|
+
task=inp.prompt,
|
|
154
|
+
subagent_type=inp.subagent_type or "general-purpose",
|
|
155
|
+
system_prompt=system_prompt,
|
|
156
|
+
max_steps=runtime_ctx.max_steps,
|
|
157
|
+
agent_depth=runtime_ctx.agent_depth,
|
|
158
|
+
isolation=overrides.isolation,
|
|
159
|
+
fork_from_parent=(self._mode == "fork"),
|
|
160
|
+
is_async=is_async,
|
|
161
|
+
model=runtime_ctx.model,
|
|
162
|
+
path_prep=prepared,
|
|
163
|
+
inject_fork_worktree_notice=inject_fork_wt,
|
|
164
|
+
fork_worktree_parent_cwd=parent_notice_cwd,
|
|
165
|
+
fork_worktree_path=prepared.worktree_dir,
|
|
166
|
+
)
|
|
167
|
+
# agent_id 由 RuntimeContextFactory 派生,同步到 subagent_ctx
|
|
168
|
+
subagent_ctx.agent_id = child_agent_id
|
|
169
|
+
|
|
170
|
+
_on_progress = _make_progress_handler(
|
|
171
|
+
inp.subagent_type or "general-purpose", time.monotonic()
|
|
172
|
+
)
|
|
173
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
174
|
+
|
|
175
|
+
if is_async:
|
|
176
|
+
return self._launch_async_subagent(
|
|
177
|
+
agent_output_cls=AgentToolOutput,
|
|
178
|
+
subagent_ctx=subagent_ctx,
|
|
179
|
+
loader=child_loader,
|
|
180
|
+
model=runtime_ctx.model,
|
|
181
|
+
description=inp.description,
|
|
182
|
+
on_progress=_on_progress,
|
|
183
|
+
parent_ctx=ctx,
|
|
184
|
+
output_dir=output_dir,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
background_signal = getattr(ctx, "background_signal", None)
|
|
188
|
+
if background_signal is not None:
|
|
189
|
+
result = self._run_with_background_signal(
|
|
190
|
+
subagent_ctx=subagent_ctx,
|
|
191
|
+
loader=child_loader,
|
|
192
|
+
model=runtime_ctx.model,
|
|
193
|
+
description=inp.description,
|
|
194
|
+
on_progress=_on_progress,
|
|
195
|
+
parent_ctx=ctx,
|
|
196
|
+
background_signal=background_signal,
|
|
197
|
+
allowed_tool_names=allowed_tool_names,
|
|
198
|
+
output_dir=output_dir,
|
|
199
|
+
)
|
|
200
|
+
if isinstance(result, BackgroundLaunchedResult):
|
|
201
|
+
output_file = os.path.join(
|
|
202
|
+
output_dir, result.task_id, "output.txt"
|
|
203
|
+
)
|
|
204
|
+
log.info("agent switched to background task_id=%s", result.task_id)
|
|
205
|
+
return AgentToolOutput(
|
|
206
|
+
status="async_launched",
|
|
207
|
+
content="",
|
|
208
|
+
agent_id=result.agent_id,
|
|
209
|
+
total_steps=0,
|
|
210
|
+
terminal_reason="background_signal",
|
|
211
|
+
task_id=result.task_id,
|
|
212
|
+
output_file=output_file,
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
result = self._run_foreground_subagent(
|
|
216
|
+
subagent_ctx=subagent_ctx,
|
|
217
|
+
loader=child_loader,
|
|
218
|
+
model=runtime_ctx.model,
|
|
219
|
+
on_progress=_on_progress,
|
|
220
|
+
allowed_tool_names=allowed_tool_names,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return AgentToolOutput(
|
|
224
|
+
status=result.status,
|
|
225
|
+
content=result.content,
|
|
226
|
+
agent_id=result.agent_id,
|
|
227
|
+
total_steps=result.total_steps,
|
|
228
|
+
terminal_reason=result.terminal_reason or None,
|
|
229
|
+
error_message=result.error_message or None,
|
|
230
|
+
output_file=getattr(result, "output_file", None),
|
|
231
|
+
child_run_id=getattr(result, "child_run_id", None),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
def _build_logger(self, ctx: "ToolExecutionContext") -> ObservabilityLoggerAdapter:
|
|
235
|
+
return ObservabilityLoggerAdapter(
|
|
236
|
+
logger,
|
|
237
|
+
build_log_context(
|
|
238
|
+
session_id=getattr(ctx, "session_id", None),
|
|
239
|
+
tool_call_id=getattr(ctx, "tool_call_id", None),
|
|
240
|
+
agent_id=getattr(ctx, "agent_id", None),
|
|
241
|
+
).as_extra(),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def _derive_runtime_context(
|
|
245
|
+
self,
|
|
246
|
+
*,
|
|
247
|
+
inp: "AgentToolInput",
|
|
248
|
+
ctx: "ToolExecutionContext",
|
|
249
|
+
subagent_config: "SubagentConfig",
|
|
250
|
+
child_agent_id: str,
|
|
251
|
+
) -> tuple[SubagentContextOverrides, "AgentLoopConfig", PreparedSubagentPaths]:
|
|
252
|
+
overrides = SubagentContextOverrides(
|
|
253
|
+
model=inp.model or None,
|
|
254
|
+
isolation=inp.isolation,
|
|
255
|
+
cwd=inp.cwd or None,
|
|
256
|
+
)
|
|
257
|
+
prepared = SubagentExecutionPaths.prepare(parent_ctx=ctx, overrides=overrides)
|
|
258
|
+
runtime_ctx: AgentLoopConfig = RuntimeContextFactory.derive(
|
|
259
|
+
parent_ctx=ctx,
|
|
260
|
+
overrides=overrides,
|
|
261
|
+
subagent_config=subagent_config,
|
|
262
|
+
agent_id=child_agent_id,
|
|
263
|
+
subagent_effective_cwd=prepared.effective_cwd,
|
|
264
|
+
)
|
|
265
|
+
return overrides, runtime_ctx, prepared
|
|
266
|
+
|
|
267
|
+
def _decide_async(self, *, inp: "AgentToolInput", ctx: "ToolExecutionContext") -> bool:
|
|
268
|
+
is_coordinator = getattr(ctx, "is_coordinator", False)
|
|
269
|
+
is_fork_enabled = getattr(ctx, "is_fork_enabled", False)
|
|
270
|
+
if self._mode == "coordinate" and is_coordinator:
|
|
271
|
+
return True
|
|
272
|
+
if self._mode == "fork" and is_fork_enabled:
|
|
273
|
+
return True
|
|
274
|
+
return should_run_async(inp, ctx)
|
|
275
|
+
|
|
276
|
+
def _register_background_agent(
|
|
277
|
+
self,
|
|
278
|
+
*,
|
|
279
|
+
subagent_ctx: Any,
|
|
280
|
+
loader: Any,
|
|
281
|
+
model: Any,
|
|
282
|
+
description: str | None,
|
|
283
|
+
on_progress: Any,
|
|
284
|
+
parent_ctx: "ToolExecutionContext",
|
|
285
|
+
output_dir: str,
|
|
286
|
+
) -> Any:
|
|
287
|
+
return register_background_agent(
|
|
288
|
+
ctx=subagent_ctx,
|
|
289
|
+
loader=loader,
|
|
290
|
+
model=model,
|
|
291
|
+
output_dir=output_dir,
|
|
292
|
+
description=description,
|
|
293
|
+
on_progress=on_progress,
|
|
294
|
+
parent_ctx=parent_ctx,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def _launch_async_subagent(
|
|
298
|
+
self,
|
|
299
|
+
*,
|
|
300
|
+
agent_output_cls: type[Any],
|
|
301
|
+
subagent_ctx: Any,
|
|
302
|
+
loader: Any,
|
|
303
|
+
model: Any,
|
|
304
|
+
description: str | None,
|
|
305
|
+
on_progress: Any,
|
|
306
|
+
parent_ctx: "ToolExecutionContext",
|
|
307
|
+
output_dir: str,
|
|
308
|
+
) -> Any:
|
|
309
|
+
handle = self._register_background_agent(
|
|
310
|
+
subagent_ctx=subagent_ctx,
|
|
311
|
+
loader=loader,
|
|
312
|
+
model=model,
|
|
313
|
+
description=description,
|
|
314
|
+
on_progress=on_progress,
|
|
315
|
+
parent_ctx=parent_ctx,
|
|
316
|
+
output_dir=output_dir,
|
|
317
|
+
)
|
|
318
|
+
return agent_output_cls(
|
|
319
|
+
status="async_launched",
|
|
320
|
+
content="",
|
|
321
|
+
agent_id=handle.agent_id,
|
|
322
|
+
total_steps=0,
|
|
323
|
+
terminal_reason="background",
|
|
324
|
+
task_id=handle.task_id,
|
|
325
|
+
output_file=handle.output_file,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
def _run_with_background_signal(
|
|
329
|
+
self,
|
|
330
|
+
*,
|
|
331
|
+
subagent_ctx: Any,
|
|
332
|
+
loader: Any,
|
|
333
|
+
model: Any,
|
|
334
|
+
description: str | None,
|
|
335
|
+
on_progress: Any,
|
|
336
|
+
parent_ctx: "ToolExecutionContext",
|
|
337
|
+
background_signal: Any,
|
|
338
|
+
allowed_tool_names: set[str],
|
|
339
|
+
output_dir: str,
|
|
340
|
+
) -> Any:
|
|
341
|
+
def _register_from_signal(child_ctx: Any) -> str:
|
|
342
|
+
handle = self._register_background_agent(
|
|
343
|
+
subagent_ctx=child_ctx,
|
|
344
|
+
loader=loader,
|
|
345
|
+
model=model,
|
|
346
|
+
description=description,
|
|
347
|
+
on_progress=on_progress,
|
|
348
|
+
parent_ctx=parent_ctx,
|
|
349
|
+
output_dir=output_dir,
|
|
350
|
+
)
|
|
351
|
+
return handle.task_id
|
|
352
|
+
|
|
353
|
+
return _run_coroutine_sync(
|
|
354
|
+
run_subagent_with_background_signal(
|
|
355
|
+
ctx=subagent_ctx,
|
|
356
|
+
loader=loader,
|
|
357
|
+
model=model,
|
|
358
|
+
on_progress=on_progress,
|
|
359
|
+
background_signal=background_signal,
|
|
360
|
+
on_background_request=_register_from_signal,
|
|
361
|
+
allowed_tool_names=allowed_tool_names,
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
def _resolve_background_output_dir(self, runtime_ctx: "AgentLoopConfig") -> str:
|
|
366
|
+
if self._background_output_dir:
|
|
367
|
+
return self._background_output_dir
|
|
368
|
+
workspace_cfg = resolve_agent_workspace_config(
|
|
369
|
+
workspace_root=runtime_ctx.workspace_root or Path.cwd(),
|
|
370
|
+
agent_home=runtime_ctx.agent_home,
|
|
371
|
+
)
|
|
372
|
+
return str(workspace_cfg.tasks_dir)
|
|
373
|
+
|
|
374
|
+
def _run_foreground_subagent(
|
|
375
|
+
self,
|
|
376
|
+
*,
|
|
377
|
+
subagent_ctx: Any,
|
|
378
|
+
loader: Any,
|
|
379
|
+
model: Any,
|
|
380
|
+
on_progress: Any,
|
|
381
|
+
allowed_tool_names: set[str],
|
|
382
|
+
) -> Any:
|
|
383
|
+
return _run_coroutine_sync(
|
|
384
|
+
run_subagent(
|
|
385
|
+
ctx=subagent_ctx,
|
|
386
|
+
loader=loader,
|
|
387
|
+
model=model,
|
|
388
|
+
on_progress=on_progress,
|
|
389
|
+
allowed_tool_names=allowed_tool_names,
|
|
390
|
+
)
|
|
391
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Subagent Progress Event 数据结构
|
|
2
|
+
|
|
3
|
+
职责:进度事件载荷(Channel B)
|
|
4
|
+
在整体链路中的位置:runner.py 构造 → AgentRuntimeTool.invoke() 的 on_progress 回调消费
|
|
5
|
+
CC 对照:src/agent/subagent/progress.ts onProgress 回调参数类型
|
|
6
|
+
当前裁剪范围:v1 基础事件类型,无 async 路径
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class SubagentProgressEvent:
|
|
15
|
+
"""子 Agent 进度事件
|
|
16
|
+
|
|
17
|
+
type 枚举:
|
|
18
|
+
- tool_use: 工具调用开始
|
|
19
|
+
- tool_result: 工具调用结束
|
|
20
|
+
- model_step: 模型推理完成
|
|
21
|
+
- hint: 后台化提示(v2)
|
|
22
|
+
- completed: 子 Agent 完成
|
|
23
|
+
"""
|
|
24
|
+
type: Literal["tool_use", "tool_result", "model_step", "hint", "completed"]
|
|
25
|
+
subagent_type: str = ""
|
|
26
|
+
agent_id: str = ""
|
|
27
|
+
step: int = 0
|
|
28
|
+
tool_name: str = ""
|
|
29
|
+
summary: str = ""
|
|
30
|
+
meta: dict = field(default_factory=dict)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
loop/subagent/prompt.py — 子代理 system prompt 环境信息注入
|
|
3
|
+
|
|
4
|
+
职责:enhance_system_prompt_with_env(),在子代理 base prompt 基础上追加
|
|
5
|
+
env 块(工作区根、进程 cwd、git、agent_home、builtin 总闸等)与行为 notes。
|
|
6
|
+
在整体链路中的位置:SubagentOrchestrator.invoke_subagent() 调用(built-in 与 Markdown 子代理共用)。
|
|
7
|
+
CC 对照:constants/prompts.ts computeEnvInfo + enhanceSystemPromptWithEnvDetails。
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from langchain_agentx.utils.subprocess_text import default_text_subprocess_runner
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
_AGENT_NOTES = """Notes:
|
|
16
|
+
- Always use absolute file paths, never relative paths.
|
|
17
|
+
- In your final response, share file paths (always absolute) relevant to the task."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _is_git_repo(path: str) -> bool:
|
|
21
|
+
try:
|
|
22
|
+
runner = default_text_subprocess_runner()
|
|
23
|
+
result = runner.run(
|
|
24
|
+
["git", "-C", path, "rev-parse", "--is-inside-work-tree"],
|
|
25
|
+
capture_output=True,
|
|
26
|
+
timeout=3,
|
|
27
|
+
)
|
|
28
|
+
return result.returncode == 0
|
|
29
|
+
except Exception:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def enhance_system_prompt_with_env(
|
|
34
|
+
base_prompt: str,
|
|
35
|
+
cwd: str | None,
|
|
36
|
+
) -> str:
|
|
37
|
+
"""在 base_prompt 基础上追加环境信息块与行为 notes。
|
|
38
|
+
|
|
39
|
+
cwd 为 None 时原样返回,不注入任何内容。
|
|
40
|
+
CC 对照:computeEnvInfo + enhanceSystemPromptWithEnvDetails 的组合。
|
|
41
|
+
"""
|
|
42
|
+
if not cwd:
|
|
43
|
+
return base_prompt
|
|
44
|
+
|
|
45
|
+
is_git = _is_git_repo(cwd)
|
|
46
|
+
env_block = (
|
|
47
|
+
f"<env>\n"
|
|
48
|
+
f"Working directory: {cwd}\n"
|
|
49
|
+
f"Is directory a git repo: {'Yes' if is_git else 'No'}\n"
|
|
50
|
+
f"</env>"
|
|
51
|
+
)
|
|
52
|
+
return f"{base_prompt}\n\n{_AGENT_NOTES}\n\n{env_block}"
|