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,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,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,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
|
+
]
|