@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
package/src/env/environment.ts
DELETED
|
@@ -1,708 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview BaseEnvironment Implementation
|
|
3
|
-
*
|
|
4
|
-
* Environment 的基础实现类(非抽象),提供:
|
|
5
|
-
* - 组件注册与管理
|
|
6
|
-
* - 核心调度方法(handle_query, handle_action)
|
|
7
|
-
* - EnvEvent 事件机制
|
|
8
|
-
*
|
|
9
|
-
* 设计原则:
|
|
10
|
-
* 1. Environment 只做两件事:
|
|
11
|
-
* - 组件管理:持有、注册、获取组件
|
|
12
|
-
* - 核心调度:handle_query / handle_action / EnvEvent
|
|
13
|
-
* 2. 其他能力归属到对应 Component
|
|
14
|
-
*
|
|
15
|
-
* 子类可覆盖:
|
|
16
|
-
* - registerDefaultComponents(): 注册默认组件
|
|
17
|
-
* - handle_query(): 查询处理逻辑
|
|
18
|
-
* - handle_action(): 动作处理逻辑
|
|
19
|
-
* - onInit/onStart/onStop: 生命周期钩子
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { BaseComponent, type Component } from "./component";
|
|
23
|
-
import type {
|
|
24
|
-
Environment,
|
|
25
|
-
ServiceConfig,
|
|
26
|
-
ComponentConfigEntry,
|
|
27
|
-
GeneratedComponentOptions
|
|
28
|
-
} from "./interface";
|
|
29
|
-
import type {
|
|
30
|
-
EnvironmentConfig,
|
|
31
|
-
BaseEnvironmentConfig,
|
|
32
|
-
EnvEvent,
|
|
33
|
-
EnvEventInput,
|
|
34
|
-
EnvEventHandler,
|
|
35
|
-
Action,
|
|
36
|
-
ToolResult,
|
|
37
|
-
Context,
|
|
38
|
-
} from "./types";
|
|
39
|
-
import { createLogger } from "./log-trace/logger";
|
|
40
|
-
import { generateId } from "../utils/id";
|
|
41
|
-
import { ContextError, ErrorCodes } from "./errors";
|
|
42
|
-
import * as fsSync from "fs";
|
|
43
|
-
import * as path from "path";
|
|
44
|
-
import { TracedAs } from "./log-trace/decorator";
|
|
45
|
-
|
|
46
|
-
const logger = createLogger("environment");
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* BaseEnvironment 实现类(非抽象)
|
|
50
|
-
*
|
|
51
|
-
* 实现 Environment 接口,提供简洁的环境基础功能。
|
|
52
|
-
* 子类可继承此类并覆盖特定方法来自定义行为。
|
|
53
|
-
*/
|
|
54
|
-
export class BaseEnvironment extends BaseComponent implements Environment {
|
|
55
|
-
// ============ 标识 ============
|
|
56
|
-
|
|
57
|
-
readonly name: string;
|
|
58
|
-
readonly version: string;
|
|
59
|
-
|
|
60
|
-
// ============ 组件管理 ============
|
|
61
|
-
|
|
62
|
-
protected components = new Map<string, Component>();
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 构造函数
|
|
66
|
-
*/
|
|
67
|
-
constructor(config?: BaseEnvironmentConfig) {
|
|
68
|
-
super();
|
|
69
|
-
this.name = config?.name ?? "base-environment";
|
|
70
|
-
this.version = config?.version ?? "1.0.0";
|
|
71
|
-
|
|
72
|
-
// 注册默认组件
|
|
73
|
-
this.registerDefaultComponents();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* 注册默认组件(子类可覆盖)
|
|
78
|
-
*/
|
|
79
|
-
protected registerDefaultComponents(): void {
|
|
80
|
-
// 子类可覆盖以注册默认组件
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* 获取环境配置
|
|
85
|
-
*/
|
|
86
|
-
getConfig(): EnvironmentConfig & { env: Environment } {
|
|
87
|
-
return {
|
|
88
|
-
name: this.name,
|
|
89
|
-
version: this.version,
|
|
90
|
-
enabled: true,
|
|
91
|
-
env: this,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ============ 组件管理 ============
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 注册组件
|
|
99
|
-
*/
|
|
100
|
-
registerComponent(component: Component): void {
|
|
101
|
-
this.components.set(component.name, component);
|
|
102
|
-
logger.debug(`Component registered: ${component.name}`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* 注销组件
|
|
107
|
-
*/
|
|
108
|
-
unregisterComponent(name: string): void {
|
|
109
|
-
const component = this.components.get(name);
|
|
110
|
-
if (component) {
|
|
111
|
-
this.components.delete(name);
|
|
112
|
-
logger.debug(`Component unregistered: ${name}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 获取组件
|
|
118
|
-
*/
|
|
119
|
-
getComponent<T extends Component>(name: string): T | undefined {
|
|
120
|
-
return this.components.get(name) as T | undefined;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 列出所有组件
|
|
125
|
-
*/
|
|
126
|
-
listComponents(): Component[] {
|
|
127
|
-
return Array.from(this.components.values());
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// ============ 核心能力(子类可覆盖) ============
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* 处理自然语言查询(核心入口)
|
|
134
|
-
*
|
|
135
|
-
* 委托给 AgentComponent.run() 处理
|
|
136
|
-
*/
|
|
137
|
-
@TracedAs("env.handle_query", { recordParams: true, recordResult: true, log: true })
|
|
138
|
-
async handle_query(
|
|
139
|
-
query: string,
|
|
140
|
-
context?: import("./agent/types").AgentContext
|
|
141
|
-
): Promise<string> {
|
|
142
|
-
// 1. 获取 AgentComponent
|
|
143
|
-
const agentComponent = this.getComponent<import("./agent/agent-component").AgentComponent>("agent");
|
|
144
|
-
|
|
145
|
-
if (!agentComponent) {
|
|
146
|
-
throw new Error("AgentComponent not found. Please register AgentComponent before calling handle_query.");
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// 2. 获取 system prompt(从 PromptComponent 获取)
|
|
150
|
-
let systemPrompt = "You are a helpful assistant.";
|
|
151
|
-
let promptSource = "fallback";
|
|
152
|
-
try {
|
|
153
|
-
const promptComponent = this.getComponent<import("./prompt/prompt-component").PromptComponent>("prompt");
|
|
154
|
-
if (promptComponent) {
|
|
155
|
-
const loadedPrompt = await promptComponent.getPrompt("default");
|
|
156
|
-
if (loadedPrompt) {
|
|
157
|
-
systemPrompt = loadedPrompt;
|
|
158
|
-
promptSource = "PromptComponent";
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
} catch (err) {
|
|
162
|
-
logger.warn(`[handle_query] Failed to get prompt from PromptComponent: ${err}`);
|
|
163
|
-
}
|
|
164
|
-
logger.info(`[handle_query] Using system prompt from ${promptSource}, length: ${systemPrompt.length}`);
|
|
165
|
-
|
|
166
|
-
// 3. 读取 memory 内容并注入到 prompt(如果 {{memory}} 变量存在)
|
|
167
|
-
let finalSystemPrompt = systemPrompt;
|
|
168
|
-
if (systemPrompt.includes("{{memory}}")) {
|
|
169
|
-
try {
|
|
170
|
-
const memoryComponent = this.getComponent<import("./memory/memory-component").MemoryComponent>("memory");
|
|
171
|
-
if (memoryComponent) {
|
|
172
|
-
const memoryContent = await memoryComponent.recallMemory();
|
|
173
|
-
finalSystemPrompt = systemPrompt.replace("{{memory}}", memoryContent || "(No memory)");
|
|
174
|
-
logger.info(`[handle_query] Injected memory content, length: ${memoryContent.length}`);
|
|
175
|
-
} else {
|
|
176
|
-
finalSystemPrompt = systemPrompt.replace("{{memory}}", "(Memory component not available)");
|
|
177
|
-
}
|
|
178
|
-
} catch (err) {
|
|
179
|
-
logger.warn(`[handle_query] Failed to load memory content: ${err}`);
|
|
180
|
-
finalSystemPrompt = systemPrompt.replace("{{memory}}", "(Failed to load memory)");
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// 3.1 注入 workspace_dir(当前工作目录)
|
|
185
|
-
if (finalSystemPrompt.includes("{{workspace_dir}}")) {
|
|
186
|
-
const workspaceDir = process.cwd();
|
|
187
|
-
finalSystemPrompt = finalSystemPrompt.replace("{{workspace_dir}}", workspaceDir);
|
|
188
|
-
logger.debug(`[handle_query] Injected workspace_dir: ${workspaceDir}`);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// 4. 根据 agentType 获取或创建 agent
|
|
192
|
-
// - 如果 context.agentType 为空或 "default",使用默认 agent
|
|
193
|
-
// - 否则使用 context.agentType 对应的 agent(delegate-tool 会预先注册)
|
|
194
|
-
const agentName = (context?.agentType && context.agentType !== "default")
|
|
195
|
-
? context.agentType
|
|
196
|
-
: "default";
|
|
197
|
-
|
|
198
|
-
let agent = agentComponent.getAgent(agentName);
|
|
199
|
-
if (!agent) {
|
|
200
|
-
// 如果指定了 agentType 但 agent 不存在,使用默认 agent
|
|
201
|
-
if (agentName !== "default") {
|
|
202
|
-
logger.warn(`[handle_query] Agent "${agentName}" not found, falling back to "default"`);
|
|
203
|
-
}
|
|
204
|
-
agent = agentComponent.getAgent("default");
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// 如果默认 agent 也不存在,则创建
|
|
208
|
-
if (!agent) {
|
|
209
|
-
agent = agentComponent.registerAgent("default", {
|
|
210
|
-
type: "primary",
|
|
211
|
-
systemPrompt: finalSystemPrompt,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// 执行 agent
|
|
216
|
-
const result = await agentComponent.run(agent.name, query, context);
|
|
217
|
-
|
|
218
|
-
// 4. 如果有错误,检查是否是 ContextError,需要让上层处理
|
|
219
|
-
if (result.error) {
|
|
220
|
-
// 如果错误信息包含上下文阈值相关,抛出 ContextError 让 ContextHandler 处理
|
|
221
|
-
const errorMsg = result.error.toLowerCase();
|
|
222
|
-
if (
|
|
223
|
-
errorMsg.includes("context") ||
|
|
224
|
-
errorMsg.includes("threshold") ||
|
|
225
|
-
errorMsg.includes("token") ||
|
|
226
|
-
result.error.includes("CTX_001")
|
|
227
|
-
) {
|
|
228
|
-
// 尝试从错误消息中提取上下文使用信息
|
|
229
|
-
// 格式如: "Context threshold exceeded: 1230/10000 (12.3%)"
|
|
230
|
-
const usageMatch = result.error.match(/(\d+)\/(\d+)\s*\(([\d.]+)%\)/);
|
|
231
|
-
let usage: { promptTokens: number; completionTokens: number; totalTokens: number } | undefined;
|
|
232
|
-
let contextWindow: number | undefined;
|
|
233
|
-
|
|
234
|
-
if (usageMatch) {
|
|
235
|
-
const totalTokens = parseInt(usageMatch[1], 10);
|
|
236
|
-
usage = {
|
|
237
|
-
promptTokens: totalTokens,
|
|
238
|
-
completionTokens: 0,
|
|
239
|
-
totalTokens
|
|
240
|
-
};
|
|
241
|
-
contextWindow = parseInt(usageMatch[2], 10);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// 构造 ContextError 抛出
|
|
245
|
-
const ctxError = new ContextError(
|
|
246
|
-
result.error,
|
|
247
|
-
ErrorCodes.CONTEXT_THRESHOLD_EXCEEDED,
|
|
248
|
-
context?.sessionId,
|
|
249
|
-
usage,
|
|
250
|
-
contextWindow
|
|
251
|
-
);
|
|
252
|
-
throw ctxError;
|
|
253
|
-
}
|
|
254
|
-
// 其他错误继续抛出
|
|
255
|
-
throw new Error(result.error);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// 6. 返回响应文本
|
|
259
|
-
return result.finalText || "";
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* 处理动作
|
|
264
|
-
*
|
|
265
|
-
* 默认实现抛出错误,子类必须实现。
|
|
266
|
-
*/
|
|
267
|
-
async handle_action(action: Action, context: Context): Promise<ToolResult> {
|
|
268
|
-
throw new Error("handle_action not implemented. Override in subclass.");
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// ============ EnvEvent 机制 ============
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* 事件订阅者映射
|
|
275
|
-
*/
|
|
276
|
-
protected eventHandlers = new Map<string, Set<EnvEventHandler>>();
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* 通配符订阅者(接收所有事件)
|
|
280
|
-
*/
|
|
281
|
-
protected wildcardHandlers = new Set<EnvEventHandler>();
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* 订阅 EnvEvent(返回取消订阅函数)
|
|
285
|
-
*/
|
|
286
|
-
subscribe(handler: EnvEventHandler): () => void {
|
|
287
|
-
this.wildcardHandlers.add(handler);
|
|
288
|
-
logger.debug(`EnvEvent handler subscribed (wildcard)`);
|
|
289
|
-
|
|
290
|
-
// 返回取消订阅函数
|
|
291
|
-
return () => {
|
|
292
|
-
this.wildcardHandlers.delete(handler);
|
|
293
|
-
logger.debug(`EnvEvent handler unsubscribed (wildcard)`);
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* 订阅指定类型事件
|
|
299
|
-
*/
|
|
300
|
-
subscribeTo(eventType: string | string[], handler: EnvEventHandler): () => void {
|
|
301
|
-
const types = Array.isArray(eventType) ? eventType : [eventType];
|
|
302
|
-
|
|
303
|
-
for (const type of types) {
|
|
304
|
-
if (!this.eventHandlers.has(type)) {
|
|
305
|
-
this.eventHandlers.set(type, new Set());
|
|
306
|
-
}
|
|
307
|
-
this.eventHandlers.get(type)!.add(handler);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
logger.debug(`EnvEvent handler subscribed for types: ${types.join(", ")}`);
|
|
311
|
-
|
|
312
|
-
// 返回取消订阅函数
|
|
313
|
-
return () => {
|
|
314
|
-
for (const type of types) {
|
|
315
|
-
this.eventHandlers.get(type)?.delete(handler);
|
|
316
|
-
}
|
|
317
|
-
logger.debug(`EnvEvent handler unsubscribed for types: ${types.join(", ")}`);
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* 订阅所有事件(通配符)
|
|
323
|
-
*
|
|
324
|
-
* 与 subscribe 相同,为保持 API 一致性
|
|
325
|
-
*/
|
|
326
|
-
subscribeAll(handler: EnvEventHandler): () => void {
|
|
327
|
-
return this.subscribe(handler);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* 推送事件
|
|
332
|
-
*/
|
|
333
|
-
pushEnvEvent(event: EnvEvent | EnvEventInput): void {
|
|
334
|
-
// 如果是完整 EnvEvent,直接使用;否则创建新的
|
|
335
|
-
const fullEvent: EnvEvent = "id" in event && event.id
|
|
336
|
-
? event as EnvEvent
|
|
337
|
-
: {
|
|
338
|
-
id: (event as EnvEventInput).id ?? generateId(),
|
|
339
|
-
type: event.type,
|
|
340
|
-
timestamp: (event as EnvEventInput).timestamp ?? Date.now(),
|
|
341
|
-
metadata: {
|
|
342
|
-
...(event as EnvEventInput).metadata,
|
|
343
|
-
env_name: (event as EnvEventInput).metadata?.env_name ?? this.name,
|
|
344
|
-
},
|
|
345
|
-
payload: (event as EnvEventInput).payload ?? {},
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// 通知通配符订阅者
|
|
349
|
-
for (const handler of this.wildcardHandlers) {
|
|
350
|
-
try {
|
|
351
|
-
handler(fullEvent);
|
|
352
|
-
} catch (error) {
|
|
353
|
-
logger.error(`Error in EnvEvent handler: ${error}`);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// 通知特定类型订阅者
|
|
358
|
-
const handlers = this.eventHandlers.get(fullEvent.type);
|
|
359
|
-
if (handlers) {
|
|
360
|
-
for (const handler of handlers) {
|
|
361
|
-
try {
|
|
362
|
-
handler(fullEvent);
|
|
363
|
-
} catch (error) {
|
|
364
|
-
logger.error(`Error in EnvEvent handler for ${fullEvent.type}: ${error}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* 创建并推送事件(便捷方法)
|
|
372
|
-
*/
|
|
373
|
-
protected emit<T = unknown>(
|
|
374
|
-
type: string,
|
|
375
|
-
payload: T,
|
|
376
|
-
metadata?: Partial<EnvEvent["metadata"]>
|
|
377
|
-
): void {
|
|
378
|
-
const event: EnvEvent<T> = {
|
|
379
|
-
id: generateId(),
|
|
380
|
-
type,
|
|
381
|
-
timestamp: Date.now(),
|
|
382
|
-
metadata: {
|
|
383
|
-
env_name: this.name,
|
|
384
|
-
...metadata,
|
|
385
|
-
},
|
|
386
|
-
payload,
|
|
387
|
-
};
|
|
388
|
-
this.pushEnvEvent(event);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// ============ 生命周期 ============
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* 初始化所有组件(分阶段初始化)
|
|
395
|
-
*
|
|
396
|
-
* 1. 第一阶段:初始化 ConfigComponent(如果存在)
|
|
397
|
-
* 2. 第二阶段:初始化其他组件
|
|
398
|
-
*/
|
|
399
|
-
protected async initializeComponents(): Promise<void> {
|
|
400
|
-
logger.debug(`Starting component initialization, total: ${this.components.size}`);
|
|
401
|
-
|
|
402
|
-
// 1️⃣ 第一阶段:初始化 ConfigComponent(如果存在)
|
|
403
|
-
// 特殊处理:直接访问 this.components 因为此时 ConfigComponent 尚未 init
|
|
404
|
-
// 正常情况下组件应通过 this.env.getComponent() 获取其他已初始化的组件
|
|
405
|
-
const configComp = this.components.get("config");
|
|
406
|
-
if (configComp && configComp.getStatus() === "created") {
|
|
407
|
-
logger.debug(`Initializing ConfigComponent first...`);
|
|
408
|
-
await configComp.init({
|
|
409
|
-
name: "config",
|
|
410
|
-
version: configComp.version,
|
|
411
|
-
enabled: true,
|
|
412
|
-
env: this,
|
|
413
|
-
});
|
|
414
|
-
logger.debug(`ConfigComponent initialized`);
|
|
415
|
-
} else {
|
|
416
|
-
logger.debug(`No ConfigComponent found, skipping first stage`);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// 2️⃣ 第二阶段:初始化其他组件
|
|
420
|
-
const otherComponents = Array.from(this.components.values())
|
|
421
|
-
.filter(c => c.getStatus() === "created");
|
|
422
|
-
|
|
423
|
-
if (otherComponents.length > 0) {
|
|
424
|
-
logger.debug(`Initializing ${otherComponents.length} other components...`);
|
|
425
|
-
for (const component of otherComponents) {
|
|
426
|
-
logger.debug(`Initializing component: ${component.name}`);
|
|
427
|
-
await component.init({
|
|
428
|
-
name: component.name,
|
|
429
|
-
version: component.version,
|
|
430
|
-
enabled: true,
|
|
431
|
-
env: this,
|
|
432
|
-
});
|
|
433
|
-
logger.debug(`Component initialized: ${component.name}`);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
logger.debug(`All components initialized`);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* 启动所有组件
|
|
442
|
-
*
|
|
443
|
-
* 注意:由于 Environment.init() 会将组件状态设为 "running",我们需要确保
|
|
444
|
-
* 即使组件已经是 "running" 状态,它们的 start() 方法仍然被调用。
|
|
445
|
-
* 这是因为 start() 负责注册工具等运行时资源。
|
|
446
|
-
*/
|
|
447
|
-
protected async startComponents(): Promise<void> {
|
|
448
|
-
// 启动所有已注册的组件(不检查状态)
|
|
449
|
-
const allComponents = Array.from(this.components.values());
|
|
450
|
-
|
|
451
|
-
if (allComponents.length > 0) {
|
|
452
|
-
logger.debug(`Starting ${allComponents.length} components...`);
|
|
453
|
-
for (const component of allComponents) {
|
|
454
|
-
logger.debug(`Starting component: ${component.name} (current status: ${component.getStatus()})`);
|
|
455
|
-
await component.start();
|
|
456
|
-
logger.debug(`Component started: ${component.name}`);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* 停止所有组件
|
|
463
|
-
*/
|
|
464
|
-
protected async stopComponents(): Promise<void> {
|
|
465
|
-
const componentsToStop = Array.from(this.components.values())
|
|
466
|
-
.filter(c => c.getStatus() !== "stopped");
|
|
467
|
-
|
|
468
|
-
if (componentsToStop.length > 0) {
|
|
469
|
-
logger.debug(`Stopping ${componentsToStop.length} components...`);
|
|
470
|
-
for (const component of componentsToStop) {
|
|
471
|
-
logger.debug(`Stopping component: ${component.name}`);
|
|
472
|
-
await component.stop();
|
|
473
|
-
logger.debug(`Component stopped: ${component.name}`);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* 初始化(可覆盖)
|
|
480
|
-
*/
|
|
481
|
-
protected async onInit(): Promise<void> {
|
|
482
|
-
await this.initializeComponents();
|
|
483
|
-
logger.info(`Environment "${this.name}" initialized`);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* 启动(可覆盖)
|
|
488
|
-
*/
|
|
489
|
-
protected async onStart(): Promise<void> {
|
|
490
|
-
await this.startComponents();
|
|
491
|
-
logger.info(`Environment "${this.name}" started`);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* 停止(可覆盖)
|
|
496
|
-
*/
|
|
497
|
-
protected async onStop(): Promise<void> {
|
|
498
|
-
await this.stopComponents();
|
|
499
|
-
// 清理事件处理器
|
|
500
|
-
this.eventHandlers.clear();
|
|
501
|
-
this.wildcardHandlers.clear();
|
|
502
|
-
logger.info(`Environment "${this.name}" stopped`);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* BaseComponent 钩子
|
|
507
|
-
*
|
|
508
|
-
* Environment 特殊处理:它本身就是 env,所以不需要外部传入。
|
|
509
|
-
* 此方法覆盖 BaseComponent.init(),直接设置自引用。
|
|
510
|
-
*/
|
|
511
|
-
async init(): Promise<void> {
|
|
512
|
-
// Environment 特殊处理:设置自引用
|
|
513
|
-
// 注意:这里需要直接访问 protected env 属性,使用 TypeScript 的原型链访问
|
|
514
|
-
// 这是唯一需要绕过类型检查的地方,因为 Environment 是特殊情况
|
|
515
|
-
Object.defineProperty(this, "env", {
|
|
516
|
-
value: this,
|
|
517
|
-
writable: true,
|
|
518
|
-
enumerable: false,
|
|
519
|
-
configurable: true,
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
this.setStatus("initializing");
|
|
523
|
-
await this.onInit();
|
|
524
|
-
this.setStatus("running");
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
async start(): Promise<void> {
|
|
528
|
-
// 注意:Environment.init() 会将状态设为 "running",但组件的 start() 仍需被调用
|
|
529
|
-
// 所以这里使用一个内部标志来跟踪是否已经启动过
|
|
530
|
-
if ((this as any)._started) return;
|
|
531
|
-
(this as any)._started = true;
|
|
532
|
-
|
|
533
|
-
await this.onStart();
|
|
534
|
-
this.setStatus("running");
|
|
535
|
-
logger.info(`Environment "${this.name}" started`);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
async stop(): Promise<void> {
|
|
539
|
-
this.setStatus("stopping");
|
|
540
|
-
await this.onStop();
|
|
541
|
-
this.setStatus("stopped");
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// ============ 服务配置能力 ============
|
|
545
|
-
|
|
546
|
-
/**
|
|
547
|
-
* 从配置文件加载服务配置
|
|
548
|
-
*/
|
|
549
|
-
async loadServiceConfig(configPath: string): Promise<ServiceConfig> {
|
|
550
|
-
// 1. 获取 ConfigComponent
|
|
551
|
-
const configComponent = this.getComponent<import("../config/config-component").ConfigComponent>("config");
|
|
552
|
-
if (!configComponent) {
|
|
553
|
-
throw new Error("ConfigComponent not found. Please register ConfigComponent before loading service config.");
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// 2. 获取配置目录
|
|
557
|
-
const xdgDataHome = configComponent.getXdgDataHome();
|
|
558
|
-
|
|
559
|
-
// 3. 读取配置文件
|
|
560
|
-
const fullPath = path.resolve(xdgDataHome, configPath);
|
|
561
|
-
if (!fsSync.existsSync(fullPath)) {
|
|
562
|
-
throw new Error(`Service config file not found: ${fullPath}`);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// 4. 解析配置文件(支持 JSON/JSONC)
|
|
566
|
-
const content = fsSync.readFileSync(fullPath, "utf-8");
|
|
567
|
-
let config: ServiceConfig;
|
|
568
|
-
|
|
569
|
-
try {
|
|
570
|
-
config = JSON.parse(content);
|
|
571
|
-
} catch (e) {
|
|
572
|
-
throw new Error(`Failed to parse service config: ${e}`);
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
logger.debug(`Service config loaded from: ${fullPath}`);
|
|
576
|
-
return config;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
/**
|
|
580
|
-
* 生成组件初始化选项
|
|
581
|
-
*/
|
|
582
|
-
generateComponentOptions(
|
|
583
|
-
componentName: string,
|
|
584
|
-
configEntry: ComponentConfigEntry
|
|
585
|
-
): GeneratedComponentOptions {
|
|
586
|
-
// 1. 获取 ConfigComponent(必填)
|
|
587
|
-
const configComponent = this.getComponent<import("../config/config-component").ConfigComponent>("config");
|
|
588
|
-
if (!configComponent) {
|
|
589
|
-
throw new Error("ConfigComponent not found. Please register ConfigComponent before generating component options.");
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// 2. 构建选项对象
|
|
593
|
-
const options: GeneratedComponentOptions = {
|
|
594
|
-
configComponent,
|
|
595
|
-
configPath: configEntry.configPath,
|
|
596
|
-
envPrefix: configEntry.envPrefix,
|
|
597
|
-
config: configEntry.config,
|
|
598
|
-
};
|
|
599
|
-
|
|
600
|
-
logger.debug(`Generated options for component: ${componentName}`);
|
|
601
|
-
return options;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* 注册组件并用配置初始化
|
|
606
|
-
*/
|
|
607
|
-
async registerComponentWithConfig(
|
|
608
|
-
component: Component,
|
|
609
|
-
configEntry: ComponentConfigEntry
|
|
610
|
-
): Promise<void> {
|
|
611
|
-
// 1. 如果组件未注册,先注册
|
|
612
|
-
if (!this.components.has(component.name)) {
|
|
613
|
-
this.registerComponent(component);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
// 2. 生成初始化选项
|
|
617
|
-
const options = this.generateComponentOptions(component.name, configEntry);
|
|
618
|
-
|
|
619
|
-
// 3. 如果组件已初始化,跳过
|
|
620
|
-
if (component.getStatus() === "running") {
|
|
621
|
-
logger.debug(`Component ${component.name} already initialized, skipping`);
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
// 4. 初始化组件
|
|
626
|
-
await component.init({
|
|
627
|
-
name: component.name,
|
|
628
|
-
version: component.version,
|
|
629
|
-
enabled: configEntry.enabled ?? true,
|
|
630
|
-
env: this,
|
|
631
|
-
options,
|
|
632
|
-
});
|
|
633
|
-
|
|
634
|
-
logger.debug(`Component ${component.name} registered and initialized with config`);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* 从配置文件初始化整个环境
|
|
639
|
-
*/
|
|
640
|
-
async initFromConfig(configPath: string): Promise<void> {
|
|
641
|
-
// 0. 设置 Environment 自引用(如果不尚未设置)
|
|
642
|
-
if (!(this as any).env) {
|
|
643
|
-
Object.defineProperty(this, "env", {
|
|
644
|
-
value: this,
|
|
645
|
-
writable: true,
|
|
646
|
-
enumerable: false,
|
|
647
|
-
configurable: true,
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// 1. 加载服务配置
|
|
652
|
-
const serviceConfig = await this.loadServiceConfig(configPath);
|
|
653
|
-
|
|
654
|
-
// 2. 更新环境名称和版本(如果配置了)
|
|
655
|
-
if (serviceConfig.environment) {
|
|
656
|
-
if (serviceConfig.environment.name) {
|
|
657
|
-
(this as any).name = serviceConfig.environment.name;
|
|
658
|
-
}
|
|
659
|
-
if (serviceConfig.environment.version) {
|
|
660
|
-
(this as any).version = serviceConfig.environment.version;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// 3. 确保 ConfigComponent 已注册
|
|
665
|
-
const configComponent = this.getComponent<import("../config/config-component").ConfigComponent>("config");
|
|
666
|
-
if (!configComponent) {
|
|
667
|
-
throw new Error("ConfigComponent not found. Please register ConfigComponent before initFromConfig.");
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// 4. 初始化 ConfigComponent
|
|
671
|
-
if (configComponent.getStatus() === "created") {
|
|
672
|
-
await configComponent.init({
|
|
673
|
-
name: "config",
|
|
674
|
-
version: configComponent.version,
|
|
675
|
-
enabled: true,
|
|
676
|
-
env: this,
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// 5. 初始化每个配置的组件
|
|
681
|
-
const components = serviceConfig.components || {};
|
|
682
|
-
for (const [componentName, configEntry] of Object.entries(components)) {
|
|
683
|
-
// 跳过禁用的组件
|
|
684
|
-
if (configEntry.enabled === false) {
|
|
685
|
-
logger.debug(`Component ${componentName} is disabled, skipping`);
|
|
686
|
-
continue;
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// 获取组件实例
|
|
690
|
-
const component = this.getComponent(componentName);
|
|
691
|
-
if (!component) {
|
|
692
|
-
logger.warn(`Component ${componentName} not registered, skipping`);
|
|
693
|
-
continue;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// 跳过 ConfigComponent(已初始化)
|
|
697
|
-
if (component.name === "config") continue;
|
|
698
|
-
|
|
699
|
-
// 注册并初始化
|
|
700
|
-
await this.registerComponentWithConfig(component, configEntry);
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// 6. 设置环境状态为 running
|
|
704
|
-
this.setStatus("running");
|
|
705
|
-
|
|
706
|
-
logger.info(`Environment "${this.name}" initialized from config: ${configPath}`);
|
|
707
|
-
}
|
|
708
|
-
}
|