@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,334 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
inferNextNode,
|
|
4
|
-
findLastInterruptMessage,
|
|
5
|
-
findLastCallMessage,
|
|
6
|
-
parseNodeOutputs,
|
|
7
|
-
type ResumePoint,
|
|
8
|
-
} from './session-recovery';
|
|
9
|
-
|
|
10
|
-
// Mock SessionMessage type
|
|
11
|
-
interface MockMessage {
|
|
12
|
-
role: string;
|
|
13
|
-
content: string;
|
|
14
|
-
metadata: Record<string, unknown>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function createMessage(role: string, content: string, metadata: Record<string, unknown>): MockMessage {
|
|
18
|
-
return { role, content, metadata };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('inferNextNode', () => {
|
|
22
|
-
describe('when no messages', () => {
|
|
23
|
-
it('should return entry node from definition', () => {
|
|
24
|
-
const messages: MockMessage[] = [];
|
|
25
|
-
const definition = {
|
|
26
|
-
entryNode: 'node_A',
|
|
27
|
-
nodes: { node_A: { id: 'node_A' } },
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const result = inferNextNode(messages as any, definition);
|
|
31
|
-
|
|
32
|
-
expect(result.type).toBe('entry_node');
|
|
33
|
-
expect(result.nodeId).toBe('node_A');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should handle missing entryNode', () => {
|
|
37
|
-
const messages: MockMessage[] = [];
|
|
38
|
-
const definition = {};
|
|
39
|
-
|
|
40
|
-
const result = inferNextNode(messages as any, definition);
|
|
41
|
-
|
|
42
|
-
expect(result.type).toBe('entry_node');
|
|
43
|
-
expect(result.nodeId).toBeUndefined();
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('when last message is workflow.node.call', () => {
|
|
48
|
-
it('should return resume_node type with nodeId', () => {
|
|
49
|
-
const messages = [
|
|
50
|
-
createMessage('workflow.node.call', '{}', {
|
|
51
|
-
type: 'workflow.node.call',
|
|
52
|
-
workflowNodeId: 'node_A',
|
|
53
|
-
workflowNodeType: 'tool',
|
|
54
|
-
}),
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
const result = inferNextNode(messages as any, {});
|
|
58
|
-
|
|
59
|
-
expect(result.type).toBe('resume_node');
|
|
60
|
-
expect(result.nodeId).toBe('node_A');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should include agentSessionId if present', () => {
|
|
64
|
-
const messages = [
|
|
65
|
-
createMessage('workflow.node.call', '{}', {
|
|
66
|
-
type: 'workflow.node.call',
|
|
67
|
-
workflowNodeId: 'agent_1',
|
|
68
|
-
workflowNodeType: 'agent',
|
|
69
|
-
agentSessionId: 'agent_agent_1_123',
|
|
70
|
-
}),
|
|
71
|
-
];
|
|
72
|
-
|
|
73
|
-
const result = inferNextNode(messages as any, {});
|
|
74
|
-
|
|
75
|
-
expect(result.type).toBe('resume_node');
|
|
76
|
-
expect(result.nodeId).toBe('agent_1');
|
|
77
|
-
expect(result.agentSessionId).toBe('agent_agent_1_123');
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe('when last message is workflow.node.interrupt', () => {
|
|
82
|
-
it('should return ask_user type with nodeId', () => {
|
|
83
|
-
const messages = [
|
|
84
|
-
createMessage('workflow.node.interrupt', 'Continue?', {
|
|
85
|
-
type: 'workflow.node.interrupt',
|
|
86
|
-
workflowNodeId: 'ask_user_1',
|
|
87
|
-
workflowNodeType: 'ask_user',
|
|
88
|
-
query: 'Continue?',
|
|
89
|
-
}),
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
const result = inferNextNode(messages as any, {});
|
|
93
|
-
|
|
94
|
-
expect(result.type).toBe('ask_user');
|
|
95
|
-
expect(result.nodeId).toBe('ask_user_1');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should include agentSessionId if present', () => {
|
|
99
|
-
const messages = [
|
|
100
|
-
createMessage('workflow.node.interrupt', 'Confirm?', {
|
|
101
|
-
type: 'workflow.node.interrupt',
|
|
102
|
-
workflowNodeId: 'agent_1',
|
|
103
|
-
workflowNodeType: 'agent',
|
|
104
|
-
query: 'Confirm?',
|
|
105
|
-
agentSessionId: 'agent_agent_1_456',
|
|
106
|
-
}),
|
|
107
|
-
];
|
|
108
|
-
|
|
109
|
-
const result = inferNextNode(messages as any, {});
|
|
110
|
-
|
|
111
|
-
expect(result.type).toBe('ask_user');
|
|
112
|
-
expect(result.nodeId).toBe('agent_1');
|
|
113
|
-
expect(result.agentSessionId).toBe('agent_agent_1_456');
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe('when last message is workflow.node.result', () => {
|
|
118
|
-
it('should return next_nodes from DAG edges', () => {
|
|
119
|
-
const messages = [
|
|
120
|
-
createMessage('workflow.node.call', '{}', {
|
|
121
|
-
type: 'workflow.node.call',
|
|
122
|
-
workflowNodeId: 'node_A',
|
|
123
|
-
}),
|
|
124
|
-
createMessage('workflow.node.result', '{"output":"done"}', {
|
|
125
|
-
type: 'workflow.node.result',
|
|
126
|
-
workflowNodeId: 'node_A',
|
|
127
|
-
workflowNodeType: 'tool',
|
|
128
|
-
success: true,
|
|
129
|
-
}),
|
|
130
|
-
];
|
|
131
|
-
|
|
132
|
-
const definition = {
|
|
133
|
-
edges: [
|
|
134
|
-
{ from: 'node_A', to: 'node_B' },
|
|
135
|
-
{ from: 'node_A', to: 'node_C' },
|
|
136
|
-
],
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const result = inferNextNode(messages as any, definition);
|
|
140
|
-
|
|
141
|
-
expect(result.type).toBe('next_nodes');
|
|
142
|
-
expect(result.nodeIds).toEqual(['node_B', 'node_C']);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it('should return empty array if no edges from node', () => {
|
|
146
|
-
const messages = [
|
|
147
|
-
createMessage('workflow.node.result', '{"output":"done"}', {
|
|
148
|
-
type: 'workflow.node.result',
|
|
149
|
-
workflowNodeId: 'node_A',
|
|
150
|
-
success: true,
|
|
151
|
-
}),
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
const definition = {
|
|
155
|
-
edges: [
|
|
156
|
-
{ from: 'node_B', to: 'node_C' },
|
|
157
|
-
],
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const result = inferNextNode(messages as any, definition);
|
|
161
|
-
|
|
162
|
-
expect(result.type).toBe('next_nodes');
|
|
163
|
-
expect(result.nodeIds).toEqual([]);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should return empty array if no edges defined', () => {
|
|
167
|
-
const messages = [
|
|
168
|
-
createMessage('workflow.node.result', '{"output":"done"}', {
|
|
169
|
-
type: 'workflow.node.result',
|
|
170
|
-
workflowNodeId: 'node_A',
|
|
171
|
-
success: true,
|
|
172
|
-
}),
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
const result = inferNextNode(messages as any, {});
|
|
176
|
-
|
|
177
|
-
expect(result.type).toBe('next_nodes');
|
|
178
|
-
expect(result.nodeIds).toEqual([]);
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe('when last message has unknown type', () => {
|
|
183
|
-
it('should find last call message and resume', () => {
|
|
184
|
-
const messages = [
|
|
185
|
-
createMessage('user', 'hello', {}),
|
|
186
|
-
createMessage('workflow.node.call', '{}', {
|
|
187
|
-
type: 'workflow.node.call',
|
|
188
|
-
workflowNodeId: 'node_A',
|
|
189
|
-
}),
|
|
190
|
-
createMessage('system', 'some status', {
|
|
191
|
-
type: 'unknown',
|
|
192
|
-
}),
|
|
193
|
-
];
|
|
194
|
-
|
|
195
|
-
const result = inferNextNode(messages as any, {});
|
|
196
|
-
|
|
197
|
-
expect(result.type).toBe('resume_node');
|
|
198
|
-
expect(result.nodeId).toBe('node_A');
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('should fallback to entry node if no call found', () => {
|
|
202
|
-
const messages = [
|
|
203
|
-
createMessage('user', 'hello', {}),
|
|
204
|
-
];
|
|
205
|
-
|
|
206
|
-
const definition = { entryNode: 'start' };
|
|
207
|
-
|
|
208
|
-
const result = inferNextNode(messages as any, definition);
|
|
209
|
-
|
|
210
|
-
expect(result.type).toBe('entry_node');
|
|
211
|
-
expect(result.nodeId).toBe('start');
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
describe('findLastInterruptMessage', () => {
|
|
217
|
-
it('should return last interrupt message', () => {
|
|
218
|
-
const messages = [
|
|
219
|
-
createMessage('workflow.node.call', '{}', { type: 'workflow.node.call' }),
|
|
220
|
-
createMessage('workflow.node.result', '{}', { type: 'workflow.node.result' }),
|
|
221
|
-
createMessage('workflow.node.interrupt', 'Continue?', {
|
|
222
|
-
type: 'workflow.node.interrupt',
|
|
223
|
-
workflowNodeId: 'ask_1',
|
|
224
|
-
}),
|
|
225
|
-
];
|
|
226
|
-
|
|
227
|
-
const result = findLastInterruptMessage(messages as any);
|
|
228
|
-
|
|
229
|
-
expect(result).not.toBeNull();
|
|
230
|
-
expect(result!.metadata.workflowNodeId).toBe('ask_1');
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('should return null if no interrupt message', () => {
|
|
234
|
-
const messages = [
|
|
235
|
-
createMessage('workflow.node.call', '{}', { type: 'workflow.node.call' }),
|
|
236
|
-
createMessage('workflow.node.result', '{}', { type: 'workflow.node.result' }),
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
const result = findLastInterruptMessage(messages as any);
|
|
240
|
-
|
|
241
|
-
expect(result).toBeNull();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
it('should return null for empty array', () => {
|
|
245
|
-
const result = findLastInterruptMessage([]);
|
|
246
|
-
expect(result).toBeNull();
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
describe('findLastCallMessage', () => {
|
|
251
|
-
it('should return last call message', () => {
|
|
252
|
-
const messages = [
|
|
253
|
-
createMessage('workflow.node.call', '{}', {
|
|
254
|
-
type: 'workflow.node.call',
|
|
255
|
-
workflowNodeId: 'node_A',
|
|
256
|
-
}),
|
|
257
|
-
createMessage('workflow.node.call', '{}', {
|
|
258
|
-
type: 'workflow.node.call',
|
|
259
|
-
workflowNodeId: 'node_B',
|
|
260
|
-
}),
|
|
261
|
-
];
|
|
262
|
-
|
|
263
|
-
const result = findLastCallMessage(messages as any);
|
|
264
|
-
|
|
265
|
-
expect(result).not.toBeNull();
|
|
266
|
-
expect(result!.metadata.workflowNodeId).toBe('node_B');
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('should return null if no call message', () => {
|
|
270
|
-
const messages = [
|
|
271
|
-
createMessage('user', 'hello', {}),
|
|
272
|
-
createMessage('workflow.node.result', '{}', { type: 'workflow.node.result' }),
|
|
273
|
-
];
|
|
274
|
-
|
|
275
|
-
const result = findLastCallMessage(messages as any);
|
|
276
|
-
|
|
277
|
-
expect(result).toBeNull();
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
describe('parseNodeOutputs', () => {
|
|
282
|
-
it('should parse outputs from call-result pairs', () => {
|
|
283
|
-
const messages = [
|
|
284
|
-
createMessage('workflow.node.call', '{}', {
|
|
285
|
-
type: 'workflow.node.call',
|
|
286
|
-
workflowNodeId: 'node_A',
|
|
287
|
-
}),
|
|
288
|
-
createMessage('workflow.node.result', '{"output":"result_A"}', {
|
|
289
|
-
type: 'workflow.node.result',
|
|
290
|
-
workflowNodeId: 'node_A',
|
|
291
|
-
}),
|
|
292
|
-
createMessage('workflow.node.call', '{}', {
|
|
293
|
-
type: 'workflow.node.call',
|
|
294
|
-
workflowNodeId: 'node_B',
|
|
295
|
-
}),
|
|
296
|
-
createMessage('workflow.node.result', '{"output":"result_B"}', {
|
|
297
|
-
type: 'workflow.node.result',
|
|
298
|
-
workflowNodeId: 'node_B',
|
|
299
|
-
}),
|
|
300
|
-
];
|
|
301
|
-
|
|
302
|
-
const result = parseNodeOutputs(messages as any);
|
|
303
|
-
|
|
304
|
-
expect(result.get('node_A')).toEqual({ output: 'result_A' });
|
|
305
|
-
expect(result.get('node_B')).toEqual({ output: 'result_B' });
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
it('should handle JSON parse error gracefully', () => {
|
|
309
|
-
const messages = [
|
|
310
|
-
createMessage('workflow.node.call', '{}', {
|
|
311
|
-
type: 'workflow.node.call',
|
|
312
|
-
workflowNodeId: 'node_A',
|
|
313
|
-
}),
|
|
314
|
-
createMessage('workflow.node.result', 'not json', {
|
|
315
|
-
type: 'workflow.node.result',
|
|
316
|
-
workflowNodeId: 'node_A',
|
|
317
|
-
}),
|
|
318
|
-
];
|
|
319
|
-
|
|
320
|
-
const result = parseNodeOutputs(messages as any);
|
|
321
|
-
|
|
322
|
-
expect(result.get('node_A')).toBe('not json');
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it('should return empty map for no outputs', () => {
|
|
326
|
-
const messages = [
|
|
327
|
-
createMessage('user', 'hello', {}),
|
|
328
|
-
];
|
|
329
|
-
|
|
330
|
-
const result = parseNodeOutputs(messages as any);
|
|
331
|
-
|
|
332
|
-
expect(result.size).toBe(0);
|
|
333
|
-
});
|
|
334
|
-
});
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session Recovery Utilities
|
|
3
|
-
*
|
|
4
|
-
* Utilities for inferring the next execution point from session messages.
|
|
5
|
-
* This is the core of the unified run/resume mechanism.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { SessionMessage } from '../../session/types';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Represents a resume point - where to continue execution from
|
|
12
|
-
*/
|
|
13
|
-
export interface ResumePoint {
|
|
14
|
-
/** Type of resume point */
|
|
15
|
-
type: 'entry_node' | 'resume_node' | 'ask_user' | 'next_nodes';
|
|
16
|
-
/** Node ID (for single node resume) */
|
|
17
|
-
nodeId?: string;
|
|
18
|
-
/** Node IDs (for multiple next nodes) */
|
|
19
|
-
nodeIds?: string[];
|
|
20
|
-
/** Agent sub-session ID (for agent node resume) */
|
|
21
|
-
agentSessionId?: string;
|
|
22
|
-
/** Input for the node */
|
|
23
|
-
input?: unknown;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Infer the next node to execute based on session messages
|
|
28
|
-
*
|
|
29
|
-
* Decision logic:
|
|
30
|
-
* - No messages → execute entry node
|
|
31
|
-
* - Last = workflow.node.call → resume this node (incomplete)
|
|
32
|
-
* - Last = workflow.node.interrupt → resume this node (ask_user)
|
|
33
|
-
* - Last = workflow.node.result → execute next nodes from DAG
|
|
34
|
-
* - Unknown → find last call, resume it, or fallback to entry
|
|
35
|
-
*/
|
|
36
|
-
export function inferNextNode(
|
|
37
|
-
messages: SessionMessage[],
|
|
38
|
-
definition: {
|
|
39
|
-
entryNode?: string;
|
|
40
|
-
edges?: Array<{ from: string; to: string }>;
|
|
41
|
-
}
|
|
42
|
-
): ResumePoint {
|
|
43
|
-
if (messages.length === 0) {
|
|
44
|
-
// First run - execute entry node
|
|
45
|
-
return { type: 'entry_node', nodeId: definition.entryNode };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const lastMessage = messages[messages.length - 1];
|
|
49
|
-
const metadata = lastMessage.metadata as Record<string, unknown>;
|
|
50
|
-
|
|
51
|
-
switch (metadata?.type) {
|
|
52
|
-
case 'workflow.node.call':
|
|
53
|
-
// Node was interrupted (not completed)
|
|
54
|
-
return {
|
|
55
|
-
type: 'resume_node',
|
|
56
|
-
nodeId: metadata.workflowNodeId as string,
|
|
57
|
-
agentSessionId: metadata.agentSessionId as string | undefined,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
case 'workflow.node.interrupt':
|
|
61
|
-
// Ask_user or ESC interrupted
|
|
62
|
-
return {
|
|
63
|
-
type: 'ask_user',
|
|
64
|
-
nodeId: metadata.workflowNodeId as string,
|
|
65
|
-
agentSessionId: metadata.agentSessionId as string | undefined,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
case 'workflow.node.result':
|
|
69
|
-
// Node completed, get next from DAG
|
|
70
|
-
return getNextNodes(metadata.workflowNodeId as string, definition);
|
|
71
|
-
|
|
72
|
-
default:
|
|
73
|
-
// Unknown message type, try to find last call
|
|
74
|
-
const lastCall = findLastCallMessage(messages);
|
|
75
|
-
if (lastCall) {
|
|
76
|
-
const callMetadata = lastCall.metadata as Record<string, unknown>;
|
|
77
|
-
return {
|
|
78
|
-
type: 'resume_node',
|
|
79
|
-
nodeId: callMetadata.workflowNodeId as string,
|
|
80
|
-
agentSessionId: callMetadata.agentSessionId as string | undefined,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
// No call found, fallback to entry
|
|
84
|
-
return { type: 'entry_node', nodeId: definition.entryNode };
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Get next nodes from DAG edges
|
|
90
|
-
*/
|
|
91
|
-
function getNextNodes(
|
|
92
|
-
completedNodeId: string,
|
|
93
|
-
definition: { edges?: Array<{ from: string; to: string }> }
|
|
94
|
-
): ResumePoint {
|
|
95
|
-
if (!definition.edges) {
|
|
96
|
-
return { type: 'next_nodes', nodeIds: [] };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const nextNodeIds = definition.edges
|
|
100
|
-
.filter(edge => edge.from === completedNodeId)
|
|
101
|
-
.map(edge => edge.to);
|
|
102
|
-
|
|
103
|
-
return { type: 'next_nodes', nodeIds: nextNodeIds };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Find the last interrupt message in the session
|
|
108
|
-
*/
|
|
109
|
-
export function findLastInterruptMessage(
|
|
110
|
-
messages: SessionMessage[]
|
|
111
|
-
): SessionMessage | null {
|
|
112
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
113
|
-
const msg = messages[i];
|
|
114
|
-
if ((msg.metadata as Record<string, unknown>)?.type === 'workflow.node.interrupt') {
|
|
115
|
-
return msg;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Find the last call message in the session
|
|
123
|
-
*/
|
|
124
|
-
export function findLastCallMessage(
|
|
125
|
-
messages: SessionMessage[]
|
|
126
|
-
): SessionMessage | null {
|
|
127
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
128
|
-
const msg = messages[i];
|
|
129
|
-
if ((msg.metadata as Record<string, unknown>)?.type === 'workflow.node.call') {
|
|
130
|
-
return msg;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Parse node outputs from session messages
|
|
138
|
-
*
|
|
139
|
-
* Extracts outputs by matching workflow.node.call with workflow.node.result pairs
|
|
140
|
-
*/
|
|
141
|
-
export function parseNodeOutputs(
|
|
142
|
-
messages: SessionMessage[]
|
|
143
|
-
): Map<string, unknown> {
|
|
144
|
-
const outputs = new Map<string, unknown>();
|
|
145
|
-
let lastCallNodeId: string | null = null;
|
|
146
|
-
|
|
147
|
-
for (const msg of messages) {
|
|
148
|
-
const metadata = msg.metadata as Record<string, unknown>;
|
|
149
|
-
|
|
150
|
-
if (metadata?.type === 'workflow.node.call') {
|
|
151
|
-
lastCallNodeId = metadata.workflowNodeId as string;
|
|
152
|
-
} else if (metadata?.type === 'workflow.node.result' && lastCallNodeId) {
|
|
153
|
-
try {
|
|
154
|
-
outputs.set(lastCallNodeId, JSON.parse(msg.content as string));
|
|
155
|
-
} catch {
|
|
156
|
-
outputs.set(lastCallNodeId, msg.content);
|
|
157
|
-
}
|
|
158
|
-
lastCallNodeId = null;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return outputs;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Check if session has pending ask_user interrupt
|
|
167
|
-
*/
|
|
168
|
-
export function hasPendingAskUser(messages: SessionMessage[]): boolean {
|
|
169
|
-
if (messages.length === 0) return false;
|
|
170
|
-
|
|
171
|
-
const lastMessage = messages[messages.length - 1];
|
|
172
|
-
const metadata = lastMessage.metadata as Record<string, unknown>;
|
|
173
|
-
|
|
174
|
-
return metadata?.type === 'workflow.node.interrupt';
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Get agent session ID from last interrupt message
|
|
179
|
-
*/
|
|
180
|
-
export function getAgentSessionIdFromInterrupt(
|
|
181
|
-
messages: SessionMessage[]
|
|
182
|
-
): string | null {
|
|
183
|
-
const lastInterrupt = findLastInterruptMessage(messages);
|
|
184
|
-
if (!lastInterrupt) return null;
|
|
185
|
-
|
|
186
|
-
const metadata = lastInterrupt.metadata as Record<string, unknown>;
|
|
187
|
-
return (metadata?.agentSessionId as string) || null;
|
|
188
|
-
}
|