@ai-setting/roy-agent-core 1.3.9 → 1.3.11
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,598 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview AgentNode - Delegate work to an AI agent
|
|
3
|
-
*
|
|
4
|
-
* AgentNode delegates work to an AI agent with task description and context.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Node, NodeDefinition, NodeExecutionContext, NodeExecutionResult } from '../types';
|
|
8
|
-
import type { SessionComponent } from '../../session/session-component';
|
|
9
|
-
import { AskUserError } from '../types/workflow-hil';
|
|
10
|
-
import { TracedAs } from '../../log-trace/decorator';
|
|
11
|
-
|
|
12
|
-
// ============================================================================
|
|
13
|
-
// Agent Types
|
|
14
|
-
// ============================================================================
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Agent 注册配置
|
|
18
|
-
*/
|
|
19
|
-
export interface AgentRegistrationConfig {
|
|
20
|
-
/** Agent 类型 */
|
|
21
|
-
type?: string;
|
|
22
|
-
/** 系统提示词 */
|
|
23
|
-
systemPrompt?: string;
|
|
24
|
-
/** 模型名称 */
|
|
25
|
-
model?: string;
|
|
26
|
-
/** 最大迭代次数 */
|
|
27
|
-
maxIterations?: number;
|
|
28
|
-
/** 允许的工具列表 */
|
|
29
|
-
allowedTools?: string[];
|
|
30
|
-
/** 禁止的工具列表 */
|
|
31
|
-
deniedTools?: string[];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* AgentRunner 接口
|
|
36
|
-
*
|
|
37
|
-
* 用于运行 AI Agent 的接口
|
|
38
|
-
*/
|
|
39
|
-
export interface AgentRunner {
|
|
40
|
-
/**
|
|
41
|
-
* 运行 Agent
|
|
42
|
-
* @param config Agent 配置
|
|
43
|
-
* @param resumeOptions 可选的恢复选项(用于恢复暂停的 agent)
|
|
44
|
-
* @returns Agent 执行结果
|
|
45
|
-
*/
|
|
46
|
-
run(config: AgentConfig, resumeOptions?: { userResponse?: string; agentSessionId?: string }): Promise<AgentResult>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 恢复暂停的 Agent
|
|
50
|
-
*
|
|
51
|
-
* @param agentSessionId Agent session ID
|
|
52
|
-
* @param userResponse 用户的响应
|
|
53
|
-
* @param config 原始的 agent 配置
|
|
54
|
-
* @returns Agent 执行结果
|
|
55
|
-
*/
|
|
56
|
-
resumeAgent?(agentSessionId: string, userResponse: string, config: AgentConfig): Promise<AgentResult>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 获取当前 agent session ID
|
|
60
|
-
*/
|
|
61
|
-
getCurrentAgentSessionId?(): string | undefined;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* 设置 SessionComponent
|
|
65
|
-
*/
|
|
66
|
-
setSessionComponent?(sessionComponent: SessionComponent): void;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 获取待恢复的 session 信息
|
|
70
|
-
*/
|
|
71
|
-
getPendingSession?(agentSessionId: string): { agentSessionId: string; nodeId: string; runId: string; createdAt: number } | undefined;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 注册 Agent(如果不存在)
|
|
75
|
-
*/
|
|
76
|
-
registerAgent?(name: string, config: AgentRegistrationConfig): void;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 检查 Agent 是否已注册
|
|
80
|
-
*/
|
|
81
|
-
hasAgent?(name: string): boolean;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Agent 配置
|
|
86
|
-
*/
|
|
87
|
-
export interface AgentConfig {
|
|
88
|
-
/** Agent 类型 */
|
|
89
|
-
type: string;
|
|
90
|
-
/** Prompt(任务描述) */
|
|
91
|
-
prompt: string;
|
|
92
|
-
/** 可选配置 */
|
|
93
|
-
options?: {
|
|
94
|
-
/** 超时时间(毫秒) */
|
|
95
|
-
timeout?: number;
|
|
96
|
-
/** 模型名称 */
|
|
97
|
-
model?: string;
|
|
98
|
-
/** 允许的工具列表(用于限制 agent 可用的工具) */
|
|
99
|
-
allowedTools?: string[];
|
|
100
|
-
/** 拒绝的工具列表 */
|
|
101
|
-
deniedTools?: string[];
|
|
102
|
-
};
|
|
103
|
-
/** Workflow 历史消息(来自前置 agent 节点) */
|
|
104
|
-
workflowHistory?: Array<{
|
|
105
|
-
role: 'user' | 'assistant' | 'tool';
|
|
106
|
-
content: string;
|
|
107
|
-
toolCallId?: string;
|
|
108
|
-
toolName?: string;
|
|
109
|
-
nodeId?: string;
|
|
110
|
-
}>;
|
|
111
|
-
/** 节点 ID(用于 history 标记) */
|
|
112
|
-
nodeId?: string;
|
|
113
|
-
/** Agent sub-session ID(用于 HiL resume) */
|
|
114
|
-
agentSessionId?: string;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Agent 执行结果
|
|
119
|
-
*/
|
|
120
|
-
export interface AgentResult {
|
|
121
|
-
/** Agent 输出 */
|
|
122
|
-
output: unknown;
|
|
123
|
-
/** 执行元数据 */
|
|
124
|
-
metadata?: {
|
|
125
|
-
/** 消耗的 token 数量 */
|
|
126
|
-
tokens?: number;
|
|
127
|
-
/** 执行耗时(毫秒) */
|
|
128
|
-
duration?: number;
|
|
129
|
-
/** 其他元数据 */
|
|
130
|
-
[key: string]: unknown;
|
|
131
|
-
};
|
|
132
|
-
/** 生成的消息列表(用于 workflow history 累积) */
|
|
133
|
-
messages?: Array<{
|
|
134
|
-
role: 'user' | 'assistant' | 'tool';
|
|
135
|
-
content: string;
|
|
136
|
-
toolCallId?: string;
|
|
137
|
-
toolName?: string;
|
|
138
|
-
nodeId?: string;
|
|
139
|
-
}>;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// ============================================================================
|
|
143
|
-
// AgentNode Implementation
|
|
144
|
-
// ============================================================================
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* AgentNode 类
|
|
148
|
-
*
|
|
149
|
-
* 委托 AI Agent 执行任务的节点类型
|
|
150
|
-
*/
|
|
151
|
-
export class AgentNode implements Node {
|
|
152
|
-
/** 节点类型 */
|
|
153
|
-
readonly type = 'agent';
|
|
154
|
-
/** 节点 ID */
|
|
155
|
-
readonly id: string;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* 创建 AgentNode
|
|
159
|
-
* @param definition 节点定义
|
|
160
|
-
* @param agentRunner Agent 运行器
|
|
161
|
-
*/
|
|
162
|
-
constructor(
|
|
163
|
-
private definition: NodeDefinition,
|
|
164
|
-
private agentRunner: AgentRunner
|
|
165
|
-
) {
|
|
166
|
-
this.id = definition.id;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* 执行 AgentNode
|
|
171
|
-
*
|
|
172
|
-
* 流程:
|
|
173
|
-
* 1. 从 definition.config 获取 agent 配置
|
|
174
|
-
* 2. 解析 prompt 模板(可能引用前置节点输出)
|
|
175
|
-
* 3. 通过 agentRunner 运行 agent
|
|
176
|
-
* 4. 返回 agent 结果
|
|
177
|
-
*
|
|
178
|
-
* @param context 执行上下文
|
|
179
|
-
* @returns 执行结果
|
|
180
|
-
*/
|
|
181
|
-
@TracedAs("agent.node.execute", { recordParams: true, recordResult: true, log: true })
|
|
182
|
-
async execute(context: NodeExecutionContext): Promise<NodeExecutionResult> {
|
|
183
|
-
const startTime = Date.now();
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
// 1. 从配置中获取 agent 参数
|
|
187
|
-
const config = this.definition.config as Record<string, unknown> || {};
|
|
188
|
-
const agentType = (config.agent_type as string) || 'general';
|
|
189
|
-
const promptTemplate = (config.prompt as string) || '';
|
|
190
|
-
const options = (config.options as AgentConfig['options']) || {};
|
|
191
|
-
|
|
192
|
-
// 2. 解析 prompt 模板
|
|
193
|
-
const resolvedPrompt = this.resolveTemplate(promptTemplate, context);
|
|
194
|
-
|
|
195
|
-
// 3. 自动注册 agent(如果不存在)
|
|
196
|
-
// 这样 workflow 定义中引用的 agent 类型会被自动注册,无需手动预注册
|
|
197
|
-
if (this.agentRunner.registerAgent && this.agentRunner.hasAgent) {
|
|
198
|
-
if (!this.agentRunner.hasAgent(agentType)) {
|
|
199
|
-
this.agentRunner.registerAgent(agentType, {
|
|
200
|
-
type: agentType,
|
|
201
|
-
systemPrompt: (config.system_prompt as string) || `You are a ${agentType} agent.`,
|
|
202
|
-
model: options.model,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// 4. 检查是否需要恢复执行(从 pause 恢复时传递了 userResponse)
|
|
208
|
-
// 从 context 中获取恢复选项(由 engine.resumeNode 设置)
|
|
209
|
-
const userResponse = (context as any).userResponse;
|
|
210
|
-
let agentSessionId = (context as any).agentSessionId;
|
|
211
|
-
|
|
212
|
-
// 5. 如果不是恢复模式,创建 agent sub-session
|
|
213
|
-
// Sub-session 用于存储 agent 的对话历史,支持 resume
|
|
214
|
-
if (!userResponse && context.sessionComponent && !agentSessionId) {
|
|
215
|
-
agentSessionId = await this.createAgentSubSession(context);
|
|
216
|
-
|
|
217
|
-
// 将 agentSessionId 设置到 context 中,供后续使用(如 AskUserError)
|
|
218
|
-
// 注意:NodeExecutionContext 是引用类型,直接修改会生效
|
|
219
|
-
(context as any).agentSessionId = agentSessionId;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 6. 构建 AgentConfig
|
|
223
|
-
// 注意:添加 allowedTools: ['ask_user'] 确保 ask_user 工具在 workflow agent 上下文中可用
|
|
224
|
-
// 这样 ask_user 只在 workflow agent 中可用,不影响 default agent 和 sub agent
|
|
225
|
-
const agentConfig: AgentConfig = {
|
|
226
|
-
type: agentType,
|
|
227
|
-
prompt: resolvedPrompt,
|
|
228
|
-
options: {
|
|
229
|
-
timeout: options.timeout,
|
|
230
|
-
model: options.model,
|
|
231
|
-
// 添加 ask_user 到 allowedTools,确保 workflow agent 可以调用此工具
|
|
232
|
-
allowedTools: ['ask_user'],
|
|
233
|
-
},
|
|
234
|
-
// 传递 workflow history(来自前置 agent 节点)
|
|
235
|
-
workflowHistory: context.workflowHistory,
|
|
236
|
-
// 传递节点信息(用于 history 标记)
|
|
237
|
-
nodeId: this.definition.id,
|
|
238
|
-
// 传递 agent sub-session ID
|
|
239
|
-
agentSessionId,
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
// 如果有 userResponse,说明是从 pause 恢复的,应该传递给 agentRunner
|
|
243
|
-
const resumeOptions = userResponse
|
|
244
|
-
? { userResponse, agentSessionId }
|
|
245
|
-
: undefined;
|
|
246
|
-
|
|
247
|
-
// 7. 运行 agent(传递 resumeOptions 如果是从 pause 恢复的)
|
|
248
|
-
const result = await this.agentRunner.run(agentConfig, resumeOptions);
|
|
249
|
-
|
|
250
|
-
// 8. 计算执行耗时
|
|
251
|
-
const duration = Date.now() - startTime;
|
|
252
|
-
|
|
253
|
-
// 9. 返回成功结果
|
|
254
|
-
return {
|
|
255
|
-
output: {
|
|
256
|
-
result: result.output,
|
|
257
|
-
metadata: result.metadata,
|
|
258
|
-
// 返回 workflow history 供 WorkflowEngine 累积
|
|
259
|
-
workflowHistory: result.messages,
|
|
260
|
-
},
|
|
261
|
-
error: undefined,
|
|
262
|
-
duration,
|
|
263
|
-
};
|
|
264
|
-
} catch (error) {
|
|
265
|
-
// 检查是否是 AskUserError - 这是用于工作流暂停的特殊错误,需要向上传播
|
|
266
|
-
// 以便 Executor 能够正确处理暂停逻辑
|
|
267
|
-
if (error instanceof AskUserError) {
|
|
268
|
-
// 确保 AskUserError 携带 agentSessionId(如果有的话)
|
|
269
|
-
const contextAgentSessionId = (context as any).agentSessionId;
|
|
270
|
-
if (contextAgentSessionId && !error.agentSessionId) {
|
|
271
|
-
// 创建一个新的 AskUserError 携带 agentSessionId
|
|
272
|
-
throw new AskUserError(
|
|
273
|
-
error.runId,
|
|
274
|
-
error.sessionId,
|
|
275
|
-
error.nodeId,
|
|
276
|
-
error.nodeType,
|
|
277
|
-
error.query,
|
|
278
|
-
contextAgentSessionId,
|
|
279
|
-
error.timestamp
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
throw error; // 重新抛出,让 Executor 处理
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// 其他错误处理
|
|
286
|
-
const duration = Date.now() - startTime;
|
|
287
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
output: undefined,
|
|
291
|
-
error: errorMessage,
|
|
292
|
-
duration,
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* 创建 agent sub-session
|
|
299
|
-
*
|
|
300
|
-
* Sub-session 用于存储 agent 的对话历史,支持 human-in-loop resume
|
|
301
|
-
*/
|
|
302
|
-
@TracedAs("agent.node.createAgentSubSession", { recordParams: true, recordResult: true, log: true })
|
|
303
|
-
private async createAgentSubSession(context: NodeExecutionContext): Promise<string> {
|
|
304
|
-
const sessionComponent = context.sessionComponent;
|
|
305
|
-
if (!sessionComponent) {
|
|
306
|
-
return '';
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const agentSessionId = `agent_${this.definition.id}_${Date.now()}`;
|
|
310
|
-
|
|
311
|
-
// 1. 创建 agent sub-session
|
|
312
|
-
await sessionComponent.create({
|
|
313
|
-
id: agentSessionId,
|
|
314
|
-
title: `Agent: ${this.definition.id}`,
|
|
315
|
-
metadata: {
|
|
316
|
-
type: 'agent',
|
|
317
|
-
parentSessionId: context.sessionId,
|
|
318
|
-
nodeId: this.definition.id,
|
|
319
|
-
workflowName: context.workflowName,
|
|
320
|
-
},
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
// 2. 更新 workflow session 的 metadata,添加 agentSessions 引用
|
|
324
|
-
const workflowSession = await sessionComponent.get(context.sessionId);
|
|
325
|
-
if (workflowSession) {
|
|
326
|
-
const metadata = workflowSession.metadata as any || {};
|
|
327
|
-
const agentSessions = metadata.agentSessions || [];
|
|
328
|
-
|
|
329
|
-
// 检查是否已经存在
|
|
330
|
-
const existingIndex = agentSessions.findIndex(
|
|
331
|
-
(s: any) => s.nodeId === this.definition.id
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
if (existingIndex >= 0) {
|
|
335
|
-
agentSessions[existingIndex] = {
|
|
336
|
-
nodeId: this.definition.id,
|
|
337
|
-
sessionId: agentSessionId,
|
|
338
|
-
status: 'active',
|
|
339
|
-
createdAt: Date.now(),
|
|
340
|
-
};
|
|
341
|
-
} else {
|
|
342
|
-
agentSessions.push({
|
|
343
|
-
nodeId: this.definition.id,
|
|
344
|
-
sessionId: agentSessionId,
|
|
345
|
-
status: 'active',
|
|
346
|
-
createdAt: Date.now(),
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
await sessionComponent.update(context.sessionId, {
|
|
351
|
-
metadata: {
|
|
352
|
-
...metadata,
|
|
353
|
-
agentSessions,
|
|
354
|
-
},
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return agentSessionId;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* 解析模板字符串
|
|
363
|
-
*
|
|
364
|
-
* 支持以下模板变量:
|
|
365
|
-
* - {{input.key}} - 从 context.input 获取值
|
|
366
|
-
* - {{nodes.nodeId}} - 从前置节点输出获取值
|
|
367
|
-
* - {{nodes.nodeId.output}} - 从前置节点输出获取值
|
|
368
|
-
* - {{nodes.nodeId.output.path}} - 从前置节点输出的嵌套路径获取值
|
|
369
|
-
*
|
|
370
|
-
* @param template 模板字符串
|
|
371
|
-
* @param context 执行上下文
|
|
372
|
-
* @returns 解析后的字符串
|
|
373
|
-
*/
|
|
374
|
-
private resolveTemplate(template: string, context: NodeExecutionContext): string {
|
|
375
|
-
if (!template) {
|
|
376
|
-
return '';
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
let resolved = template;
|
|
380
|
-
|
|
381
|
-
// 解析 input 变量: {{input.key}} 或 {{input.key.nested}}
|
|
382
|
-
resolved = resolved.replace(/\{\{input\.([^}]+)\}\}/g, (match, path) => {
|
|
383
|
-
const value = this.getNestedValue(context.input as any, path);
|
|
384
|
-
return this.stringifyValue(value, match);
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// 解析 node 输出变量: {{nodes.nodeId}} 或 {{nodes.nodeId.output}} 或 {{nodes.nodeId.output.path}}
|
|
388
|
-
resolved = resolved.replace(/\{\{nodes\.([^}]+)\}\}/g, (match, path) => {
|
|
389
|
-
// 路径格式: nodeId 或 nodeId.output 或 nodeId.output.path
|
|
390
|
-
const segments = path.split('.');
|
|
391
|
-
const nodeId = segments[0];
|
|
392
|
-
|
|
393
|
-
// 从 previousOutputs 获取原始输出(尝试规范化匹配)
|
|
394
|
-
let nodeOutput = context.previousOutputs.get(nodeId);
|
|
395
|
-
|
|
396
|
-
if (nodeOutput === undefined) {
|
|
397
|
-
// 尝试规范化版本(hyphen <-> underscore)
|
|
398
|
-
const normalizedUnderscore = nodeId.replace(/-/g, '_');
|
|
399
|
-
const normalizedHyphen = nodeId.replace(/_/g, '-');
|
|
400
|
-
|
|
401
|
-
if (normalizedUnderscore !== nodeId) {
|
|
402
|
-
nodeOutput = context.previousOutputs.get(normalizedUnderscore);
|
|
403
|
-
}
|
|
404
|
-
if (nodeOutput === undefined && normalizedHyphen !== nodeId) {
|
|
405
|
-
nodeOutput = context.previousOutputs.get(normalizedHyphen);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
if (nodeOutput === undefined) {
|
|
410
|
-
return match;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 首先从包装格式中提取实际值
|
|
414
|
-
// 处理 DecoratorNode 格式: { success, output, ... } 和 AgentNode 格式: { result, metadata }
|
|
415
|
-
nodeOutput = this.extractFromWrapper(nodeOutput);
|
|
416
|
-
|
|
417
|
-
// 然后从提取后的值中获取嵌套路径
|
|
418
|
-
if (segments.length === 1) {
|
|
419
|
-
// 只有 nodeId,直接返回提取后的值
|
|
420
|
-
// 如果是对象,序列化为 JSON;如果是原始值,转为字符串
|
|
421
|
-
return this.stringifyValue(nodeOutput, match);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// 从嵌套路径获取(从 segments[1] 开始)
|
|
425
|
-
// 如果 segments[1] 是包装属性("output"、"result"、"metadata"),跳过它因为 extractFromWrapper 已经提取了
|
|
426
|
-
let value: any = nodeOutput;
|
|
427
|
-
let startIndex = 1;
|
|
428
|
-
if (segments.length > 1 &&
|
|
429
|
-
(segments[1] === 'output' || segments[1] === 'result' || segments[1] === 'metadata')) {
|
|
430
|
-
startIndex = 2;
|
|
431
|
-
}
|
|
432
|
-
for (let i = startIndex; i < segments.length; i++) {
|
|
433
|
-
if (value === null || value === undefined) {
|
|
434
|
-
return match;
|
|
435
|
-
}
|
|
436
|
-
value = value[segments[i]];
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return this.stringifyValue(value, match);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
// 解析裸 node 输出变量: {{nodeId}} 或 {{nodeId.output}} (不带 nodes. 前缀)
|
|
443
|
-
// 这需要放在 {{input.}} 和 {{nodes.}} 之后,以避免与它们冲突
|
|
444
|
-
resolved = resolved.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
|
|
445
|
-
// 跳过已经是 input 或 nodes 开头的(已由前面的规则处理)
|
|
446
|
-
if (path.startsWith('input.') || path.startsWith('nodes.')) {
|
|
447
|
-
return match;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
const segments = path.split('.');
|
|
451
|
-
const nodeId = segments[0];
|
|
452
|
-
|
|
453
|
-
// 从 previousOutputs 获取原始输出(尝试规范化匹配)
|
|
454
|
-
let nodeOutput = context.previousOutputs.get(nodeId);
|
|
455
|
-
|
|
456
|
-
if (nodeOutput === undefined) {
|
|
457
|
-
// 尝试规范化版本(hyphen <-> underscore)
|
|
458
|
-
const normalizedUnderscore = nodeId.replace(/-/g, '_');
|
|
459
|
-
const normalizedHyphen = nodeId.replace(/_/g, '-');
|
|
460
|
-
|
|
461
|
-
if (normalizedUnderscore !== nodeId) {
|
|
462
|
-
nodeOutput = context.previousOutputs.get(normalizedUnderscore);
|
|
463
|
-
}
|
|
464
|
-
if (nodeOutput === undefined && normalizedHyphen !== nodeId) {
|
|
465
|
-
nodeOutput = context.previousOutputs.get(normalizedHyphen);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
if (nodeOutput === undefined) {
|
|
470
|
-
return match;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// 首先从包装格式中提取实际值
|
|
474
|
-
nodeOutput = this.extractFromWrapper(nodeOutput);
|
|
475
|
-
|
|
476
|
-
// 然后从提取后的值中获取嵌套路径
|
|
477
|
-
if (segments.length === 1) {
|
|
478
|
-
// 只有 nodeId,直接返回提取后的值
|
|
479
|
-
// 如果是对象,序列化为 JSON;如果是原始值,转为字符串
|
|
480
|
-
return this.stringifyValue(nodeOutput, match);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// 从嵌套路径获取(从 segments[1] 开始)
|
|
484
|
-
// 如果 segments[1] 是包装属性("output"、"result"、"metadata"),跳过它因为 extractFromWrapper 已经提取了
|
|
485
|
-
let value: any = nodeOutput;
|
|
486
|
-
let startIndex = 1;
|
|
487
|
-
if (segments.length > 1 &&
|
|
488
|
-
(segments[1] === 'output' || segments[1] === 'result' || segments[1] === 'metadata')) {
|
|
489
|
-
startIndex = 2;
|
|
490
|
-
}
|
|
491
|
-
for (let i = startIndex; i < segments.length; i++) {
|
|
492
|
-
if (value === null || value === undefined) {
|
|
493
|
-
return match;
|
|
494
|
-
}
|
|
495
|
-
value = value[segments[i]];
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return this.stringifyValue(value, match);
|
|
499
|
-
});
|
|
500
|
-
|
|
501
|
-
return resolved;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Convert a value to string for template replacement.
|
|
506
|
-
* - If value is undefined, return the original template
|
|
507
|
-
* - If value is a string, return it directly
|
|
508
|
-
* - If value is null, return 'null'
|
|
509
|
-
* - If value is an object or array, serialize to JSON
|
|
510
|
-
*
|
|
511
|
-
* @param value - The value to stringify
|
|
512
|
-
* @param originalTemplate - The original template string (returned if value is undefined)
|
|
513
|
-
* @returns String representation of the value
|
|
514
|
-
*/
|
|
515
|
-
private stringifyValue(value: unknown, originalTemplate: string): string {
|
|
516
|
-
if (value === undefined) {
|
|
517
|
-
return originalTemplate;
|
|
518
|
-
}
|
|
519
|
-
if (value === null) {
|
|
520
|
-
return 'null';
|
|
521
|
-
}
|
|
522
|
-
if (typeof value === 'string') {
|
|
523
|
-
return value;
|
|
524
|
-
}
|
|
525
|
-
// For objects and arrays, serialize to JSON
|
|
526
|
-
return JSON.stringify(value);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* 从包装格式中提取实际输出值
|
|
531
|
-
*
|
|
532
|
-
* 处理以下格式:
|
|
533
|
-
* - AgentNode: { result, metadata } -> 返回 result
|
|
534
|
-
* - DecoratorNode: { success, output, ... } -> 返回 output
|
|
535
|
-
* - 其他格式直接返回
|
|
536
|
-
*
|
|
537
|
-
* @param value 原始值
|
|
538
|
-
* @returns 提取后的值
|
|
539
|
-
*/
|
|
540
|
-
private extractFromWrapper(value: unknown): unknown {
|
|
541
|
-
if (value === null || value === undefined) {
|
|
542
|
-
return value;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
if (typeof value !== 'object') {
|
|
546
|
-
return value;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// 检查 AgentNode 包装格式: { result, metadata }
|
|
550
|
-
// 这是 AgentNode 输出的特征签名
|
|
551
|
-
if ('result' in value && 'metadata' in value) {
|
|
552
|
-
return (value as { result: unknown }).result;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
// 检查 DecoratorNode 包装格式: { success, output, ... }
|
|
556
|
-
// 有 'output' 但没有 'result'(AgentNode 的特征)
|
|
557
|
-
if ('output' in value) {
|
|
558
|
-
return (value as { output: unknown }).output;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
return value;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* 获取嵌套对象的值
|
|
566
|
-
*
|
|
567
|
-
* @param obj 对象
|
|
568
|
-
* @param path 属性路径
|
|
569
|
-
* @returns 值或 undefined
|
|
570
|
-
*/
|
|
571
|
-
private getNestedValue(obj: Record<string, unknown> | undefined, path: string): unknown {
|
|
572
|
-
if (!obj) {
|
|
573
|
-
return undefined;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// Special case: If obj has an 'input' key, we might be accessing a key inside it
|
|
577
|
-
// This happens when createExecutionContext wraps globalInput as {input: globalInput}
|
|
578
|
-
if ('input' in obj && path in (obj['input'] as Record<string, unknown>)) {
|
|
579
|
-
// Path exists inside 'input', so look there
|
|
580
|
-
return (obj['input'] as Record<string, unknown>)[path];
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Normal case: path.split('.').reduce(...) with obj as initial value
|
|
584
|
-
// This allows {{input.city}} to work when path = "city" and obj = {input: {city: "..."}}
|
|
585
|
-
return path.split('.').reduce((current: unknown, key: string) => {
|
|
586
|
-
if (current && typeof current === 'object') {
|
|
587
|
-
return (current as Record<string, unknown>)[key];
|
|
588
|
-
}
|
|
589
|
-
return undefined;
|
|
590
|
-
}, obj as unknown);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// ============================================================================
|
|
595
|
-
// Exports
|
|
596
|
-
// ============================================================================
|
|
597
|
-
|
|
598
|
-
export { AgentNode as default };
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview AskUserNode - Node for requesting user input
|
|
3
|
-
*
|
|
4
|
-
* This node is used for simple pause/resume scenarios where a workflow
|
|
5
|
-
* needs user input without going through an Agent.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Node, NodeExecutionResult } from '../types';
|
|
9
|
-
import type { NodeDefinition } from '../types';
|
|
10
|
-
import { AskUserError, createNodeInterruptEvent } from '../types/workflow-hil';
|
|
11
|
-
import type { NodeInterruptEvent } from '../types/workflow-hil';
|
|
12
|
-
|
|
13
|
-
// ==================== Types ====================
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* AskUserNode Configuration
|
|
17
|
-
*/
|
|
18
|
-
export interface AskUserNodeConfig {
|
|
19
|
-
/** Question to ask the user */
|
|
20
|
-
query?: string;
|
|
21
|
-
/** Optional choices for the user */
|
|
22
|
-
options?: string[];
|
|
23
|
-
/** If true, user must explicitly confirm */
|
|
24
|
-
required_confirm?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ==================== AskUserNode Class ====================
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* AskUserNode - Standalone node for user input requests
|
|
31
|
-
*
|
|
32
|
-
* This node pauses the workflow and waits for user response.
|
|
33
|
-
* Used for simple human-in-loop scenarios without an Agent.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```yaml
|
|
37
|
-
* nodes:
|
|
38
|
-
* - id: confirm_step
|
|
39
|
-
* type: ask_user
|
|
40
|
-
* config:
|
|
41
|
-
* query: "Do you want to proceed?"
|
|
42
|
-
* options:
|
|
43
|
-
* - "Yes"
|
|
44
|
-
* - "No"
|
|
45
|
-
* - "Cancel"
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
export class AskUserNode implements Node {
|
|
49
|
-
readonly type = 'ask_user';
|
|
50
|
-
readonly id: string;
|
|
51
|
-
|
|
52
|
-
private config: AskUserNodeConfig;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Create a new AskUserNode
|
|
56
|
-
*/
|
|
57
|
-
constructor(definition: NodeDefinition) {
|
|
58
|
-
this.id = definition.id;
|
|
59
|
-
this.config = (definition.config as AskUserNodeConfig) || {};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Execute the AskUserNode
|
|
64
|
-
*
|
|
65
|
-
* Publishes a node.interrupt event and throws AskUserError to pause workflow.
|
|
66
|
-
*
|
|
67
|
-
* @param context - Node execution context
|
|
68
|
-
* @throws AskUserError - Always throws to pause workflow
|
|
69
|
-
*/
|
|
70
|
-
async execute(context: {
|
|
71
|
-
runId: string;
|
|
72
|
-
sessionId: string;
|
|
73
|
-
eventBus: {
|
|
74
|
-
publish(event: NodeInterruptEvent): Promise<void>;
|
|
75
|
-
};
|
|
76
|
-
nodeOutputs: Map<string, unknown>;
|
|
77
|
-
}): Promise<NodeExecutionResult> {
|
|
78
|
-
const query = this.config.query || '确认继续吗?';
|
|
79
|
-
const options = this.config.options;
|
|
80
|
-
|
|
81
|
-
// Build query with options if provided
|
|
82
|
-
const fullQuery = options
|
|
83
|
-
? `${query} (选项: ${options.join(', ')})`
|
|
84
|
-
: query;
|
|
85
|
-
|
|
86
|
-
// Publish node.interrupt event
|
|
87
|
-
await context.eventBus.publish(
|
|
88
|
-
createNodeInterruptEvent(
|
|
89
|
-
context.runId,
|
|
90
|
-
this.id,
|
|
91
|
-
this.type,
|
|
92
|
-
fullQuery
|
|
93
|
-
)
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
// Throw AskUserError to pause workflow
|
|
97
|
-
throw new AskUserError(
|
|
98
|
-
context.runId,
|
|
99
|
-
context.sessionId,
|
|
100
|
-
this.id,
|
|
101
|
-
this.type,
|
|
102
|
-
query
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Validate node configuration
|
|
108
|
-
*/
|
|
109
|
-
validateConfig(_config: Record<string, unknown>): boolean {
|
|
110
|
-
// query is optional, has default value
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
}
|