@ai-setting/roy-agent-core 1.3.10 → 1.3.14
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.
- package/dist/config/index.js +1647 -0
- package/dist/index.js +12579 -89691
- package/package.json +19 -56
- package/src/config/config-component.test.ts +0 -627
- package/src/config/config-component.ts +0 -906
- package/src/config/config-parser.test.ts +0 -319
- package/src/config/config-parser.ts +0 -203
- package/src/config/decentralized-config.test.ts +0 -740
- package/src/config/env-key.ts +0 -210
- package/src/config/env-source.test.ts +0 -252
- package/src/config/env-source.ts +0 -301
- package/src/config/file-source.test.ts +0 -357
- package/src/config/file-source.ts +0 -421
- package/src/config/index.ts +0 -24
- package/src/config/protocol-resolver.test.ts +0 -217
- package/src/config/protocol-resolver.ts +0 -228
- package/src/env/agent/agent-component.abort.test.ts +0 -511
- package/src/env/agent/agent-component.record-session.test.ts +0 -349
- package/src/env/agent/agent-component.test.ts +0 -1389
- package/src/env/agent/agent-component.tool-error.test.ts +0 -327
- package/src/env/agent/agent-component.ts +0 -1711
- package/src/env/agent/agent-config-registration.test.ts +0 -226
- package/src/env/agent/agent-config-registration.ts +0 -46
- package/src/env/agent/agent-reminder-plugin.integration.test.ts +0 -243
- package/src/env/agent/index.ts +0 -10
- package/src/env/agent/summary-agent.parse-hint.test.ts +0 -360
- package/src/env/agent/summary-agent.ts +0 -508
- package/src/env/agent/types.ts +0 -536
- package/src/env/commands/commands-component.test.ts +0 -364
- package/src/env/commands/commands-component.ts +0 -604
- package/src/env/commands/commands-config-registration.test.ts +0 -198
- package/src/env/commands/commands-config-registration.ts +0 -38
- package/src/env/commands/index.ts +0 -21
- package/src/env/commands/parser.test.ts +0 -203
- package/src/env/commands/parser.ts +0 -115
- package/src/env/commands/types.ts +0 -184
- package/src/env/commands-prompt-integration.test.ts +0 -243
- package/src/env/component-env.test.ts +0 -119
- package/src/env/component.ts +0 -335
- package/src/env/constants.test.ts +0 -72
- package/src/env/constants.ts +0 -123
- package/src/env/debug/debug-component.test.ts +0 -114
- package/src/env/debug/debug-component.ts +0 -547
- package/src/env/debug/formatters/index.ts +0 -9
- package/src/env/debug/formatters/repl-formatter.test.ts +0 -139
- package/src/env/debug/formatters/repl-formatter.ts +0 -358
- package/src/env/debug/formatters/trace-formatter.test.ts +0 -119
- package/src/env/debug/formatters/trace-formatter.ts +0 -191
- package/src/env/debug/formatters/tree-formatter.test.ts +0 -107
- package/src/env/debug/formatters/tree-formatter.ts +0 -325
- package/src/env/debug/index.ts +0 -38
- package/src/env/debug/parser/regex-parser.test.ts +0 -201
- package/src/env/debug/parser/regex-parser.ts +0 -196
- package/src/env/debug/parser/span-builder.test.ts +0 -241
- package/src/env/debug/parser/span-builder.ts +0 -386
- package/src/env/debug/reader/log-reader.test.ts +0 -170
- package/src/env/debug/reader/log-reader.ts +0 -186
- package/src/env/debug/reader/span-db-reader.test.ts +0 -118
- package/src/env/debug/reader/span-db-reader.ts +0 -201
- package/src/env/debug/types.test.ts +0 -187
- package/src/env/debug/types.ts +0 -171
- package/src/env/environment-init.test.ts +0 -183
- package/src/env/environment-lifecycle.test.ts +0 -516
- package/src/env/environment-service.test.ts +0 -332
- package/src/env/environment.handle-query.test.ts +0 -96
- package/src/env/environment.test.ts +0 -232
- package/src/env/environment.ts +0 -708
- package/src/env/errors.test.ts +0 -165
- package/src/env/errors.ts +0 -157
- package/src/env/event-source/event-source-agent-handler.test.ts +0 -193
- package/src/env/event-source/event-source-agent-handler.ts +0 -111
- package/src/env/event-source/event-source-component.process-cleanup.test.ts +0 -236
- package/src/env/event-source/event-source-component.stop.test.ts +0 -346
- package/src/env/event-source/event-source-component.test.ts +0 -1207
- package/src/env/event-source/event-source-component.ts +0 -1379
- package/src/env/event-source/event-source-config-registration.test.ts +0 -242
- package/src/env/event-source/event-source-config-registration.ts +0 -37
- package/src/env/event-source/event-source-integration.test.ts +0 -320
- package/src/env/event-source/event-source-platform.test.ts +0 -630
- package/src/env/event-source/types.ts +0 -298
- package/src/env/hook/global-hook-manager.ts +0 -162
- package/src/env/hook/hook-manager.test.ts +0 -374
- package/src/env/hook/hook-manager.ts +0 -309
- package/src/env/hook/index.ts +0 -38
- package/src/env/hook/types.ts +0 -138
- package/src/env/index.ts +0 -144
- package/src/env/interface.ts +0 -203
- package/src/env/llm/hooks.test.ts +0 -293
- package/src/env/llm/hooks.ts +0 -316
- package/src/env/llm/index.ts +0 -61
- package/src/env/llm/invoke-threshold-check.test.ts +0 -88
- package/src/env/llm/invoke-timeout.test.ts +0 -54
- package/src/env/llm/invoke.test.ts +0 -71
- package/src/env/llm/invoke.ts +0 -1039
- package/src/env/llm/llm-config.test.ts +0 -523
- package/src/env/llm/llm.test.ts +0 -233
- package/src/env/llm/llm.ts +0 -568
- package/src/env/llm/provider.test.ts +0 -182
- package/src/env/llm/provider.ts +0 -108
- package/src/env/llm/transform.test.ts +0 -251
- package/src/env/llm/transform.ts +0 -286
- package/src/env/llm/types.test.ts +0 -580
- package/src/env/llm/types.ts +0 -424
- package/src/env/log-trace/decorator-otel.test.ts +0 -182
- package/src/env/log-trace/decorator.ts +0 -230
- package/src/env/log-trace/index.ts +0 -79
- package/src/env/log-trace/log-trace-component.test.ts +0 -242
- package/src/env/log-trace/log-trace-component.ts +0 -497
- package/src/env/log-trace/log-trace-config-registration.test.ts +0 -348
- package/src/env/log-trace/log-trace-config-registration.ts +0 -45
- package/src/env/log-trace/logger.test.ts +0 -149
- package/src/env/log-trace/logger.ts +0 -522
- package/src/env/log-trace/opentelemetry/cli-propagation.test.ts +0 -147
- package/src/env/log-trace/opentelemetry/cli-propagation.ts +0 -194
- package/src/env/log-trace/opentelemetry/integration.test.ts +0 -668
- package/src/env/log-trace/opentelemetry/mod.ts +0 -25
- package/src/env/log-trace/opentelemetry/propagation-env.test.ts +0 -181
- package/src/env/log-trace/opentelemetry/propagation-env.ts +0 -136
- package/src/env/log-trace/opentelemetry/propagation.test.ts +0 -259
- package/src/env/log-trace/opentelemetry/propagation.ts +0 -215
- package/src/env/log-trace/opentelemetry/tracer-provider-context.test.ts +0 -166
- package/src/env/log-trace/opentelemetry/tracer-provider.test.ts +0 -379
- package/src/env/log-trace/opentelemetry/tracer-provider.ts +0 -612
- package/src/env/log-trace/span-storage.test.ts +0 -145
- package/src/env/log-trace/span-storage.ts +0 -230
- package/src/env/log-trace/trace-context.test.ts +0 -187
- package/src/env/log-trace/trace-context.ts +0 -162
- package/src/env/log-trace/types.test.ts +0 -63
- package/src/env/log-trace/types.ts +0 -172
- package/src/env/mcp/README.md +0 -244
- package/src/env/mcp/__integration__/mcp-component.integration.test.ts +0 -373
- package/src/env/mcp/config.test.ts +0 -74
- package/src/env/mcp/config.ts +0 -116
- package/src/env/mcp/index.ts +0 -41
- package/src/env/mcp/loader.test.ts +0 -161
- package/src/env/mcp/loader.ts +0 -209
- package/src/env/mcp/mcp-component.test.ts +0 -111
- package/src/env/mcp/mcp-component.ts +0 -358
- package/src/env/mcp/mcp-config-registration.test.ts +0 -304
- package/src/env/mcp/mcp-config-registration.ts +0 -50
- package/src/env/mcp/scanner.test.ts +0 -170
- package/src/env/mcp/scanner.ts +0 -246
- package/src/env/mcp/tool/adapter.test.ts +0 -520
- package/src/env/mcp/tool/adapter.ts +0 -521
- package/src/env/mcp/tool/index.ts +0 -5
- package/src/env/mcp/types.test.ts +0 -171
- package/src/env/mcp/types.ts +0 -79
- package/src/env/memory/README.md +0 -177
- package/src/env/memory/built-in/index.ts +0 -59
- package/src/env/memory/built-in/recall-memory.ts +0 -103
- package/src/env/memory/built-in/record-memory.ts +0 -148
- package/src/env/memory/index.ts +0 -20
- package/src/env/memory/memory-component.test.ts +0 -239
- package/src/env/memory/memory-component.ts +0 -503
- package/src/env/memory/memory-config-registration.test.ts +0 -67
- package/src/env/memory/memory-config-registration.ts +0 -48
- package/src/env/memory/memory-config.ts +0 -45
- package/src/env/memory/memory-file.test.ts +0 -268
- package/src/env/memory/plugin/index.ts +0 -48
- package/src/env/memory/plugin/memory-agent.test.ts +0 -249
- package/src/env/memory/plugin/memory-agent.ts +0 -365
- package/src/env/memory/plugin/memory-manager.ts +0 -198
- package/src/env/memory/plugin/memory-plugin-agent.test.ts +0 -145
- package/src/env/memory/plugin/memory-plugin.ts +0 -210
- package/src/env/memory/plugin/plugin-simplified.test.ts +0 -51
- package/src/env/memory/plugin/recall-memory.test.ts +0 -106
- package/src/env/memory/plugin/recall-memory.ts +0 -53
- package/src/env/memory/plugin/types.ts +0 -101
- package/src/env/memory/tools/memory-agent-tools.ts +0 -228
- package/src/env/memory/types.ts +0 -85
- package/src/env/paths.ts +0 -118
- package/src/env/prompt/index.ts +0 -18
- package/src/env/prompt/memory-prompts.test.ts +0 -91
- package/src/env/prompt/prompt-component.test.ts +0 -491
- package/src/env/prompt/prompt-component.ts +0 -619
- package/src/env/prompt/prompt-config-registration.test.ts +0 -213
- package/src/env/prompt/prompt-config-registration.ts +0 -39
- package/src/env/prompt/prompts-index.ts +0 -504
- package/src/env/prompt/renderer.ts +0 -67
- package/src/env/prompt/types.ts +0 -136
- package/src/env/session/hooks.ts +0 -18
- package/src/env/session/index.ts +0 -37
- package/src/env/session/search-query-parser.test.ts +0 -425
- package/src/env/session/search-query-parser.ts +0 -171
- package/src/env/session/session-checkpoint.test.ts +0 -523
- package/src/env/session/session-component.extract-recent-messages.test.ts +0 -209
- package/src/env/session/session-component.test.ts +0 -132
- package/src/env/session/session-component.ts +0 -1249
- package/src/env/session/session-config-registration.test.ts +0 -138
- package/src/env/session/session-config-registration.ts +0 -52
- package/src/env/session/session-message-converter.test.ts +0 -763
- package/src/env/session/session-message-converter.ts +0 -415
- package/src/env/session/session-message-e2e.test.ts +0 -448
- package/src/env/session/session-search.test.ts +0 -391
- package/src/env/session/session-store.test.ts +0 -362
- package/src/env/session/session-store.ts +0 -141
- package/src/env/session/storage/index.ts +0 -6
- package/src/env/session/storage/memory.ts +0 -502
- package/src/env/session/storage/sqlite.ts +0 -794
- package/src/env/session/types.ts +0 -742
- package/src/env/skill/config.ts +0 -39
- package/src/env/skill/index.ts +0 -6
- package/src/env/skill/parser.test.ts +0 -116
- package/src/env/skill/parser.ts +0 -77
- package/src/env/skill/scanner.test.ts +0 -211
- package/src/env/skill/scanner.ts +0 -119
- package/src/env/skill/skill-component.test.ts +0 -234
- package/src/env/skill/skill-component.ts +0 -352
- package/src/env/skill/skill-config-registration.test.ts +0 -60
- package/src/env/skill/skill-config-registration.ts +0 -43
- package/src/env/skill/tool/index.ts +0 -1
- package/src/env/skill/tool/skill-tool.test.ts +0 -100
- package/src/env/skill/tool/skill-tool.ts +0 -72
- package/src/env/skill/types.ts +0 -64
- package/src/env/task/delegate/delegate-tool.test.ts +0 -498
- package/src/env/task/delegate/delegate-tool.ts +0 -1014
- package/src/env/task/delegate/index.ts +0 -18
- package/src/env/task/delegate/stop-tool.test.ts +0 -140
- package/src/env/task/delegate/stop-tool.ts +0 -119
- package/src/env/task/delegate/task-events.test.ts +0 -178
- package/src/env/task/delegate/task-events.ts +0 -143
- package/src/env/task/hooks/contexts.test.ts +0 -92
- package/src/env/task/hooks/contexts.ts +0 -192
- package/src/env/task/hooks/index.ts +0 -23
- package/src/env/task/hooks/task-hook-points.test.ts +0 -32
- package/src/env/task/hooks/task-hook-points.ts +0 -54
- package/src/env/task/index.ts +0 -7
- package/src/env/task/plugins/index.ts +0 -13
- package/src/env/task/plugins/task-plugin.test.ts +0 -74
- package/src/env/task/plugins/task-plugin.ts +0 -89
- package/src/env/task/plugins/task-tag-plugin.test.ts +0 -377
- package/src/env/task/plugins/task-tag-plugin.ts +0 -319
- package/src/env/task/plugins/task-workflow-extractor.integration.test.ts +0 -226
- package/src/env/task/plugins/workflow-extractor-agent.test.ts +0 -107
- package/src/env/task/plugins/workflow-extractor-agent.ts +0 -225
- package/src/env/task/storage/index.ts +0 -6
- package/src/env/task/storage/sqlite-task-store.test.ts +0 -283
- package/src/env/task/storage/sqlite-task-store.ts +0 -903
- package/src/env/task/storage/task-search.test.ts +0 -291
- package/src/env/task/tag-service.test.ts +0 -198
- package/src/env/task/tag-service.ts +0 -264
- package/src/env/task/task-component.test.ts +0 -193
- package/src/env/task/task-component.ts +0 -658
- package/src/env/task/task-config-registration.test.ts +0 -57
- package/src/env/task/task-config-registration.ts +0 -37
- package/src/env/task/task-types.test.ts +0 -137
- package/src/env/task/tools/complete-tool.ts +0 -44
- package/src/env/task/tools/create-tool.ts +0 -49
- package/src/env/task/tools/delete-tool.ts +0 -43
- package/src/env/task/tools/get-tool.ts +0 -59
- package/src/env/task/tools/index.ts +0 -10
- package/src/env/task/tools/list-tool.ts +0 -40
- package/src/env/task/tools/operation/create-tool.ts +0 -48
- package/src/env/task/tools/operation/delete-tool.ts +0 -43
- package/src/env/task/tools/operation/get-tool.ts +0 -43
- package/src/env/task/tools/operation/index.ts +0 -9
- package/src/env/task/tools/operation/list-tool.ts +0 -40
- package/src/env/task/tools/operation/operation-tools.test.ts +0 -274
- package/src/env/task/tools/operation/operation-types.ts +0 -75
- package/src/env/task/tools/operation/update-tool.ts +0 -47
- package/src/env/task/tools/task-tools.test.ts +0 -203
- package/src/env/task/tools/task-types.test.ts +0 -75
- package/src/env/task/tools/task-types.ts +0 -68
- package/src/env/task/tools/update-tool.ts +0 -70
- package/src/env/task/types.ts +0 -160
- package/src/env/tool/built-in/bash.ts +0 -201
- package/src/env/tool/built-in/echo.ts +0 -29
- package/src/env/tool/built-in/edit-file.test.ts +0 -136
- package/src/env/tool/built-in/edit-file.ts +0 -92
- package/src/env/tool/built-in/glob.test.ts +0 -94
- package/src/env/tool/built-in/glob.ts +0 -65
- package/src/env/tool/built-in/grep.test.ts +0 -122
- package/src/env/tool/built-in/grep.ts +0 -108
- package/src/env/tool/built-in/index.ts +0 -44
- package/src/env/tool/built-in/read-file.test.ts +0 -84
- package/src/env/tool/built-in/read-file.ts +0 -75
- package/src/env/tool/built-in/write-file.test.ts +0 -119
- package/src/env/tool/built-in/write-file.ts +0 -68
- package/src/env/tool/index.ts +0 -24
- package/src/env/tool/registry.test.ts +0 -257
- package/src/env/tool/registry.ts +0 -167
- package/src/env/tool/tool-component.test.ts +0 -559
- package/src/env/tool/tool-component.ts +0 -563
- package/src/env/tool/tool-config-registration.test.ts +0 -249
- package/src/env/tool/tool-config-registration.ts +0 -46
- package/src/env/tool/types.ts +0 -267
- package/src/env/tool/validator.test.ts +0 -143
- package/src/env/tool/validator.ts +0 -44
- package/src/env/types.ts +0 -180
- package/src/env/workflow/ask-user-tool-registration.test.ts +0 -216
- package/src/env/workflow/complex-workflow.integration.test.ts +0 -1900
- package/src/env/workflow/decorators/decorator-node.ts +0 -229
- package/src/env/workflow/decorators/decorator.test.ts +0 -196
- package/src/env/workflow/decorators/edge.ts +0 -82
- package/src/env/workflow/decorators/index.ts +0 -31
- package/src/env/workflow/decorators/node-as.ts +0 -98
- package/src/env/workflow/decorators/workflow.ts +0 -54
- package/src/env/workflow/engine/dag-manager.test.ts +0 -570
- package/src/env/workflow/engine/dag-manager.ts +0 -594
- package/src/env/workflow/engine/engine.ts +0 -1422
- package/src/env/workflow/engine/event-bus.test.ts +0 -359
- package/src/env/workflow/engine/event-bus.ts +0 -156
- package/src/env/workflow/engine/executor-agent-session.test.ts +0 -84
- package/src/env/workflow/engine/executor.test.ts +0 -619
- package/src/env/workflow/engine/executor.ts +0 -593
- package/src/env/workflow/engine/index.ts +0 -24
- package/src/env/workflow/engine/node-registry.test.ts +0 -560
- package/src/env/workflow/engine/node-registry.ts +0 -289
- package/src/env/workflow/engine/resume-removed.test.ts +0 -22
- package/src/env/workflow/engine/scheduler.test.ts +0 -715
- package/src/env/workflow/engine/scheduler.ts +0 -318
- package/src/env/workflow/engine/workflow-engine.test.ts +0 -815
- package/src/env/workflow/extractor/workflow-converter.ts +0 -306
- package/src/env/workflow/fixtures.ts +0 -380
- package/src/env/workflow/index.ts +0 -38
- package/src/env/workflow/integration/run-resume-unified.test.ts +0 -186
- package/src/env/workflow/integration/service-integration.test.ts +0 -267
- package/src/env/workflow/metadata/keys.ts +0 -12
- package/src/env/workflow/nodes/agent-component-adapter.test.ts +0 -318
- package/src/env/workflow/nodes/agent-component-adapter.ts +0 -448
- package/src/env/workflow/nodes/agent-node.test.ts +0 -371
- package/src/env/workflow/nodes/agent-node.ts +0 -598
- package/src/env/workflow/nodes/ask-user-node.ts +0 -113
- package/src/env/workflow/nodes/condition-node.ts +0 -200
- package/src/env/workflow/nodes/index.ts +0 -9
- package/src/env/workflow/nodes/merge-node.ts +0 -141
- package/src/env/workflow/nodes/skill-node.test.ts +0 -253
- package/src/env/workflow/nodes/skill-node.ts +0 -393
- package/src/env/workflow/nodes/tool-node.test.ts +0 -251
- package/src/env/workflow/nodes/tool-node.ts +0 -493
- package/src/env/workflow/nodes/workflow-llm-history.test.ts +0 -455
- package/src/env/workflow/nodes/workflow-node.test.ts +0 -315
- package/src/env/workflow/nodes/workflow-node.ts +0 -311
- package/src/env/workflow/service/index.ts +0 -27
- package/src/env/workflow/service/registry.test.ts +0 -133
- package/src/env/workflow/service/registry.ts +0 -71
- package/src/env/workflow/service/workflow-service.test.ts +0 -310
- package/src/env/workflow/service/workflow-service.ts +0 -393
- package/src/env/workflow/storage/index.ts +0 -28
- package/src/env/workflow/storage/mock-repositories.ts +0 -385
- package/src/env/workflow/storage/sqlite.test.ts +0 -179
- package/src/env/workflow/storage/sqlite.ts +0 -163
- package/src/env/workflow/storage/workflow-repo.test.ts +0 -780
- package/src/env/workflow/storage/workflow-repo.ts +0 -342
- package/src/env/workflow/tools/ask-user-tool.ts +0 -82
- package/src/env/workflow/tools/index.ts +0 -26
- package/src/env/workflow/tools/run-workflow.test.ts +0 -352
- package/src/env/workflow/tools/run-workflow.ts +0 -214
- package/src/env/workflow/types/context.ts +0 -18
- package/src/env/workflow/types/decorators-types.ts +0 -198
- package/src/env/workflow/types/event.test.ts +0 -515
- package/src/env/workflow/types/event.ts +0 -193
- package/src/env/workflow/types/index.ts +0 -49
- package/src/env/workflow/types/run.test.ts +0 -437
- package/src/env/workflow/types/run.ts +0 -173
- package/src/env/workflow/types/workflow-hil.ts +0 -114
- package/src/env/workflow/types/workflow-message.test.ts +0 -138
- package/src/env/workflow/types/workflow-message.ts +0 -196
- package/src/env/workflow/types/workflow-session.test.ts +0 -95
- package/src/env/workflow/types/workflow-session.ts +0 -59
- package/src/env/workflow/types/workflow.test.ts +0 -495
- package/src/env/workflow/types/workflow.ts +0 -195
- package/src/env/workflow/types_compat.ts +0 -51
- package/src/env/workflow/utils/create-workflow.ts +0 -47
- package/src/env/workflow/utils/execution-state.ts +0 -245
- package/src/env/workflow/utils/index.ts +0 -18
- package/src/env/workflow/utils/node-registry-helper.ts +0 -58
- package/src/env/workflow/utils/recovery-validator.test.ts +0 -460
- package/src/env/workflow/utils/recovery-validator.ts +0 -377
- package/src/env/workflow/utils/session-parser.test.ts +0 -111
- package/src/env/workflow/utils/session-parser.ts +0 -94
- package/src/env/workflow/utils/session-recovery.test.ts +0 -334
- package/src/env/workflow/utils/session-recovery.ts +0 -188
- package/src/env/workflow/utils/template-resolver.test.ts +0 -258
- package/src/env/workflow/utils/template-resolver.ts +0 -436
- package/src/env/workflow/utils/validation-rules.ts +0 -149
- package/src/env/workflow/workflow-component.ts +0 -544
- package/src/index.ts +0 -422
- package/src/utils/id.ts +0 -21
|
@@ -1,1014 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview delegate_task Tool
|
|
3
|
-
*
|
|
4
|
-
* 基于 agent-core 的 delegate_task 实现
|
|
5
|
-
* 参考: packages/core/src/core/environment/expend/task/task-tool.ts
|
|
6
|
-
*
|
|
7
|
-
* 功能:
|
|
8
|
-
* - 委派子Agent执行任务(同步/后台模式)
|
|
9
|
-
* - 支持多种 subagent 类型
|
|
10
|
-
* - 支持任务关联(task_id)
|
|
11
|
-
* - 发布 EnvEvent 事件
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { z } from "zod";
|
|
15
|
-
import type { Tool, ToolContext, ToolResult } from "../../tool/types";
|
|
16
|
-
import type { TaskComponent } from "../task-component";
|
|
17
|
-
import type { SessionComponent } from "../../session/session-component";
|
|
18
|
-
import { createLogger } from "../../log-trace/logger";
|
|
19
|
-
import {
|
|
20
|
-
TaskEventTypes,
|
|
21
|
-
createTaskStartedPayload,
|
|
22
|
-
createTaskProgressPayload,
|
|
23
|
-
createTaskCompletedPayload
|
|
24
|
-
} from "./task-events";
|
|
25
|
-
import { env } from "process";
|
|
26
|
-
import { AgentComponent } from "../../agent";
|
|
27
|
-
|
|
28
|
-
// Hook 机制
|
|
29
|
-
import { globalHookManager } from "../../hook/global-hook-manager";
|
|
30
|
-
import { TaskHookPoints } from "../hooks";
|
|
31
|
-
import type { TaskDelegateContext } from "../hooks/contexts";
|
|
32
|
-
import type { TagService } from "../tag-service";
|
|
33
|
-
|
|
34
|
-
const logger = createLogger("task:delegate");
|
|
35
|
-
|
|
36
|
-
// ============================================================================
|
|
37
|
-
// SubAgent Types (简化版)
|
|
38
|
-
// ============================================================================
|
|
39
|
-
|
|
40
|
-
export interface SubAgentSpec {
|
|
41
|
-
id: string;
|
|
42
|
-
name: string;
|
|
43
|
-
description: string;
|
|
44
|
-
mode: "subagent" | "primary" | "all";
|
|
45
|
-
promptOverride?: string;
|
|
46
|
-
/** 允许的工具列表(白名单) */
|
|
47
|
-
allowedTools?: string[];
|
|
48
|
-
/** 拒绝的工具列表(黑名单) */
|
|
49
|
-
deniedTools?: string[];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const builtInSubAgents: SubAgentSpec[] = [
|
|
53
|
-
{
|
|
54
|
-
id: "general",
|
|
55
|
-
name: "general",
|
|
56
|
-
mode: "subagent",
|
|
57
|
-
description: "General-purpose agent for researching complex questions and executing multi-step tasks.",
|
|
58
|
-
promptOverride: `You are a subagent created by the main agent to handle a specific task.
|
|
59
|
-
|
|
60
|
-
## Your Role
|
|
61
|
-
- You were created to handle: {task_description}
|
|
62
|
-
- Complete this task. That's your entire purpose.
|
|
63
|
-
- You are NOT the main agent. Don't try to be.
|
|
64
|
-
|
|
65
|
-
## Task Context Awareness (Required Behavior)
|
|
66
|
-
|
|
67
|
-
**IMPORTANT: Before starting any work, you MUST gather task context to avoid working with outdated or missing information.**
|
|
68
|
-
|
|
69
|
-
1. **Read task details first**: Use \`task_get\` to read the task's:
|
|
70
|
-
- \`description\`: Detailed description of what needs to be done
|
|
71
|
-
- \`goals_and_expected_deliverables\`: Clear success criteria and expected outputs
|
|
72
|
-
- \`current_status\`: Current work progress
|
|
73
|
-
- \`parent_task_id\`: If exists, this is a sub-task
|
|
74
|
-
|
|
75
|
-
2. **Read recent operations**: Use \`task_operation_list\` to get the last ~15 operation records
|
|
76
|
-
- These provide history, progress, decisions, and context from previous work
|
|
77
|
-
|
|
78
|
-
3. **Read parent task context** (if \`parent_task_id\` exists):
|
|
79
|
-
- Use \`task_get\` to read the parent task's description and goals
|
|
80
|
-
- Use \`task_operation_list\` to get parent's recent operations
|
|
81
|
-
- This forms the overall task background and ensures alignment
|
|
82
|
-
|
|
83
|
-
**Why this matters**:
|
|
84
|
-
- The main agent may have made critical decisions recorded in operations
|
|
85
|
-
- Parent task goals provide the broader context for your sub-task
|
|
86
|
-
- Without this context, you risk working on wrong/outdated goals
|
|
87
|
-
|
|
88
|
-
## Rules
|
|
89
|
-
1. **Gather context first** - Always read task details and operations before starting
|
|
90
|
-
2. **Stay focused** - Do your assigned task, nothing else
|
|
91
|
-
3. **Complete the task** - Your final message will be automatically reported to the main agent
|
|
92
|
-
4. **Don't initiate** - No heartbeats, no proactive actions, no side quests
|
|
93
|
-
5. **Be ephemeral** - You may be terminated after task completion. That's fine.
|
|
94
|
-
6. **No nested delegation** - Do NOT use delegate_task or stop_task tools. Complete the task yourself.
|
|
95
|
-
|
|
96
|
-
## Execution
|
|
97
|
-
- Use the available tools to complete the task
|
|
98
|
-
- If you need more information, ask the main agent through the result
|
|
99
|
-
- Return a clear summary of what you did and the results`,
|
|
100
|
-
// Prevent nested delegation by denying delegate_task and stop_task
|
|
101
|
-
deniedTools: ["delegate_task", "stop_task"],
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
id: "explore",
|
|
105
|
-
name: "explore",
|
|
106
|
-
mode: "subagent",
|
|
107
|
-
description: "Fast agent specialized for exploring codebases, finding files, and searching for patterns.",
|
|
108
|
-
allowedTools: ["glob", "grep", "read", "bash"],
|
|
109
|
-
deniedTools: ["delegate_task", "stop_task"],
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
id: "file_agent",
|
|
113
|
-
name: "file_agent",
|
|
114
|
-
mode: "subagent",
|
|
115
|
-
description: "File operation expert, skilled at reading, writing, searching and organizing files.",
|
|
116
|
-
allowedTools: ["file_read", "file_write", "file_glob", "grep", "glob", "read"],
|
|
117
|
-
deniedTools: ["delegate_task", "stop_task"],
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
id: "web_search_agent",
|
|
121
|
-
name: "web_search_agent",
|
|
122
|
-
mode: "subagent",
|
|
123
|
-
description: "Web search expert, using Exa search engine to get latest information.",
|
|
124
|
-
allowedTools: ["exa_web_search_exa"],
|
|
125
|
-
deniedTools: ["delegate_task", "stop_task"],
|
|
126
|
-
},
|
|
127
|
-
];
|
|
128
|
-
|
|
129
|
-
function getSubAgentSpec(id: string): SubAgentSpec | undefined {
|
|
130
|
-
return builtInSubAgents.find((agent) => agent.id === id);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function listSubAgents(): SubAgentSpec[] {
|
|
134
|
-
return [...builtInSubAgents];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function getSubAgentToolDescription(): string {
|
|
138
|
-
return builtInSubAgents.map((agent) => `- ${agent.id}: ${agent.description}`).join("\n");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// ============================================================================
|
|
142
|
-
// SubAgent Registration Helper
|
|
143
|
-
// ============================================================================
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* 确保 subAgent 已注册到 AgentComponent
|
|
147
|
-
*
|
|
148
|
-
* @param agentComponent AgentComponent 实例
|
|
149
|
-
* @param subagentType subAgent 类型(用作 agentName)
|
|
150
|
-
* @param basePrompt 基础 system prompt
|
|
151
|
-
* @param subAgent subAgent 配置(可能包含 allowedTools)
|
|
152
|
-
* @param deniedTools 拒绝的工具列表
|
|
153
|
-
* @returns 注册的 agent 实例
|
|
154
|
-
*/
|
|
155
|
-
function ensureSubAgentRegistered(
|
|
156
|
-
agentComponent: any,
|
|
157
|
-
subagentType: string,
|
|
158
|
-
basePrompt: string,
|
|
159
|
-
subAgent: SubAgentSpec | undefined,
|
|
160
|
-
deniedTools: string[]
|
|
161
|
-
): any {
|
|
162
|
-
let agentInstance = agentComponent.getAgent(subagentType);
|
|
163
|
-
if (!agentInstance) {
|
|
164
|
-
const agentConfig: Record<string, unknown> = {
|
|
165
|
-
type: "sub",
|
|
166
|
-
systemPrompt: basePrompt,
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// 添加 allowedTools(如果有)
|
|
170
|
-
if (subAgent?.allowedTools && subAgent.allowedTools.length > 0) {
|
|
171
|
-
agentConfig.allowedTools = subAgent.allowedTools;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// 添加 deniedTools(如果有)
|
|
175
|
-
if (deniedTools.length > 0) {
|
|
176
|
-
agentConfig.deniedTools = deniedTools;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
agentInstance = agentComponent.registerAgent(subagentType, agentConfig as any);
|
|
180
|
-
logger.debug(`[delegate] Registered subagent: ${subagentType}`);
|
|
181
|
-
}
|
|
182
|
-
return agentInstance;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// ============================================================================
|
|
186
|
-
// Tool Parameters Schema
|
|
187
|
-
// ============================================================================
|
|
188
|
-
|
|
189
|
-
export const DelegateToolParameters = z.object({
|
|
190
|
-
description: z.string().describe("A short (3-5 words) description of the task"),
|
|
191
|
-
prompt: z.string().describe("The task for the agent to perform"),
|
|
192
|
-
subagent_type: z
|
|
193
|
-
.string()
|
|
194
|
-
.describe("The type of specialized agent to use for this task")
|
|
195
|
-
.default("general"),
|
|
196
|
-
background: z
|
|
197
|
-
.boolean()
|
|
198
|
-
.describe("Whether to run the task in background. If true, returns immediately and notifies when complete (default: false)")
|
|
199
|
-
.default(false),
|
|
200
|
-
timeout: z
|
|
201
|
-
.number()
|
|
202
|
-
.describe("Task timeout in milliseconds. If set, task will be terminated after timeout (optional)")
|
|
203
|
-
.optional(),
|
|
204
|
-
cleanup: z
|
|
205
|
-
.enum(["delete", "keep"] as const)
|
|
206
|
-
.describe("Whether to delete sub session after completion. 'delete' removes the session, 'keep' retains it (default: keep)")
|
|
207
|
-
.default("keep")
|
|
208
|
-
.optional(),
|
|
209
|
-
task_id: z
|
|
210
|
-
.number()
|
|
211
|
-
.describe("Optional task ID to associate with this delegate task, for tracking in operation records")
|
|
212
|
-
.optional(),
|
|
213
|
-
reason: z
|
|
214
|
-
.string()
|
|
215
|
-
.describe("Brief reason for calling this tool (max 30 chars, e.g., 'Delegate refactor task')")
|
|
216
|
-
.optional(),
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
export type DelegateToolParams = z.infer<typeof DelegateToolParameters>;
|
|
220
|
-
|
|
221
|
-
// ============================================================================
|
|
222
|
-
// Delegate Tool Implementation
|
|
223
|
-
// ============================================================================
|
|
224
|
-
|
|
225
|
-
export interface DelegateToolResult {
|
|
226
|
-
tool: Tool;
|
|
227
|
-
backgroundTaskManager: BackgroundTaskManager;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export interface BackgroundTask {
|
|
231
|
-
id: string;
|
|
232
|
-
subSessionId: string;
|
|
233
|
-
parentSessionId: string;
|
|
234
|
-
description: string;
|
|
235
|
-
subagentType: string;
|
|
236
|
-
status: "pending" | "running" | "completed" | "failed" | "timeout" | "stopped";
|
|
237
|
-
createdAt: number;
|
|
238
|
-
startedAt?: number;
|
|
239
|
-
completedAt?: number;
|
|
240
|
-
result?: string;
|
|
241
|
-
error?: string;
|
|
242
|
-
progress?: number;
|
|
243
|
-
progressMessage?: string;
|
|
244
|
-
abortController?: AbortController;
|
|
245
|
-
taskId?: number; // 关联的任务ID
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export interface CreateBackgroundTaskOptions {
|
|
249
|
-
parentSessionId: string;
|
|
250
|
-
description: string;
|
|
251
|
-
prompt: string;
|
|
252
|
-
subagentType: string;
|
|
253
|
-
timeout?: number;
|
|
254
|
-
cleanup?: "delete" | "keep";
|
|
255
|
-
taskId?: number;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const DEFAULT_TIMEOUT = 900000; // 15 minutes
|
|
259
|
-
const PROGRESS_INTERVAL = 120000; // 2 minutes
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Background Task Manager (简化版)
|
|
263
|
-
*
|
|
264
|
-
* 管理后台任务的创建、执行、状态跟踪
|
|
265
|
-
* 支持 EnvEvent 发布
|
|
266
|
-
*/
|
|
267
|
-
export class BackgroundTaskManager {
|
|
268
|
-
private tasks: Map<string, BackgroundTask> = new Map();
|
|
269
|
-
private progressTimers: Map<string, NodeJS.Timeout> = new Map();
|
|
270
|
-
private abortControllers: Map<string, AbortController> = new Map();
|
|
271
|
-
|
|
272
|
-
constructor(private env: any) {
|
|
273
|
-
// env 应该具有 pushEnvEvent 和 getComponent 方法
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Get SessionComponent from env
|
|
278
|
-
*/
|
|
279
|
-
private getSessionComponent(): any {
|
|
280
|
-
return this.env?.getComponent?.("session");
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async createTask(options: CreateBackgroundTaskOptions): Promise<{ taskId: string; subSessionId: string }> {
|
|
284
|
-
const { parentSessionId, description, prompt, subagentType, timeout, cleanup, taskId } = options;
|
|
285
|
-
|
|
286
|
-
const taskIdGen = `task_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
287
|
-
|
|
288
|
-
// Get SessionComponent
|
|
289
|
-
const sessionComponent = this.getSessionComponent();
|
|
290
|
-
if (!sessionComponent) {
|
|
291
|
-
throw new Error("SessionComponent not found");
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Create sub-session
|
|
295
|
-
const parentSession = await sessionComponent.get(parentSessionId);
|
|
296
|
-
if (!parentSession) {
|
|
297
|
-
throw new Error(`Parent session not found: ${parentSessionId}`);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const metadata: Record<string, unknown> = {
|
|
301
|
-
subagent_type: subagentType,
|
|
302
|
-
created_by: "subagent",
|
|
303
|
-
task_description: description,
|
|
304
|
-
};
|
|
305
|
-
if (taskId) {
|
|
306
|
-
metadata.task_id = taskId;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const subSession = await sessionComponent.create({
|
|
310
|
-
title: `${description} (@${subagentType} subagent)`,
|
|
311
|
-
metadata,
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
if (!subSession) {
|
|
315
|
-
throw new Error("Failed to create sub-session");
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const abortController = new AbortController();
|
|
319
|
-
|
|
320
|
-
const task: BackgroundTask = {
|
|
321
|
-
id: taskIdGen,
|
|
322
|
-
subSessionId: subSession.id,
|
|
323
|
-
parentSessionId,
|
|
324
|
-
description,
|
|
325
|
-
subagentType,
|
|
326
|
-
status: "pending",
|
|
327
|
-
createdAt: Date.now(),
|
|
328
|
-
abortController,
|
|
329
|
-
taskId,
|
|
330
|
-
};
|
|
331
|
-
this.tasks.set(taskIdGen, task);
|
|
332
|
-
this.abortControllers.set(taskIdGen, abortController);
|
|
333
|
-
|
|
334
|
-
// Publish task.started event
|
|
335
|
-
this.publishEvent(TaskEventTypes.TASK_STARTED, createTaskStartedPayload(task, parentSessionId), parentSessionId);
|
|
336
|
-
|
|
337
|
-
// Start execution asynchronously
|
|
338
|
-
this.executeTask(taskIdGen, prompt, timeout, cleanup, parentSessionId).catch((err) => {
|
|
339
|
-
logger.error(`[BackgroundTaskManager] executeTask unhandled rejection`, {
|
|
340
|
-
taskId: taskIdGen,
|
|
341
|
-
error: err instanceof Error ? err.message : String(err),
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
return { taskId: taskIdGen, subSessionId: subSession.id };
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
private async executeTask(
|
|
349
|
-
taskId: string,
|
|
350
|
-
prompt: string,
|
|
351
|
-
timeout?: number,
|
|
352
|
-
cleanup?: "delete" | "keep",
|
|
353
|
-
parentSessionId?: string
|
|
354
|
-
): Promise<void> {
|
|
355
|
-
const task = this.tasks.get(taskId);
|
|
356
|
-
if (!task) {
|
|
357
|
-
logger.warn(`[BackgroundTaskManager] executeTask: Task not found`, { taskId });
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
task.status = "running";
|
|
362
|
-
task.startedAt = Date.now();
|
|
363
|
-
|
|
364
|
-
const timeoutMs = timeout || DEFAULT_TIMEOUT;
|
|
365
|
-
const abortController = this.abortControllers.get(taskId);
|
|
366
|
-
|
|
367
|
-
// Start progress reporter
|
|
368
|
-
this.startProgressReporter(taskId, parentSessionId || task.parentSessionId);
|
|
369
|
-
|
|
370
|
-
try {
|
|
371
|
-
const sessionComponent = this.getSessionComponent();
|
|
372
|
-
const subSession = await sessionComponent.get(task.subSessionId);
|
|
373
|
-
if (!subSession) {
|
|
374
|
-
throw new Error(`Sub session not found: ${task.subSessionId}`);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// Execute with timeout and abort support
|
|
378
|
-
const result = await this.executeWithAbort(subSession, prompt, timeoutMs, abortController?.signal);
|
|
379
|
-
|
|
380
|
-
if (abortController?.signal.aborted) {
|
|
381
|
-
logger.info(`[BackgroundTaskManager] Task was aborted`, { taskId });
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
task.status = "completed";
|
|
386
|
-
task.completedAt = Date.now();
|
|
387
|
-
task.result = result;
|
|
388
|
-
|
|
389
|
-
// Publish task.completed event
|
|
390
|
-
const executionTimeMs = task.completedAt - task.startedAt!;
|
|
391
|
-
this.publishEvent(
|
|
392
|
-
TaskEventTypes.TASK_COMPLETED,
|
|
393
|
-
createTaskCompletedPayload(task, parentSessionId || task.parentSessionId, executionTimeMs),
|
|
394
|
-
parentSessionId || task.parentSessionId
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
logger.info(`[BackgroundTaskManager] Task completed successfully`, {
|
|
398
|
-
taskId,
|
|
399
|
-
executionTimeMs,
|
|
400
|
-
});
|
|
401
|
-
} catch (error) {
|
|
402
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
403
|
-
const isStoppedError =
|
|
404
|
-
errorMessage.toLowerCase().includes("stopped") ||
|
|
405
|
-
errorMessage.toLowerCase().includes("aborted");
|
|
406
|
-
|
|
407
|
-
if (isStoppedError) {
|
|
408
|
-
task.status = "stopped";
|
|
409
|
-
// Publish task.stopped event
|
|
410
|
-
this.publishEvent(
|
|
411
|
-
TaskEventTypes.TASK_STOPPED,
|
|
412
|
-
createTaskCompletedPayload(task, parentSessionId || task.parentSessionId,
|
|
413
|
-
task.completedAt! - task.startedAt!),
|
|
414
|
-
parentSessionId || task.parentSessionId
|
|
415
|
-
);
|
|
416
|
-
} else if (errorMessage.includes("timeout")) {
|
|
417
|
-
task.status = "timeout";
|
|
418
|
-
// Publish task.timeout event
|
|
419
|
-
this.publishEvent(
|
|
420
|
-
TaskEventTypes.TASK_TIMEOUT,
|
|
421
|
-
createTaskCompletedPayload(task, parentSessionId || task.parentSessionId,
|
|
422
|
-
task.completedAt! - task.startedAt!),
|
|
423
|
-
parentSessionId || task.parentSessionId
|
|
424
|
-
);
|
|
425
|
-
} else {
|
|
426
|
-
task.status = "failed";
|
|
427
|
-
// Publish task.failed event
|
|
428
|
-
this.publishEvent(
|
|
429
|
-
TaskEventTypes.TASK_FAILED,
|
|
430
|
-
createTaskCompletedPayload(task, parentSessionId || task.parentSessionId,
|
|
431
|
-
task.completedAt! - task.startedAt!),
|
|
432
|
-
parentSessionId || task.parentSessionId
|
|
433
|
-
);
|
|
434
|
-
}
|
|
435
|
-
task.error = errorMessage;
|
|
436
|
-
task.completedAt = Date.now();
|
|
437
|
-
|
|
438
|
-
logger.error(`[BackgroundTaskManager] Task execution error`, {
|
|
439
|
-
taskId,
|
|
440
|
-
status: task.status,
|
|
441
|
-
error: errorMessage,
|
|
442
|
-
});
|
|
443
|
-
} finally {
|
|
444
|
-
// Stop progress reporter
|
|
445
|
-
this.stopProgressReporter(taskId);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
private async executeWithAbort(
|
|
450
|
-
subSession: any,
|
|
451
|
-
prompt: string,
|
|
452
|
-
timeoutMs: number,
|
|
453
|
-
signal?: AbortSignal
|
|
454
|
-
): Promise<string> {
|
|
455
|
-
return new Promise((resolve, reject) => {
|
|
456
|
-
const timer = setTimeout(() => {
|
|
457
|
-
reject(new Error(`Task execution timeout after ${timeoutMs}ms`));
|
|
458
|
-
}, timeoutMs);
|
|
459
|
-
|
|
460
|
-
signal?.addEventListener("abort", () => {
|
|
461
|
-
clearTimeout(timer);
|
|
462
|
-
reject(new Error("Task execution stopped"));
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
// Build full prompt
|
|
466
|
-
const metadata = subSession.info?.metadata || {};
|
|
467
|
-
const taskId = metadata.task_id as number | undefined;
|
|
468
|
-
const taskDescription = metadata.task_description as string || "";
|
|
469
|
-
const sessionId = subSession.id;
|
|
470
|
-
const subagentType = metadata.subagent_type as string || "general";
|
|
471
|
-
|
|
472
|
-
const subAgent = getSubAgentSpec(subagentType);
|
|
473
|
-
let basePrompt = subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
474
|
-
|
|
475
|
-
// Get denied tools from subagent config
|
|
476
|
-
const deniedTools = subAgent?.deniedTools || [];
|
|
477
|
-
|
|
478
|
-
// Only replace valid placeholders
|
|
479
|
-
let fullPrompt = basePrompt.replace(/{task_description}/g, taskDescription || "N/A");
|
|
480
|
-
|
|
481
|
-
// Add session info and execution guidelines
|
|
482
|
-
fullPrompt += `
|
|
483
|
-
|
|
484
|
-
---
|
|
485
|
-
|
|
486
|
-
# Session Info
|
|
487
|
-
- task_id: ${taskId || "N/A"}
|
|
488
|
-
- session_id: ${sessionId}
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
## 用户指令
|
|
493
|
-
${prompt}
|
|
494
|
-
|
|
495
|
-
---
|
|
496
|
-
|
|
497
|
-
## 执行规范
|
|
498
|
-
- 使用可用工具完成任务
|
|
499
|
-
- 返回清晰的任务执行结果摘要
|
|
500
|
-
- 适时调用 task_operation_create 记录进展`;
|
|
501
|
-
|
|
502
|
-
// Get AgentComponent and ensure subagent is registered
|
|
503
|
-
const agentComponent = this.env?.getComponent?.("agent") as any;
|
|
504
|
-
|
|
505
|
-
if (!agentComponent) {
|
|
506
|
-
clearTimeout(timer);
|
|
507
|
-
reject(new Error("AgentComponent not found"));
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
// 注册 subagent(使用公共函数)
|
|
512
|
-
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgent, deniedTools);
|
|
513
|
-
|
|
514
|
-
// Execute using handle_query with agentType specified
|
|
515
|
-
this.env.handle_query?.(fullPrompt, {
|
|
516
|
-
sessionId: sessionId,
|
|
517
|
-
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
518
|
-
agentType: subagentType, // handle_query will use this agent
|
|
519
|
-
})
|
|
520
|
-
.then((result: string) => {
|
|
521
|
-
clearTimeout(timer);
|
|
522
|
-
resolve(result);
|
|
523
|
-
})
|
|
524
|
-
.catch((error: Error) => {
|
|
525
|
-
clearTimeout(timer);
|
|
526
|
-
reject(error);
|
|
527
|
-
});
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
/**
|
|
532
|
-
* Start progress reporter for a task
|
|
533
|
-
*/
|
|
534
|
-
private startProgressReporter(taskId: string, parentSessionId: string): void {
|
|
535
|
-
const timer = setInterval(() => {
|
|
536
|
-
const task = this.tasks.get(taskId);
|
|
537
|
-
if (!task || task.status !== "running") {
|
|
538
|
-
this.stopProgressReporter(taskId);
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Update progress
|
|
543
|
-
if (task.startedAt) {
|
|
544
|
-
const elapsedMs = Date.now() - task.startedAt;
|
|
545
|
-
task.progress = Math.min(95, Math.floor((elapsedMs / PROGRESS_INTERVAL) * 100));
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
// Publish progress event
|
|
549
|
-
this.publishEvent(
|
|
550
|
-
TaskEventTypes.TASK_PROGRESS,
|
|
551
|
-
createTaskProgressPayload(task, parentSessionId),
|
|
552
|
-
parentSessionId
|
|
553
|
-
);
|
|
554
|
-
}, PROGRESS_INTERVAL);
|
|
555
|
-
|
|
556
|
-
this.progressTimers.set(taskId, timer);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Stop progress reporter for a task
|
|
561
|
-
*/
|
|
562
|
-
private stopProgressReporter(taskId: string): void {
|
|
563
|
-
const timer = this.progressTimers.get(taskId);
|
|
564
|
-
if (timer) {
|
|
565
|
-
clearInterval(timer);
|
|
566
|
-
this.progressTimers.delete(taskId);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* Publish an event to the environment
|
|
572
|
-
*/
|
|
573
|
-
private publishEvent<T>(type: string, payload: T, triggerSessionId?: string): void {
|
|
574
|
-
if (this.env?.pushEnvEvent) {
|
|
575
|
-
this.env.pushEnvEvent({
|
|
576
|
-
type,
|
|
577
|
-
metadata: {
|
|
578
|
-
trigger_session_id: triggerSessionId,
|
|
579
|
-
source: "task.delegate",
|
|
580
|
-
},
|
|
581
|
-
payload,
|
|
582
|
-
});
|
|
583
|
-
logger.info(`[BackgroundTaskManager] Event published: ${type}`, { payload });
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
stopTask(taskId: string): { success: boolean; task?: BackgroundTask; message: string } {
|
|
588
|
-
const task = this.tasks.get(taskId);
|
|
589
|
-
if (!task) {
|
|
590
|
-
return { success: false, message: "Task not found" };
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
if (task.status === "completed" || task.status === "failed" || task.status === "stopped" || task.status === "timeout") {
|
|
594
|
-
return {
|
|
595
|
-
success: false,
|
|
596
|
-
task,
|
|
597
|
-
message: `Cannot stop task with status: ${task.status}`,
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
task.status = "stopped";
|
|
602
|
-
task.abortController?.abort();
|
|
603
|
-
task.completedAt = Date.now();
|
|
604
|
-
|
|
605
|
-
// Publish task.stopped event
|
|
606
|
-
this.publishEvent(
|
|
607
|
-
TaskEventTypes.TASK_STOPPED,
|
|
608
|
-
createTaskCompletedPayload(task, task.parentSessionId, task.completedAt - task.startedAt!),
|
|
609
|
-
task.parentSessionId
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
return { success: true, task, message: "Task has been stopped" };
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
getTask(taskId: string): BackgroundTask | undefined {
|
|
616
|
-
return this.tasks.get(taskId);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
listTasks(): BackgroundTask[] {
|
|
620
|
-
return Array.from(this.tasks.values());
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* Dispose and cleanup all resources
|
|
625
|
-
* Call this when shutting down to prevent process from hanging
|
|
626
|
-
*/
|
|
627
|
-
dispose(): void {
|
|
628
|
-
// Clear all progress timers
|
|
629
|
-
for (const [taskId, timer] of this.progressTimers) {
|
|
630
|
-
clearInterval(timer);
|
|
631
|
-
logger.debug(`[BackgroundTaskManager] Cleared progress timer for task: ${taskId}`);
|
|
632
|
-
}
|
|
633
|
-
this.progressTimers.clear();
|
|
634
|
-
|
|
635
|
-
// Abort all running tasks
|
|
636
|
-
for (const [taskId, controller] of this.abortControllers) {
|
|
637
|
-
controller.abort();
|
|
638
|
-
logger.debug(`[BackgroundTaskManager] Aborted task: ${taskId}`);
|
|
639
|
-
}
|
|
640
|
-
this.abortControllers.clear();
|
|
641
|
-
|
|
642
|
-
// Clear all tasks
|
|
643
|
-
this.tasks.clear();
|
|
644
|
-
|
|
645
|
-
logger.info(`[BackgroundTaskManager] Disposed`);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
/**
|
|
650
|
-
* Create delegate_task tool
|
|
651
|
-
*/
|
|
652
|
-
export function createDelegateTool(taskComponent: TaskComponent): Tool {
|
|
653
|
-
// Pass taskComponent.env instead of taskComponent, so BackgroundTaskManager
|
|
654
|
-
// can correctly call this.env.getComponent("session")
|
|
655
|
-
const env = (taskComponent as any).env;
|
|
656
|
-
const backgroundTaskManager = new BackgroundTaskManager(env);
|
|
657
|
-
|
|
658
|
-
const tool: Tool = {
|
|
659
|
-
name: "delegate_task",
|
|
660
|
-
description: `Launch a new sub-agent to handle complex, multistep tasks autonomously.
|
|
661
|
-
|
|
662
|
-
Available agent types:
|
|
663
|
-
${getSubAgentToolDescription()}
|
|
664
|
-
|
|
665
|
-
When using the delegate_task tool, you must specify a subagent_type parameter to select which agent type to use.
|
|
666
|
-
|
|
667
|
-
## When to use delegate_task:
|
|
668
|
-
- When you need to perform complex, multi-step tasks that require independent execution
|
|
669
|
-
- When you need to explore a codebase thoroughly (use "explore" subagent)
|
|
670
|
-
- When you need to run long-running tasks without blocking the main agent (use background=true)
|
|
671
|
-
|
|
672
|
-
## Parameters:
|
|
673
|
-
- **description**: A short (3-5 words) description of the task
|
|
674
|
-
- **prompt**: The task for the agent to perform
|
|
675
|
-
- **subagent_type**: The type of specialized agent to use (e.g., "general", "explore")
|
|
676
|
-
- **background**: Whether to run in background (default: false)
|
|
677
|
-
- **timeout**: Task timeout in milliseconds (optional)
|
|
678
|
-
- **task_id**: Optional task ID to associate with this delegate task
|
|
679
|
-
|
|
680
|
-
## Synchronous vs Background mode:
|
|
681
|
-
**Synchronous mode (default)**: Waits for subagent to complete and returns result directly
|
|
682
|
-
**Background mode (background=true)**: Returns immediately with "accepted" status, runs independently`,
|
|
683
|
-
parameters: DelegateToolParameters,
|
|
684
|
-
execute: async (args: unknown, ctx: ToolContext): Promise<ToolResult> => {
|
|
685
|
-
const startTime = Date.now();
|
|
686
|
-
const params = DelegateToolParameters.parse(args);
|
|
687
|
-
const { description, prompt, subagent_type = "general", background = false, timeout, cleanup, task_id, reason } = params;
|
|
688
|
-
|
|
689
|
-
const parentSessionId = ctx.session_id || "default";
|
|
690
|
-
|
|
691
|
-
logger.info(`[delegate_task] Called: description=${description}, subagent_type=${subagent_type}, background=${background}, task_id=${task_id}`);
|
|
692
|
-
|
|
693
|
-
// Validate subagent_type
|
|
694
|
-
const subAgent = getSubAgentSpec(subagent_type);
|
|
695
|
-
if (!subAgent) {
|
|
696
|
-
return {
|
|
697
|
-
success: false,
|
|
698
|
-
output: "",
|
|
699
|
-
error: `Unknown subagent type: ${subagent_type}`,
|
|
700
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
// Get TagService from TaskComponent
|
|
705
|
-
const tagService = taskComponent.getTagService();
|
|
706
|
-
|
|
707
|
-
// Build initial prompt - hook will inject similar tasks info
|
|
708
|
-
let promptWithTaskInfo = prompt;
|
|
709
|
-
|
|
710
|
-
// Execute delegate:before Hook (can modify prompt, subagentType, etc.)
|
|
711
|
-
const delegateCtx: TaskDelegateContext = {
|
|
712
|
-
taskId: task_id,
|
|
713
|
-
prompt: promptWithTaskInfo,
|
|
714
|
-
subagentType: subagent_type,
|
|
715
|
-
background,
|
|
716
|
-
timeout,
|
|
717
|
-
cleanup,
|
|
718
|
-
reason,
|
|
719
|
-
tagService,
|
|
720
|
-
};
|
|
721
|
-
|
|
722
|
-
const hookCtx = {
|
|
723
|
-
component: { name: "task", version: "1.0.0" },
|
|
724
|
-
data: delegateCtx,
|
|
725
|
-
metadata: { sessionId: parentSessionId },
|
|
726
|
-
phase: "before" as const,
|
|
727
|
-
hookPoint: TaskHookPoints.DELEGATE_BEFORE,
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
await globalHookManager.execute(TaskHookPoints.DELEGATE_BEFORE, hookCtx, { sessionId: parentSessionId });
|
|
731
|
-
|
|
732
|
-
// Use potentially modified prompt from hook
|
|
733
|
-
promptWithTaskInfo = delegateCtx.prompt;
|
|
734
|
-
|
|
735
|
-
if (background) {
|
|
736
|
-
// Background execution
|
|
737
|
-
return await handleBackgroundTask(
|
|
738
|
-
taskComponent,
|
|
739
|
-
backgroundTaskManager,
|
|
740
|
-
parentSessionId,
|
|
741
|
-
description,
|
|
742
|
-
promptWithTaskInfo,
|
|
743
|
-
delegateCtx.subagentType,
|
|
744
|
-
delegateCtx.timeout,
|
|
745
|
-
delegateCtx.cleanup,
|
|
746
|
-
delegateCtx.taskId
|
|
747
|
-
);
|
|
748
|
-
} else {
|
|
749
|
-
// Synchronous execution
|
|
750
|
-
return await handleSyncTask(
|
|
751
|
-
taskComponent,
|
|
752
|
-
parentSessionId,
|
|
753
|
-
description,
|
|
754
|
-
promptWithTaskInfo,
|
|
755
|
-
delegateCtx.subagentType,
|
|
756
|
-
delegateCtx.timeout,
|
|
757
|
-
delegateCtx.taskId
|
|
758
|
-
);
|
|
759
|
-
}
|
|
760
|
-
},
|
|
761
|
-
};
|
|
762
|
-
|
|
763
|
-
return tool;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
async function handleSyncTask(
|
|
767
|
-
taskComponent: TaskComponent,
|
|
768
|
-
parentSessionId: string,
|
|
769
|
-
description: string,
|
|
770
|
-
prompt: string,
|
|
771
|
-
subagentType: string,
|
|
772
|
-
timeout?: number,
|
|
773
|
-
taskId?: number
|
|
774
|
-
): Promise<ToolResult> {
|
|
775
|
-
const startTime = Date.now();
|
|
776
|
-
|
|
777
|
-
try {
|
|
778
|
-
// Get SessionComponent from environment
|
|
779
|
-
const sessionComponent = (taskComponent as any).env?.getComponent?.("session") as SessionComponent | undefined;
|
|
780
|
-
if (!sessionComponent) {
|
|
781
|
-
return {
|
|
782
|
-
success: false,
|
|
783
|
-
output: "",
|
|
784
|
-
error: "SessionComponent not found",
|
|
785
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
const parentSession = await sessionComponent.get(parentSessionId);
|
|
790
|
-
if (!parentSession) {
|
|
791
|
-
return {
|
|
792
|
-
success: false,
|
|
793
|
-
output: "",
|
|
794
|
-
error: `Parent session not found: ${parentSessionId}`,
|
|
795
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
796
|
-
};
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// Create sub-session
|
|
800
|
-
const metadata: Record<string, unknown> = {
|
|
801
|
-
subagent_type: subagentType,
|
|
802
|
-
created_by: "subagent",
|
|
803
|
-
task_description: description,
|
|
804
|
-
};
|
|
805
|
-
if (taskId) {
|
|
806
|
-
metadata.task_id = taskId;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
const subSession = await sessionComponent.create({
|
|
810
|
-
parentID: parentSessionId,
|
|
811
|
-
title: `${description} (@${subagentType} subagent)`,
|
|
812
|
-
metadata,
|
|
813
|
-
});
|
|
814
|
-
|
|
815
|
-
if (!subSession) {
|
|
816
|
-
return {
|
|
817
|
-
success: false,
|
|
818
|
-
output: "",
|
|
819
|
-
error: "Failed to create sub-session",
|
|
820
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
821
|
-
};
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// Build full prompt
|
|
825
|
-
const subAgent = getSubAgentSpec(subagentType);
|
|
826
|
-
let basePrompt = subAgent?.promptOverride || `You are a subagent. Complete this task: {task_description}`;
|
|
827
|
-
|
|
828
|
-
// Get denied tools from subagent config
|
|
829
|
-
const deniedTools = subAgent?.deniedTools || [];
|
|
830
|
-
|
|
831
|
-
// Only replace valid placeholders
|
|
832
|
-
let fullPrompt = basePrompt.replace(/{task_description}/g, description || "N/A");
|
|
833
|
-
|
|
834
|
-
fullPrompt += `
|
|
835
|
-
|
|
836
|
-
---
|
|
837
|
-
|
|
838
|
-
# Session Info
|
|
839
|
-
- task_id: ${taskId || "N/A"}
|
|
840
|
-
- session_id: ${subSession.id}
|
|
841
|
-
|
|
842
|
-
---
|
|
843
|
-
|
|
844
|
-
## 用户指令
|
|
845
|
-
${prompt}
|
|
846
|
-
|
|
847
|
-
---
|
|
848
|
-
|
|
849
|
-
## 执行规范
|
|
850
|
-
- 使用可用工具完成任务
|
|
851
|
-
- 返回清晰的任务执行结果摘要
|
|
852
|
-
- 适时调用 task_operation_create 记录进展`;
|
|
853
|
-
|
|
854
|
-
const agentComponent = (taskComponent as any).env?.getComponent?.("agent") as any;
|
|
855
|
-
|
|
856
|
-
if (!agentComponent) {
|
|
857
|
-
return {
|
|
858
|
-
success: false,
|
|
859
|
-
output: "",
|
|
860
|
-
error: "AgentComponent not found",
|
|
861
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
// 注册 subagent(使用公共函数)
|
|
866
|
-
ensureSubAgentRegistered(agentComponent, subagentType, basePrompt, subAgent, deniedTools);
|
|
867
|
-
|
|
868
|
-
// 使用 handle_query 执行,通过 agentType 指定 agent
|
|
869
|
-
const timeoutMs = timeout || DEFAULT_TIMEOUT;
|
|
870
|
-
let result: string;
|
|
871
|
-
|
|
872
|
-
try {
|
|
873
|
-
result = await Promise.race([
|
|
874
|
-
(taskComponent as any).env?.handle_query?.(fullPrompt, {
|
|
875
|
-
sessionId: subSession.id,
|
|
876
|
-
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
877
|
-
agentType: subagentType, // 传入 agentType,handle_query 会使用对应的 agent
|
|
878
|
-
}),
|
|
879
|
-
new Promise<string>((_, reject) =>
|
|
880
|
-
setTimeout(() => reject(new Error(`Task execution timeout after ${timeoutMs}ms`)), timeoutMs)
|
|
881
|
-
),
|
|
882
|
-
]);
|
|
883
|
-
} catch (error) {
|
|
884
|
-
result = error instanceof Error ? error.message : String(error);
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
// Add result message to session
|
|
888
|
-
await sessionComponent.addMessage(subSession.id, {
|
|
889
|
-
role: "assistant",
|
|
890
|
-
content: result,
|
|
891
|
-
});
|
|
892
|
-
|
|
893
|
-
return {
|
|
894
|
-
success: true,
|
|
895
|
-
output: result + "\n\n" + [
|
|
896
|
-
"<task_metadata>",
|
|
897
|
-
`session_id: ${subSession.id}`,
|
|
898
|
-
`subagent_type: ${subagentType}`,
|
|
899
|
-
"</task_metadata>",
|
|
900
|
-
].join("\n"),
|
|
901
|
-
metadata: {
|
|
902
|
-
execution_time_ms: Date.now() - startTime,
|
|
903
|
-
sessionId: subSession.id,
|
|
904
|
-
},
|
|
905
|
-
};
|
|
906
|
-
} catch (error) {
|
|
907
|
-
return {
|
|
908
|
-
success: false,
|
|
909
|
-
output: "",
|
|
910
|
-
error: error instanceof Error ? error.message : String(error),
|
|
911
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
async function handleBackgroundTask(
|
|
917
|
-
taskComponent: TaskComponent,
|
|
918
|
-
backgroundTaskManager: BackgroundTaskManager,
|
|
919
|
-
parentSessionId: string,
|
|
920
|
-
description: string,
|
|
921
|
-
prompt: string,
|
|
922
|
-
subagentType: string,
|
|
923
|
-
timeout?: number,
|
|
924
|
-
cleanup?: "delete" | "keep",
|
|
925
|
-
taskId?: number
|
|
926
|
-
): Promise<ToolResult> {
|
|
927
|
-
const startTime = Date.now();
|
|
928
|
-
|
|
929
|
-
try {
|
|
930
|
-
// Create or update task
|
|
931
|
-
let associatedTaskId = taskId;
|
|
932
|
-
|
|
933
|
-
if (!associatedTaskId) {
|
|
934
|
-
// Create new task
|
|
935
|
-
const newTask = await taskComponent.createTask({
|
|
936
|
-
title: description,
|
|
937
|
-
description: `Background task delegated to ${subagentType} subagent`,
|
|
938
|
-
priority: "medium",
|
|
939
|
-
goals_and_expected_deliverables: prompt,
|
|
940
|
-
sessionId: parentSessionId,
|
|
941
|
-
});
|
|
942
|
-
associatedTaskId = newTask.id;
|
|
943
|
-
|
|
944
|
-
// Create operation record
|
|
945
|
-
await taskComponent.createOperation({
|
|
946
|
-
taskId: associatedTaskId,
|
|
947
|
-
sessionId: parentSessionId,
|
|
948
|
-
actionType: "create",
|
|
949
|
-
actionTitle: `Delegated to ${subagentType} subagent`,
|
|
950
|
-
actionDescription: `Background task started: ${description}`,
|
|
951
|
-
});
|
|
952
|
-
} else {
|
|
953
|
-
// Update existing task
|
|
954
|
-
await taskComponent.updateTask(associatedTaskId, {
|
|
955
|
-
status: "active",
|
|
956
|
-
current_status: `Running ${subagentType} subagent`,
|
|
957
|
-
});
|
|
958
|
-
|
|
959
|
-
await taskComponent.createOperation({
|
|
960
|
-
taskId: associatedTaskId,
|
|
961
|
-
sessionId: parentSessionId,
|
|
962
|
-
actionType: "progress",
|
|
963
|
-
actionTitle: `Started ${subagentType} subagent`,
|
|
964
|
-
actionDescription: `Background task: ${description}`,
|
|
965
|
-
});
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
// Create background task
|
|
969
|
-
const { taskId: bgTaskId, subSessionId } = await backgroundTaskManager.createTask({
|
|
970
|
-
parentSessionId,
|
|
971
|
-
description,
|
|
972
|
-
prompt,
|
|
973
|
-
subagentType,
|
|
974
|
-
timeout,
|
|
975
|
-
cleanup,
|
|
976
|
-
taskId: associatedTaskId,
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
const output = [
|
|
980
|
-
`✅ Background task accepted`,
|
|
981
|
-
"",
|
|
982
|
-
`📋 Task ID: ${bgTaskId}`,
|
|
983
|
-
`📝 Description: ${description}`,
|
|
984
|
-
`🤖 Sub-agent: ${subagentType}`,
|
|
985
|
-
associatedTaskId ? `📌 Associated Task: #${associatedTaskId}` : "",
|
|
986
|
-
`⏱️ Timeout: ${(timeout || DEFAULT_TIMEOUT) / 1000}s`,
|
|
987
|
-
"",
|
|
988
|
-
`Use stop_task with task_id="${bgTaskId}" to cancel this task.`,
|
|
989
|
-
].filter(Boolean).join("\n");
|
|
990
|
-
|
|
991
|
-
return {
|
|
992
|
-
success: true,
|
|
993
|
-
output,
|
|
994
|
-
metadata: {
|
|
995
|
-
execution_time_ms: Date.now() - startTime,
|
|
996
|
-
sessionId: subSessionId,
|
|
997
|
-
background: true,
|
|
998
|
-
status: "accepted",
|
|
999
|
-
task_id: associatedTaskId,
|
|
1000
|
-
bgTaskId,
|
|
1001
|
-
},
|
|
1002
|
-
};
|
|
1003
|
-
} catch (error) {
|
|
1004
|
-
return {
|
|
1005
|
-
success: false,
|
|
1006
|
-
output: "",
|
|
1007
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1008
|
-
metadata: { execution_time_ms: Date.now() - startTime },
|
|
1009
|
-
};
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// Export for stop_task tool
|
|
1014
|
-
export { handleBackgroundTask, handleSyncTask };
|