byterover-cli 0.4.0 → 1.0.0
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/README.md +1 -9
- package/dist/commands/curate.d.ts +1 -3
- package/dist/commands/curate.js +14 -51
- package/dist/commands/main.d.ts +8 -0
- package/dist/commands/main.js +29 -8
- package/dist/commands/query.d.ts +1 -3
- package/dist/commands/query.js +8 -35
- package/dist/config/context-tree-domains.d.ts +5 -0
- package/dist/config/context-tree-domains.js +6 -1
- package/dist/config/environment.js +9 -9
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +18 -0
- package/dist/core/domain/cipher/agent/agent-info.d.ts +199 -0
- package/dist/core/domain/cipher/agent/agent-info.js +143 -0
- package/dist/core/domain/cipher/agent/agent-registry.d.ts +96 -0
- package/dist/core/domain/cipher/agent/agent-registry.js +254 -0
- package/dist/core/domain/cipher/agent/index.d.ts +4 -1
- package/dist/core/domain/cipher/agent/index.js +7 -1
- package/dist/core/domain/cipher/agent-events/types.d.ts +355 -2
- package/dist/core/domain/cipher/agent-events/types.js +11 -0
- package/dist/core/domain/cipher/errors/error-normalizer.d.ts +156 -0
- package/dist/core/domain/cipher/errors/error-normalizer.js +379 -0
- package/dist/core/domain/cipher/errors/file-system-error.d.ts +2 -1
- package/dist/core/domain/cipher/errors/file-system-error.js +3 -2
- package/dist/core/domain/cipher/errors/system-prompt-error-codes.d.ts +79 -0
- package/dist/core/domain/cipher/errors/system-prompt-error-codes.js +80 -0
- package/dist/core/domain/cipher/errors/system-prompt-error.d.ts +114 -0
- package/dist/core/domain/cipher/errors/system-prompt-error.js +144 -0
- package/dist/core/domain/cipher/file-system/types.d.ts +57 -0
- package/dist/core/domain/cipher/llm/error-codes.d.ts +51 -0
- package/dist/core/domain/cipher/llm/error-codes.js +51 -0
- package/dist/core/domain/cipher/llm/index.d.ts +9 -0
- package/dist/core/domain/cipher/llm/index.js +13 -0
- package/dist/core/domain/cipher/llm/registry.d.ts +113 -0
- package/dist/core/domain/cipher/llm/registry.js +244 -0
- package/dist/core/domain/cipher/llm/schemas.d.ts +155 -0
- package/dist/core/domain/cipher/llm/schemas.js +151 -0
- package/dist/core/domain/cipher/llm/types.d.ts +121 -0
- package/dist/core/domain/cipher/llm/types.js +60 -0
- package/dist/core/domain/cipher/storage/message-storage-types.d.ts +114 -5
- package/dist/core/domain/cipher/streaming/types.d.ts +119 -0
- package/dist/core/domain/cipher/streaming/types.js +16 -0
- package/dist/core/domain/cipher/system-prompt/types.d.ts +44 -0
- package/dist/core/domain/cipher/todos/types.d.ts +34 -0
- package/dist/core/domain/cipher/tools/constants.d.ts +5 -2
- package/dist/core/domain/cipher/tools/constants.js +5 -2
- package/dist/core/domain/cipher/tools/types.d.ts +31 -0
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +3 -1
- package/dist/core/domain/errors/connection-error.d.ts +33 -0
- package/dist/core/domain/errors/connection-error.js +54 -0
- package/dist/core/domain/errors/core-process-error.d.ts +27 -0
- package/dist/core/domain/errors/core-process-error.js +43 -0
- package/dist/core/domain/errors/task-error.d.ts +64 -0
- package/dist/core/domain/errors/task-error.js +116 -0
- package/dist/core/domain/errors/transport-error.d.ts +72 -0
- package/dist/core/domain/errors/transport-error.js +114 -0
- package/dist/core/domain/instance/index.d.ts +1 -0
- package/dist/core/domain/instance/index.js +1 -0
- package/dist/core/domain/instance/types.d.ts +57 -0
- package/dist/core/domain/instance/types.js +72 -0
- package/dist/core/domain/knowledge/directory-manager.d.ts +16 -0
- package/dist/core/domain/knowledge/directory-manager.js +31 -0
- package/dist/core/domain/transport/index.d.ts +2 -0
- package/dist/core/domain/transport/index.js +2 -0
- package/dist/core/domain/transport/schemas.d.ts +1149 -0
- package/dist/core/domain/transport/schemas.js +554 -0
- package/dist/core/domain/transport/types.d.ts +67 -0
- package/dist/core/domain/transport/types.js +7 -0
- package/dist/core/interfaces/cipher/cipher-services.d.ts +15 -3
- package/dist/core/interfaces/cipher/i-chat-session.d.ts +47 -5
- package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +39 -4
- package/dist/core/interfaces/cipher/i-content-generator.d.ts +3 -5
- package/dist/core/interfaces/cipher/i-file-system.d.ts +12 -1
- package/dist/core/interfaces/cipher/i-llm-service.d.ts +4 -5
- package/dist/core/interfaces/cipher/i-todo-storage.d.ts +24 -0
- package/dist/core/interfaces/cipher/i-todo-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-plugin.d.ts +90 -0
- package/dist/core/interfaces/cipher/i-tool-plugin.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-provider.d.ts +3 -2
- package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +4 -0
- package/dist/core/interfaces/cipher/index.d.ts +35 -0
- package/dist/core/interfaces/cipher/index.js +11 -0
- package/dist/core/interfaces/cipher/message-factory.d.ts +155 -0
- package/dist/core/interfaces/cipher/message-factory.js +252 -0
- package/dist/core/interfaces/cipher/message-type-guards.d.ts +139 -0
- package/dist/core/interfaces/cipher/message-type-guards.js +173 -0
- package/dist/core/interfaces/cipher/message-types.d.ts +279 -5
- package/dist/core/interfaces/cipher/message-types.js +6 -0
- package/dist/core/interfaces/cipher/sanitization-types.d.ts +147 -0
- package/dist/core/interfaces/cipher/sanitization-types.js +46 -0
- package/dist/core/interfaces/executor/i-curate-executor.d.ts +34 -0
- package/dist/core/interfaces/executor/i-curate-executor.js +1 -0
- package/dist/core/interfaces/executor/i-query-executor.d.ts +32 -0
- package/dist/core/interfaces/executor/i-query-executor.js +1 -0
- package/dist/core/interfaces/executor/index.d.ts +2 -0
- package/dist/core/interfaces/executor/index.js +2 -0
- package/dist/core/interfaces/instance/i-instance-discovery.d.ts +45 -0
- package/dist/core/interfaces/instance/i-instance-discovery.js +1 -0
- package/dist/core/interfaces/instance/i-instance-manager.d.ts +58 -0
- package/dist/core/interfaces/instance/i-instance-manager.js +1 -0
- package/dist/core/interfaces/instance/index.d.ts +2 -0
- package/dist/core/interfaces/instance/index.js +2 -0
- package/dist/core/interfaces/noop-implementations.d.ts +53 -0
- package/dist/core/interfaces/noop-implementations.js +62 -0
- package/dist/core/interfaces/transport/i-transport-client.d.ts +97 -0
- package/dist/core/interfaces/transport/i-transport-client.js +1 -0
- package/dist/core/interfaces/transport/i-transport-server.d.ts +93 -0
- package/dist/core/interfaces/transport/i-transport-server.js +1 -0
- package/dist/core/interfaces/transport/index.d.ts +2 -0
- package/dist/core/interfaces/transport/index.js +2 -0
- package/dist/hooks/init/welcome.js +9 -24
- package/dist/infra/cipher/agent/agent-error-codes.d.ts +16 -0
- package/dist/infra/cipher/agent/agent-error-codes.js +17 -0
- package/dist/infra/cipher/agent/agent-error.d.ts +54 -0
- package/dist/infra/cipher/agent/agent-error.js +79 -0
- package/dist/infra/cipher/agent/agent-schemas.d.ts +264 -0
- package/dist/infra/cipher/agent/agent-schemas.js +97 -0
- package/dist/infra/cipher/agent/agent-state-manager.d.ts +140 -0
- package/dist/infra/cipher/agent/agent-state-manager.js +275 -0
- package/dist/infra/cipher/agent/base-agent.d.ts +118 -0
- package/dist/infra/cipher/agent/base-agent.js +240 -0
- package/dist/infra/cipher/agent/cipher-agent.d.ts +165 -0
- package/dist/infra/cipher/agent/cipher-agent.js +546 -0
- package/dist/infra/cipher/agent/index.d.ts +22 -0
- package/dist/infra/cipher/agent/index.js +24 -0
- package/dist/infra/cipher/agent/service-initializer.d.ts +79 -0
- package/dist/infra/cipher/{agent-service-factory.js → agent/service-initializer.js} +117 -68
- package/dist/infra/cipher/agent/types.d.ts +35 -0
- package/dist/infra/cipher/agent/types.js +1 -0
- package/dist/infra/cipher/blob/blob-reference-resolver.d.ts +107 -0
- package/dist/infra/cipher/blob/blob-reference-resolver.js +228 -0
- package/dist/infra/cipher/blob/blob-reference-utils.d.ts +117 -0
- package/dist/infra/cipher/blob/blob-reference-utils.js +230 -0
- package/dist/infra/cipher/consumer/consumer-lock.js +1 -0
- package/dist/infra/cipher/consumer/consumer-service.js +1 -0
- package/dist/infra/cipher/consumer/execution-consumer.d.ts +6 -1
- package/dist/infra/cipher/consumer/execution-consumer.js +54 -16
- package/dist/infra/cipher/consumer/index.d.ts +1 -1
- package/dist/infra/cipher/consumer/index.js +2 -1
- package/dist/infra/cipher/consumer/queue-polling-service.js +1 -0
- package/dist/infra/cipher/file-system/binary-utils.d.ts +43 -0
- package/dist/infra/cipher/file-system/binary-utils.js +164 -0
- package/dist/infra/cipher/file-system/context-tree-file-system-factory.d.ts +9 -0
- package/dist/infra/cipher/file-system/context-tree-file-system-factory.js +24 -0
- package/dist/infra/cipher/file-system/file-system-service.d.ts +17 -1
- package/dist/infra/cipher/file-system/file-system-service.js +327 -36
- package/dist/infra/cipher/file-system/path-validator.d.ts +32 -0
- package/dist/infra/cipher/file-system/path-validator.js +111 -6
- package/dist/infra/cipher/interactive-loop.js +41 -33
- package/dist/infra/cipher/llm/capability-cache.d.ts +87 -0
- package/dist/infra/cipher/llm/capability-cache.js +125 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +32 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.js +44 -3
- package/dist/infra/cipher/llm/context/compression/enhanced-compaction.d.ts +112 -0
- package/dist/infra/cipher/llm/context/compression/enhanced-compaction.js +175 -0
- package/dist/infra/cipher/llm/context/compression/filter-compacted.d.ts +83 -0
- package/dist/infra/cipher/llm/context/compression/filter-compacted.js +150 -0
- package/dist/infra/cipher/llm/context/compression/index.d.ts +5 -0
- package/dist/infra/cipher/llm/context/compression/index.js +6 -0
- package/dist/infra/cipher/llm/context/compression/reactive-overflow.d.ts +107 -0
- package/dist/infra/cipher/llm/context/compression/reactive-overflow.js +272 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +47 -1
- package/dist/infra/cipher/llm/context/context-manager.js +129 -0
- package/dist/infra/cipher/llm/context/utils.js +17 -4
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +4 -2
- package/dist/infra/cipher/llm/internal-llm-service.d.ts +50 -17
- package/dist/infra/cipher/llm/internal-llm-service.js +273 -50
- package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +6 -8
- package/dist/infra/cipher/llm/openrouter-llm-service.js +14 -16
- package/dist/infra/cipher/llm/retry/retry-policy.d.ts +1 -0
- package/dist/infra/cipher/llm/retry/retry-policy.js +11 -0
- package/dist/infra/cipher/llm/retry/retry-with-backoff.js +3 -2
- package/dist/infra/cipher/llm/sanitization/base64-utils.d.ts +102 -0
- package/dist/infra/cipher/llm/sanitization/base64-utils.js +182 -0
- package/dist/infra/cipher/llm/sanitization/index.d.ts +12 -0
- package/dist/infra/cipher/llm/sanitization/index.js +13 -0
- package/dist/infra/cipher/llm/sanitization/tool-sanitizer.d.ts +74 -0
- package/dist/infra/cipher/llm/sanitization/tool-sanitizer.js +398 -0
- package/dist/infra/cipher/llm/stream-processor.d.ts +158 -0
- package/dist/infra/cipher/llm/stream-processor.js +276 -0
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +13 -20
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +17 -24
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +12 -11
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +16 -15
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +15 -7
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +22 -10
- package/dist/infra/cipher/llm/tool-output-processor.d.ts +51 -0
- package/dist/infra/cipher/llm/tool-output-processor.js +139 -0
- package/dist/infra/cipher/process/command-validator.d.ts +23 -0
- package/dist/infra/cipher/process/command-validator.js +75 -0
- package/dist/infra/cipher/process/path-utils.d.ts +66 -0
- package/dist/infra/cipher/process/path-utils.js +94 -0
- package/dist/infra/cipher/process/process-service.d.ts +32 -0
- package/dist/infra/cipher/process/process-service.js +98 -17
- package/dist/infra/cipher/session/chat-session.d.ts +56 -7
- package/dist/infra/cipher/session/chat-session.js +163 -13
- package/dist/infra/cipher/session/index.d.ts +1 -0
- package/dist/infra/cipher/session/index.js +2 -0
- package/dist/infra/cipher/session/message-queue.d.ts +65 -0
- package/dist/infra/cipher/session/message-queue.js +90 -0
- package/dist/infra/cipher/session/session-manager.d.ts +106 -5
- package/dist/infra/cipher/session/session-manager.js +254 -7
- package/dist/infra/cipher/session/session-status.d.ts +137 -0
- package/dist/infra/cipher/session/session-status.js +184 -0
- package/dist/infra/cipher/session/title-generator.d.ts +8 -0
- package/dist/infra/cipher/session/title-generator.js +31 -0
- package/dist/infra/cipher/storage/message-storage-service.d.ts +65 -2
- package/dist/infra/cipher/storage/message-storage-service.js +300 -54
- package/dist/infra/cipher/storage/tool-part-factory.d.ts +116 -0
- package/dist/infra/cipher/storage/tool-part-factory.js +197 -0
- package/dist/infra/cipher/system-prompt/contributor-schemas.d.ts +516 -0
- package/dist/infra/cipher/system-prompt/contributor-schemas.js +85 -0
- package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.d.ts +59 -0
- package/dist/infra/cipher/system-prompt/contributors/agent-prompt-contributor.js +131 -0
- package/dist/infra/cipher/system-prompt/contributors/companion-contributor.d.ts +54 -0
- package/dist/infra/cipher/system-prompt/contributors/companion-contributor.js +107 -0
- package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.d.ts +68 -0
- package/dist/infra/cipher/system-prompt/contributors/context-tree-structure-contributor.js +179 -0
- package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.d.ts +25 -0
- package/dist/infra/cipher/system-prompt/contributors/datetime-contributor.js +29 -0
- package/dist/infra/cipher/system-prompt/contributors/environment-contributor.d.ts +25 -0
- package/dist/infra/cipher/system-prompt/contributors/environment-contributor.js +54 -0
- package/dist/infra/cipher/system-prompt/contributors/file-contributor.d.ts +60 -0
- package/dist/infra/cipher/system-prompt/contributors/file-contributor.js +128 -0
- package/dist/infra/cipher/system-prompt/contributors/index.d.ts +13 -0
- package/dist/infra/cipher/system-prompt/contributors/index.js +8 -0
- package/dist/infra/cipher/system-prompt/contributors/memory-contributor.d.ts +40 -0
- package/dist/infra/cipher/system-prompt/contributors/memory-contributor.js +56 -0
- package/dist/infra/cipher/system-prompt/contributors/static-contributor.d.ts +26 -0
- package/dist/infra/cipher/system-prompt/contributors/static-contributor.js +31 -0
- package/dist/infra/cipher/system-prompt/environment-context-builder.d.ts +112 -0
- package/dist/infra/cipher/system-prompt/environment-context-builder.js +256 -0
- package/dist/infra/cipher/system-prompt/prompt-cache.d.ts +102 -0
- package/dist/infra/cipher/system-prompt/prompt-cache.js +156 -0
- package/dist/infra/cipher/system-prompt/schemas.d.ts +151 -0
- package/dist/infra/cipher/system-prompt/schemas.js +94 -0
- package/dist/infra/cipher/system-prompt/system-prompt-manager.d.ts +136 -0
- package/dist/infra/cipher/system-prompt/system-prompt-manager.js +307 -0
- package/dist/infra/cipher/todos/todo-storage-service.d.ts +26 -0
- package/dist/infra/cipher/todos/todo-storage-service.js +28 -0
- package/dist/infra/cipher/tools/core-tool-scheduler.js +5 -1
- package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +1 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +27 -10
- package/dist/infra/cipher/tools/implementations/bash-output-tool.js +1 -5
- package/dist/infra/cipher/tools/implementations/batch-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/batch-tool.js +142 -0
- package/dist/infra/cipher/tools/implementations/curate-tool.js +195 -68
- package/dist/infra/cipher/tools/implementations/list-directory-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/list-directory-tool.js +52 -0
- package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +8 -1
- package/dist/infra/cipher/tools/implementations/read-file-tool.js +17 -7
- package/dist/infra/cipher/tools/implementations/read-todos-tool.d.ts +11 -0
- package/dist/infra/cipher/tools/implementations/read-todos-tool.js +39 -0
- package/dist/infra/cipher/tools/implementations/{detect-domains-tool.d.ts → spec-analyze-tool.d.ts} +1 -1
- package/dist/infra/cipher/tools/implementations/{detect-domains-tool.js → spec-analyze-tool.js} +9 -7
- package/dist/infra/cipher/tools/implementations/task-tool.d.ts +34 -0
- package/dist/infra/cipher/tools/implementations/task-tool.js +207 -0
- package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +4 -1
- package/dist/infra/cipher/tools/implementations/write-todos-tool.js +19 -63
- package/dist/infra/cipher/tools/index.d.ts +1 -1
- package/dist/infra/cipher/tools/index.js +1 -1
- package/dist/infra/cipher/tools/plugins/index.d.ts +3 -0
- package/dist/infra/cipher/tools/plugins/index.js +2 -0
- package/dist/infra/cipher/tools/plugins/logging-plugin.d.ts +28 -0
- package/dist/infra/cipher/tools/plugins/logging-plugin.js +66 -0
- package/dist/infra/cipher/tools/plugins/plugin-manager.d.ts +81 -0
- package/dist/infra/cipher/tools/plugins/plugin-manager.js +122 -0
- package/dist/infra/cipher/tools/streaming/index.d.ts +1 -0
- package/dist/infra/cipher/tools/streaming/index.js +1 -0
- package/dist/infra/cipher/tools/streaming/metadata-handler.d.ts +31 -0
- package/dist/infra/cipher/tools/streaming/metadata-handler.js +39 -0
- package/dist/infra/cipher/tools/tool-description-loader.d.ts +57 -0
- package/dist/infra/cipher/tools/tool-description-loader.js +108 -0
- package/dist/infra/cipher/tools/tool-manager.d.ts +38 -4
- package/dist/infra/cipher/tools/tool-manager.js +107 -11
- package/dist/infra/cipher/tools/tool-provider-getter.d.ts +6 -0
- package/dist/infra/cipher/tools/tool-provider-getter.js +1 -0
- package/dist/infra/cipher/tools/tool-provider.d.ts +32 -7
- package/dist/infra/cipher/tools/tool-provider.js +81 -25
- package/dist/infra/cipher/tools/tool-registry.d.ts +23 -0
- package/dist/infra/cipher/tools/tool-registry.js +58 -16
- package/dist/infra/context-tree/file-context-tree-snapshot-service.js +10 -4
- package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +4 -3
- package/dist/infra/context-tree/file-context-tree-writer-service.js +6 -4
- package/dist/infra/context-tree/path-utils.d.ts +7 -0
- package/dist/infra/context-tree/path-utils.js +7 -0
- package/dist/infra/core/executors/curate-executor.d.ts +35 -0
- package/dist/infra/core/executors/curate-executor.js +123 -0
- package/dist/infra/core/executors/index.d.ts +2 -0
- package/dist/infra/core/executors/index.js +2 -0
- package/dist/infra/core/executors/query-executor.d.ts +23 -0
- package/dist/infra/core/executors/query-executor.js +51 -0
- package/dist/infra/core/task-processor.d.ts +81 -0
- package/dist/infra/core/task-processor.js +115 -0
- package/dist/infra/instance/file-instance-discovery.d.ts +31 -0
- package/dist/infra/instance/file-instance-discovery.js +84 -0
- package/dist/infra/instance/file-instance-manager.d.ts +46 -0
- package/dist/infra/instance/file-instance-manager.js +123 -0
- package/dist/infra/instance/index.d.ts +3 -0
- package/dist/infra/instance/index.js +3 -0
- package/dist/infra/instance/process-utils.d.ts +14 -0
- package/dist/infra/instance/process-utils.js +39 -0
- package/dist/infra/process/agent-worker.d.ts +20 -0
- package/dist/infra/process/agent-worker.js +602 -0
- package/dist/infra/process/index.d.ts +12 -0
- package/dist/infra/process/index.js +11 -0
- package/dist/infra/process/ipc-types.d.ts +55 -0
- package/dist/infra/process/ipc-types.js +12 -0
- package/dist/infra/process/process-manager.d.ts +154 -0
- package/dist/infra/process/process-manager.js +471 -0
- package/dist/infra/process/task-queue-manager.d.ts +123 -0
- package/dist/infra/process/task-queue-manager.js +226 -0
- package/dist/infra/process/transport-handlers.d.ts +124 -0
- package/dist/infra/process/transport-handlers.js +348 -0
- package/dist/infra/process/transport-worker.d.ts +20 -0
- package/dist/infra/process/transport-worker.js +168 -0
- package/dist/infra/repl/commands/curate-command.js +0 -5
- package/dist/infra/repl/commands/query-command.js +0 -3
- package/dist/infra/repl/repl-startup.d.ts +4 -0
- package/dist/infra/repl/repl-startup.js +10 -1
- package/dist/infra/repl/transport-client-helper.d.ts +9 -0
- package/dist/infra/repl/transport-client-helper.js +96 -0
- package/dist/infra/transport/index.d.ts +4 -0
- package/dist/infra/transport/index.js +4 -0
- package/dist/infra/transport/port-utils.d.ts +42 -0
- package/dist/infra/transport/port-utils.js +84 -0
- package/dist/infra/transport/socket-io-transport-client.d.ts +45 -0
- package/dist/infra/transport/socket-io-transport-client.js +270 -0
- package/dist/infra/transport/socket-io-transport-server.d.ts +35 -0
- package/dist/infra/transport/socket-io-transport-server.js +207 -0
- package/dist/infra/transport/transport-client-factory.d.ts +76 -0
- package/dist/infra/transport/transport-client-factory.js +168 -0
- package/dist/infra/transport/transport-factory.d.ts +33 -0
- package/dist/infra/transport/transport-factory.js +59 -0
- package/dist/infra/usecase/curate-use-case.d.ts +8 -55
- package/dist/infra/usecase/curate-use-case.js +73 -259
- package/dist/infra/usecase/init-use-case.js +19 -8
- package/dist/infra/usecase/login-use-case.js +9 -3
- package/dist/infra/usecase/query-use-case.d.ts +18 -45
- package/dist/infra/usecase/query-use-case.js +251 -326
- package/dist/infra/usecase/status-use-case.js +1 -1
- package/dist/resources/prompts/{curate-context-tree-curation.yml → curate.yml} +25 -22
- package/dist/resources/prompts/explore.yml +78 -0
- package/dist/resources/prompts/plan.yml +114 -0
- package/dist/resources/prompts/reflection.yml +1 -1
- package/dist/resources/prompts/system-prompt.yml +15 -8
- package/dist/resources/prompts/tool-outputs.yml +0 -5
- package/dist/resources/tools/bash_exec.txt +98 -0
- package/dist/resources/tools/bash_output.txt +40 -0
- package/dist/resources/tools/batch.txt +28 -0
- package/dist/resources/tools/create_knowledge_topic.txt +23 -0
- package/dist/resources/tools/curate.txt +22 -0
- package/dist/resources/tools/delete_memory.txt +1 -0
- package/dist/resources/tools/detect_domains.txt +11 -0
- package/dist/resources/tools/edit_file.txt +1 -0
- package/dist/resources/tools/edit_memory.txt +1 -0
- package/dist/resources/tools/glob_files.txt +20 -0
- package/dist/resources/tools/grep_content.txt +18 -0
- package/dist/resources/tools/kill_process.txt +16 -0
- package/dist/resources/tools/list_directory.txt +16 -0
- package/dist/resources/tools/list_memories.txt +1 -0
- package/dist/resources/tools/read_file.txt +31 -0
- package/dist/resources/tools/read_memory.txt +1 -0
- package/dist/resources/tools/read_todos.txt +17 -0
- package/dist/resources/tools/search_history.txt +1 -0
- package/dist/resources/tools/task.txt +23 -0
- package/dist/resources/tools/write_file.txt +1 -0
- package/dist/resources/tools/write_memory.txt +1 -0
- package/dist/resources/tools/write_todos.txt +29 -0
- package/dist/tui/app.js +9 -13
- package/dist/tui/components/command-details.d.ts +14 -0
- package/dist/tui/components/command-details.js +35 -0
- package/dist/tui/components/execution/execution-changes.d.ts +5 -0
- package/dist/tui/components/execution/execution-changes.js +19 -4
- package/dist/tui/components/execution/execution-content.d.ts +4 -2
- package/dist/tui/components/execution/execution-content.js +26 -13
- package/dist/tui/components/execution/execution-input.js +3 -3
- package/dist/tui/components/execution/execution-progress.d.ts +2 -2
- package/dist/tui/components/execution/execution-progress.js +8 -6
- package/dist/tui/components/execution/log-item.d.ts +3 -4
- package/dist/tui/components/execution/log-item.js +2 -5
- package/dist/tui/components/footer.js +9 -4
- package/dist/tui/components/header.d.ts +3 -3
- package/dist/tui/components/header.js +5 -3
- package/dist/tui/components/index.d.ts +1 -0
- package/dist/tui/components/index.js +1 -0
- package/dist/tui/components/onboarding/copyable-prompt.d.ts +5 -3
- package/dist/tui/components/onboarding/copyable-prompt.js +7 -8
- package/dist/tui/components/onboarding/onboarding-flow.js +35 -25
- package/dist/tui/components/scrollable-list.js +12 -10
- package/dist/tui/components/suggestions.js +39 -41
- package/dist/tui/components/tab-bar.d.ts +2 -1
- package/dist/tui/components/tab-bar.js +3 -4
- package/dist/tui/constants.d.ts +0 -5
- package/dist/tui/constants.js +0 -5
- package/dist/tui/contexts/auth-context.js +9 -2
- package/dist/tui/contexts/{use-commands.js → commands-context.js} +6 -5
- package/dist/tui/contexts/index.d.ts +6 -1
- package/dist/tui/contexts/index.js +6 -1
- package/dist/tui/contexts/onboarding-context.d.ts +1 -1
- package/dist/tui/contexts/onboarding-context.js +9 -9
- package/dist/tui/contexts/tasks-context.d.ts +84 -0
- package/dist/tui/contexts/tasks-context.js +218 -0
- package/dist/tui/contexts/transport-context.d.ts +29 -0
- package/dist/tui/contexts/transport-context.js +82 -0
- package/dist/tui/hooks/index.d.ts +10 -6
- package/dist/tui/hooks/index.js +7 -6
- package/dist/tui/hooks/use-activity-logs.d.ts +3 -11
- package/dist/tui/hooks/use-activity-logs.js +87 -34
- package/dist/tui/hooks/use-auth-polling.d.ts +24 -0
- package/dist/tui/hooks/use-auth-polling.js +104 -0
- package/dist/tui/hooks/use-slash-command-processor.js +0 -1
- package/dist/tui/hooks/use-slash-completion.js +1 -1
- package/dist/tui/hooks/use-tab-navigation.d.ts +2 -1
- package/dist/tui/hooks/use-tab-navigation.js +16 -7
- package/dist/tui/hooks/use-terminal-breakpoint.d.ts +21 -0
- package/dist/tui/hooks/use-terminal-breakpoint.js +38 -0
- package/dist/tui/hooks/use-ui-heights.d.ts +120 -0
- package/dist/tui/hooks/use-ui-heights.js +88 -0
- package/dist/tui/providers/app-providers.js +2 -6
- package/dist/tui/types/commands.d.ts +0 -26
- package/dist/tui/types/index.d.ts +1 -1
- package/dist/tui/types/ui.d.ts +9 -4
- package/dist/tui/utils/line.d.ts +11 -0
- package/dist/tui/utils/line.js +16 -0
- package/dist/tui/utils/log.d.ts +27 -0
- package/dist/tui/utils/log.js +114 -0
- package/dist/tui/views/command-view.d.ts +7 -0
- package/dist/tui/views/command-view.js +103 -80
- package/dist/tui/views/login-view.js +7 -4
- package/dist/tui/views/logs-view.d.ts +13 -0
- package/dist/tui/views/logs-view.js +27 -52
- package/dist/utils/connection-error-handler.d.ts +16 -0
- package/dist/utils/connection-error-handler.js +49 -0
- package/dist/utils/crash-log.d.ts +14 -0
- package/dist/utils/crash-log.js +19 -0
- package/dist/utils/file-helpers.d.ts +14 -0
- package/dist/utils/file-helpers.js +21 -0
- package/dist/utils/global-logs-path.d.ts +11 -0
- package/dist/utils/global-logs-path.js +37 -0
- package/dist/utils/process-logger.d.ts +53 -0
- package/dist/utils/process-logger.js +253 -0
- package/dist/utils/sandbox-detector.d.ts +31 -0
- package/dist/utils/sandbox-detector.js +122 -0
- package/oclif.manifest.json +10 -198
- package/package.json +5 -1
- package/dist/commands/cipher-agent/run.d.ts +0 -142
- package/dist/commands/cipher-agent/run.js +0 -555
- package/dist/commands/cipher-agent/set-prompt.d.ts +0 -16
- package/dist/commands/cipher-agent/set-prompt.js +0 -58
- package/dist/commands/cipher-agent/show-prompt.d.ts +0 -13
- package/dist/commands/cipher-agent/show-prompt.js +0 -53
- package/dist/commands/foo.d.ts +0 -14
- package/dist/commands/foo.js +0 -66
- package/dist/infra/cipher/agent-service-factory.d.ts +0 -93
- package/dist/infra/cipher/cipher-agent-state-manager.d.ts +0 -63
- package/dist/infra/cipher/cipher-agent-state-manager.js +0 -108
- package/dist/infra/cipher/cipher-agent.d.ts +0 -182
- package/dist/infra/cipher/cipher-agent.js +0 -317
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +0 -106
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +0 -297
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +0 -7
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +0 -424
- package/dist/resources/prompts/modes/autonomous.yml +0 -9
- package/dist/resources/prompts/query-context-tree-retrieval.yml +0 -48
- package/dist/tui/contexts/consumer.d.ts +0 -31
- package/dist/tui/contexts/consumer.js +0 -56
- package/dist/tui/hooks/use-consumer.d.ts +0 -12
- package/dist/tui/hooks/use-consumer.js +0 -50
- package/dist/tui/hooks/use-queue-polling.d.ts +0 -31
- package/dist/tui/hooks/use-queue-polling.js +0 -90
- /package/dist/tui/contexts/{use-commands.d.ts → commands-context.d.ts} +0 -0
- /package/dist/tui/contexts/{use-mode.d.ts → mode-context.d.ts} +0 -0
- /package/dist/tui/contexts/{use-mode.js → mode-context.js} +0 -0
- /package/dist/tui/contexts/{use-theme.d.ts → theme-context.d.ts} +0 -0
- /package/dist/tui/contexts/{use-theme.js → theme-context.js} +0 -0
|
@@ -3,6 +3,7 @@ import { randomBytes } from 'node:crypto';
|
|
|
3
3
|
import { isAbsolute, relative, resolve } from 'node:path';
|
|
4
4
|
import { ProcessError } from '../../../core/domain/cipher/errors/process-error.js';
|
|
5
5
|
import { CommandValidator } from './command-validator.js';
|
|
6
|
+
import { normalizePath } from './path-utils.js';
|
|
6
7
|
/**
|
|
7
8
|
* Default timeout for foreground commands (milliseconds).
|
|
8
9
|
*/
|
|
@@ -97,6 +98,8 @@ export class ProcessService {
|
|
|
97
98
|
}
|
|
98
99
|
// Resolve working directory
|
|
99
100
|
const cwd = this.resolveSafeCwd(options.cwd);
|
|
101
|
+
// Validate path arguments in the command
|
|
102
|
+
this.validatePathArguments(normalizedCommand, cwd);
|
|
100
103
|
// Merge environment variables
|
|
101
104
|
const env = {};
|
|
102
105
|
for (const [key, value] of Object.entries({
|
|
@@ -168,6 +171,8 @@ export class ProcessService {
|
|
|
168
171
|
/**
|
|
169
172
|
* Terminate a background process.
|
|
170
173
|
*
|
|
174
|
+
* Uses process tree killing to ensure all child processes are terminated.
|
|
175
|
+
*
|
|
171
176
|
* @param processId - Unique process identifier
|
|
172
177
|
*/
|
|
173
178
|
async killProcess(processId) {
|
|
@@ -180,14 +185,8 @@ export class ProcessService {
|
|
|
180
185
|
return;
|
|
181
186
|
}
|
|
182
187
|
try {
|
|
183
|
-
//
|
|
184
|
-
bgProcess.child.
|
|
185
|
-
// Wait 5 seconds, then escalate to SIGKILL
|
|
186
|
-
setTimeout(() => {
|
|
187
|
-
if (bgProcess.child.exitCode === null) {
|
|
188
|
-
bgProcess.child.kill('SIGKILL');
|
|
189
|
-
}
|
|
190
|
-
}, 5000);
|
|
188
|
+
// Kill the entire process tree
|
|
189
|
+
await this.killProcessTree(bgProcess.child, bgProcess.child.pid);
|
|
191
190
|
}
|
|
192
191
|
catch (error) {
|
|
193
192
|
throw ProcessError.killFailed(processId, error instanceof Error ? error.message : String(error));
|
|
@@ -320,12 +319,17 @@ export class ProcessService {
|
|
|
320
319
|
truncated: false,
|
|
321
320
|
};
|
|
322
321
|
// Spawn process
|
|
322
|
+
// Use detached: true on Unix to create a process group for tree killing
|
|
323
323
|
const child = spawn(command, {
|
|
324
324
|
cwd: options.cwd,
|
|
325
|
-
detached:
|
|
325
|
+
detached: process.platform !== 'win32',
|
|
326
326
|
env: options.env,
|
|
327
327
|
shell: true,
|
|
328
328
|
});
|
|
329
|
+
// Prevent child from keeping parent alive on Unix
|
|
330
|
+
if (process.platform !== 'win32') {
|
|
331
|
+
child.unref();
|
|
332
|
+
}
|
|
329
333
|
const startedAt = new Date();
|
|
330
334
|
// Create background process entry
|
|
331
335
|
const bgProcess = {
|
|
@@ -389,13 +393,10 @@ export class ProcessService {
|
|
|
389
393
|
// Set timeout handler
|
|
390
394
|
const killTimer = setTimeout(() => {
|
|
391
395
|
if (bgProcess.status === 'running') {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
child.kill('SIGKILL');
|
|
397
|
-
}
|
|
398
|
-
}, 5000);
|
|
396
|
+
// Use process tree killing for timeout
|
|
397
|
+
this.killProcessTree(child, child.pid).catch(() => {
|
|
398
|
+
// Ignore errors during timeout kill - process may already be dead
|
|
399
|
+
});
|
|
399
400
|
}
|
|
400
401
|
}, options.timeout);
|
|
401
402
|
// Clear timeout when process completes
|
|
@@ -411,6 +412,50 @@ export class ProcessService {
|
|
|
411
412
|
startedAt,
|
|
412
413
|
};
|
|
413
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Kill a process and all its children (process tree).
|
|
417
|
+
*
|
|
418
|
+
* On Unix, uses process groups (-pid) to kill all descendants.
|
|
419
|
+
* On Windows, uses taskkill with /t flag for tree kill.
|
|
420
|
+
* Falls back to direct kill if process group kill fails.
|
|
421
|
+
*
|
|
422
|
+
* @param child - Child process to kill
|
|
423
|
+
* @param pid - Process ID (optional, extracted from child if not provided)
|
|
424
|
+
* @returns Promise that resolves when kill attempt completes
|
|
425
|
+
*/
|
|
426
|
+
async killProcessTree(child, pid) {
|
|
427
|
+
const targetPid = pid ?? child.pid;
|
|
428
|
+
if (!targetPid)
|
|
429
|
+
return;
|
|
430
|
+
if (process.platform === 'win32') {
|
|
431
|
+
// Use taskkill with /t flag for tree kill on Windows
|
|
432
|
+
return new Promise((resolve) => {
|
|
433
|
+
const killer = spawn('taskkill', ['/pid', String(targetPid), '/f', '/t'], { stdio: 'ignore' });
|
|
434
|
+
killer.once('exit', () => resolve());
|
|
435
|
+
killer.once('error', () => resolve());
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
// Unix: kill process group using negative PID
|
|
439
|
+
try {
|
|
440
|
+
process.kill(-targetPid, 'SIGTERM');
|
|
441
|
+
await this.sleep(5000);
|
|
442
|
+
try {
|
|
443
|
+
process.kill(-targetPid, 'SIGKILL');
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
// Process already dead, ignore
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
// Fallback to direct kill if process group kill fails
|
|
451
|
+
// (e.g., process wasn't started with detached: true)
|
|
452
|
+
child.kill('SIGTERM');
|
|
453
|
+
await this.sleep(5000);
|
|
454
|
+
if (child.exitCode === null) {
|
|
455
|
+
child.kill('SIGKILL');
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
414
459
|
/**
|
|
415
460
|
* Resolve and validate working directory.
|
|
416
461
|
*
|
|
@@ -426,8 +471,10 @@ export class ProcessService {
|
|
|
426
471
|
if (!cwd) {
|
|
427
472
|
return baseDir;
|
|
428
473
|
}
|
|
474
|
+
// Normalize for Git Bash on Windows
|
|
475
|
+
const normalizedCwd = normalizePath(cwd);
|
|
429
476
|
// Resolve to absolute path
|
|
430
|
-
const candidatePath = isAbsolute(
|
|
477
|
+
const candidatePath = isAbsolute(normalizedCwd) ? resolve(normalizedCwd) : resolve(baseDir, normalizedCwd);
|
|
431
478
|
// Check if path is within base directory
|
|
432
479
|
const relativePath = relative(baseDir, candidatePath);
|
|
433
480
|
const isOutsideBase = relativePath.startsWith('..') || isAbsolute(relativePath);
|
|
@@ -436,4 +483,38 @@ export class ProcessService {
|
|
|
436
483
|
}
|
|
437
484
|
return candidatePath;
|
|
438
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Sleep for specified milliseconds.
|
|
488
|
+
*
|
|
489
|
+
* @param ms - Milliseconds to sleep
|
|
490
|
+
* @returns Promise that resolves after the delay
|
|
491
|
+
*/
|
|
492
|
+
sleep(ms) {
|
|
493
|
+
return new Promise((resolve) => {
|
|
494
|
+
setTimeout(resolve, ms);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Validate file path arguments in a command.
|
|
499
|
+
*
|
|
500
|
+
* Extracts path arguments from path-sensitive commands and validates
|
|
501
|
+
* that they are within the configured base directory.
|
|
502
|
+
*
|
|
503
|
+
* @param command - Command string to validate
|
|
504
|
+
* @param baseDir - Base directory for confinement
|
|
505
|
+
* @throws ProcessError if any path argument is outside the base directory
|
|
506
|
+
*/
|
|
507
|
+
validatePathArguments(command, baseDir) {
|
|
508
|
+
const paths = this.commandValidator.extractPathArguments(command);
|
|
509
|
+
for (const pathArg of paths) {
|
|
510
|
+
// Resolve to absolute path
|
|
511
|
+
const resolved = isAbsolute(pathArg) ? resolve(pathArg) : resolve(baseDir, pathArg);
|
|
512
|
+
// Check if path is within base directory
|
|
513
|
+
const relativePath = relative(baseDir, resolved);
|
|
514
|
+
const isOutsideBase = relativePath.startsWith('..') || isAbsolute(relativePath);
|
|
515
|
+
if (isOutsideBase) {
|
|
516
|
+
throw ProcessError.invalidWorkingDirectory(pathArg, `Path argument "${pathArg}" references location outside ${baseDir}`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
439
520
|
}
|
|
@@ -3,11 +3,10 @@ import type { CipherAgentServices, SessionServices } from '../../../core/interfa
|
|
|
3
3
|
import type { IChatSession } from '../../../core/interfaces/cipher/i-chat-session.js';
|
|
4
4
|
import type { ExecutionContext } from '../../../core/interfaces/cipher/i-cipher-agent.js';
|
|
5
5
|
import type { ILLMService } from '../../../core/interfaces/cipher/i-llm-service.js';
|
|
6
|
+
import type { FileData, ImageData } from '../llm/context/context-manager.js';
|
|
6
7
|
import { SessionEventBus } from '../events/event-emitter.js';
|
|
7
8
|
/**
|
|
8
9
|
* Chat session implementation.
|
|
9
|
-
*
|
|
10
|
-
* Following Dexto's pattern: ChatSession owns session-specific services
|
|
11
10
|
* (LLM, EventBus) and receives shared services (ToolManager, SystemPromptManager).
|
|
12
11
|
*
|
|
13
12
|
* The LLM service handles:
|
|
@@ -25,8 +24,11 @@ export declare class ChatSession implements IChatSession {
|
|
|
25
24
|
readonly eventBus: SessionEventBus;
|
|
26
25
|
readonly id: string;
|
|
27
26
|
private currentController?;
|
|
27
|
+
private currentTaskId?;
|
|
28
28
|
private readonly forwarders;
|
|
29
|
+
private isExecuting;
|
|
29
30
|
private readonly llmService;
|
|
31
|
+
private readonly messageQueue;
|
|
30
32
|
private readonly sharedServices;
|
|
31
33
|
/**
|
|
32
34
|
* Creates a new chat session
|
|
@@ -41,7 +43,14 @@ export declare class ChatSession implements IChatSession {
|
|
|
41
43
|
*/
|
|
42
44
|
cancel(): void;
|
|
43
45
|
/**
|
|
44
|
-
*
|
|
46
|
+
* Cleanup session resources but preserve history for later restoration.
|
|
47
|
+
* Call this when ending a session temporarily (e.g., user navigates away).
|
|
48
|
+
* History remains in ContextManager for persistence; event listeners stay for potential reactivation.
|
|
49
|
+
*/
|
|
50
|
+
cleanup(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Dispose of the session completely - remove all event listeners.
|
|
53
|
+
* Call this when permanently destroying a session.
|
|
45
54
|
* Removes event listeners to prevent memory leaks.
|
|
46
55
|
*/
|
|
47
56
|
dispose(): void;
|
|
@@ -65,16 +74,56 @@ export declare class ChatSession implements IChatSession {
|
|
|
65
74
|
/**
|
|
66
75
|
* Send a message and get a response.
|
|
67
76
|
* Delegates to the LLM service which handles the agentic loop.
|
|
77
|
+
* Processes any queued messages first if present.
|
|
78
|
+
*
|
|
79
|
+
* @param input - User message
|
|
80
|
+
* @param options - Execution options
|
|
81
|
+
* @param options.executionContext - Optional execution context
|
|
82
|
+
* @param options.taskId - Optional task ID for concurrent task isolation
|
|
68
83
|
*/
|
|
69
84
|
run(input: string, options?: {
|
|
70
85
|
executionContext?: ExecutionContext;
|
|
71
|
-
|
|
86
|
+
taskId?: string;
|
|
72
87
|
}): Promise<string>;
|
|
73
88
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
89
|
+
* Send a message, queuing if the session is busy executing.
|
|
90
|
+
* If the session is idle, executes immediately via run().
|
|
91
|
+
* If the session is busy, queues the message and returns the queue position.
|
|
76
92
|
*
|
|
77
|
-
*
|
|
93
|
+
* @param input - User message content
|
|
94
|
+
* @param options - Optional execution options and attachments
|
|
95
|
+
* @param options.executionContext - Optional execution context for the LLM
|
|
96
|
+
* @param options.fileData - Optional file attachment
|
|
97
|
+
* @param options.imageData - Optional image attachment
|
|
98
|
+
* @returns Response string if executed, or queue info if queued
|
|
99
|
+
*/
|
|
100
|
+
sendMessage(input: string, options?: {
|
|
101
|
+
executionContext?: ExecutionContext;
|
|
102
|
+
fileData?: FileData;
|
|
103
|
+
imageData?: ImageData;
|
|
104
|
+
}): Promise<string | {
|
|
105
|
+
position: number;
|
|
106
|
+
queued: true;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Stream execution with real-time event emission.
|
|
110
|
+
* Unlike run(), this does not return a response directly - events are yielded via the agent's stream().
|
|
111
|
+
* Emits run:complete event when finished.
|
|
112
|
+
*
|
|
113
|
+
* @param input - User message
|
|
114
|
+
* @param options - Execution options with optional signal for cancellation
|
|
115
|
+
* @param options.executionContext - Optional execution context for the LLM
|
|
116
|
+
* @param options.signal - Optional AbortSignal for cancellation
|
|
117
|
+
* @param options.taskId - Optional task ID for concurrent task isolation
|
|
118
|
+
*/
|
|
119
|
+
streamRun(input: string, options?: {
|
|
120
|
+
executionContext?: ExecutionContext;
|
|
121
|
+
signal?: AbortSignal;
|
|
122
|
+
taskId?: string;
|
|
123
|
+
}): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Setup automatic event forwarding from SessionEventBus to AgentEventBus.
|
|
126
|
+
* All session events are forwarded with sessionId and taskId added to the payload.
|
|
78
127
|
*/
|
|
79
128
|
private setupEventForwarding;
|
|
80
129
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { LLMError, SessionCancelledError } from '../../../core/domain/cipher/errors/session-error.js';
|
|
2
|
+
import { MessageQueueService } from './message-queue.js';
|
|
3
|
+
import { sessionStatusManager } from './session-status.js';
|
|
2
4
|
// List of all session events that should be forwarded to agent bus
|
|
3
5
|
const SESSION_EVENT_NAMES = [
|
|
4
6
|
'llmservice:thinking',
|
|
@@ -6,13 +8,18 @@ const SESSION_EVENT_NAMES = [
|
|
|
6
8
|
'llmservice:response',
|
|
7
9
|
'llmservice:toolCall',
|
|
8
10
|
'llmservice:toolResult',
|
|
11
|
+
'llmservice:doomLoopDetected',
|
|
9
12
|
'llmservice:error',
|
|
10
13
|
'llmservice:unsupportedInput',
|
|
14
|
+
'message:queued',
|
|
15
|
+
'message:dequeued',
|
|
16
|
+
'run:complete',
|
|
17
|
+
'session:statusChanged',
|
|
18
|
+
'step:started',
|
|
19
|
+
'step:finished',
|
|
11
20
|
];
|
|
12
21
|
/**
|
|
13
22
|
* Chat session implementation.
|
|
14
|
-
*
|
|
15
|
-
* Following Dexto's pattern: ChatSession owns session-specific services
|
|
16
23
|
* (LLM, EventBus) and receives shared services (ToolManager, SystemPromptManager).
|
|
17
24
|
*
|
|
18
25
|
* The LLM service handles:
|
|
@@ -30,8 +37,11 @@ export class ChatSession {
|
|
|
30
37
|
eventBus;
|
|
31
38
|
id;
|
|
32
39
|
currentController;
|
|
40
|
+
currentTaskId;
|
|
33
41
|
forwarders = new Map();
|
|
42
|
+
isExecuting = false;
|
|
34
43
|
llmService;
|
|
44
|
+
messageQueue;
|
|
35
45
|
sharedServices;
|
|
36
46
|
/**
|
|
37
47
|
* Creates a new chat session
|
|
@@ -45,6 +55,7 @@ export class ChatSession {
|
|
|
45
55
|
this.sharedServices = sharedServices;
|
|
46
56
|
this.eventBus = sessionServices.sessionEventBus;
|
|
47
57
|
this.llmService = sessionServices.llmService;
|
|
58
|
+
this.messageQueue = new MessageQueueService(sessionServices.sessionEventBus);
|
|
48
59
|
// Setup event forwarding from session bus to agent bus
|
|
49
60
|
this.setupEventForwarding();
|
|
50
61
|
}
|
|
@@ -57,15 +68,34 @@ export class ChatSession {
|
|
|
57
68
|
}
|
|
58
69
|
}
|
|
59
70
|
/**
|
|
60
|
-
*
|
|
71
|
+
* Cleanup session resources but preserve history for later restoration.
|
|
72
|
+
* Call this when ending a session temporarily (e.g., user navigates away).
|
|
73
|
+
* History remains in ContextManager for persistence; event listeners stay for potential reactivation.
|
|
74
|
+
*/
|
|
75
|
+
cleanup() {
|
|
76
|
+
// Cancel any in-flight operation
|
|
77
|
+
if (this.currentController) {
|
|
78
|
+
this.currentController.abort();
|
|
79
|
+
this.currentController = undefined;
|
|
80
|
+
}
|
|
81
|
+
// Note: History remains in LLMService's ContextManager for persistence
|
|
82
|
+
// Event listeners remain for potential reactivation
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Dispose of the session completely - remove all event listeners.
|
|
86
|
+
* Call this when permanently destroying a session.
|
|
61
87
|
* Removes event listeners to prevent memory leaks.
|
|
62
88
|
*/
|
|
63
89
|
dispose() {
|
|
90
|
+
// First cleanup any in-flight operations
|
|
91
|
+
this.cleanup();
|
|
64
92
|
// Remove all event forwarders
|
|
65
93
|
for (const [eventName, forwarder] of this.forwarders.entries()) {
|
|
66
94
|
this.eventBus.off(eventName, forwarder);
|
|
67
95
|
}
|
|
68
96
|
this.forwarders.clear();
|
|
97
|
+
// Clean up session status
|
|
98
|
+
sessionStatusManager.remove(this.id);
|
|
69
99
|
}
|
|
70
100
|
/**
|
|
71
101
|
* Get the conversation history.
|
|
@@ -116,22 +146,40 @@ export class ChatSession {
|
|
|
116
146
|
/**
|
|
117
147
|
* Send a message and get a response.
|
|
118
148
|
* Delegates to the LLM service which handles the agentic loop.
|
|
149
|
+
* Processes any queued messages first if present.
|
|
150
|
+
*
|
|
151
|
+
* @param input - User message
|
|
152
|
+
* @param options - Execution options
|
|
153
|
+
* @param options.executionContext - Optional execution context
|
|
154
|
+
* @param options.taskId - Optional task ID for concurrent task isolation
|
|
119
155
|
*/
|
|
120
156
|
async run(input, options) {
|
|
121
157
|
// Create abort controller for cancellation
|
|
122
158
|
this.currentController = new AbortController();
|
|
159
|
+
this.isExecuting = true;
|
|
160
|
+
// Store taskId for event forwarding
|
|
161
|
+
this.currentTaskId = options?.taskId;
|
|
162
|
+
// Update session status to busy
|
|
163
|
+
sessionStatusManager.setBusy(this.id, this.eventBus);
|
|
164
|
+
// Store reference to controller for use in catch/finally blocks
|
|
165
|
+
// This prevents race conditions where currentController might be undefined
|
|
166
|
+
const controller = this.currentController;
|
|
123
167
|
try {
|
|
168
|
+
// Process any queued messages first, coalescing with current input
|
|
169
|
+
const queued = this.messageQueue.dequeueAll();
|
|
170
|
+
const finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
|
|
124
171
|
// Delegate to service - it handles everything
|
|
125
|
-
|
|
172
|
+
// Pass taskId for billing tracking
|
|
173
|
+
const response = await this.llmService.completeTask(finalInput, {
|
|
126
174
|
executionContext: options?.executionContext,
|
|
127
|
-
|
|
128
|
-
|
|
175
|
+
signal: controller.signal,
|
|
176
|
+
taskId: options?.taskId,
|
|
129
177
|
});
|
|
130
178
|
return response;
|
|
131
179
|
}
|
|
132
180
|
catch (error) {
|
|
133
|
-
// Check if cancelled
|
|
134
|
-
if (
|
|
181
|
+
// Check if cancelled - use stored controller reference to avoid undefined access
|
|
182
|
+
if (controller.signal.aborted) {
|
|
135
183
|
throw new SessionCancelledError(this.id);
|
|
136
184
|
}
|
|
137
185
|
// Wrap other errors - pass message as-is since it's already formatted
|
|
@@ -139,20 +187,122 @@ export class ChatSession {
|
|
|
139
187
|
throw new LLMError(errorMessage, this.id);
|
|
140
188
|
}
|
|
141
189
|
finally {
|
|
190
|
+
this.isExecuting = false;
|
|
142
191
|
this.currentController = undefined;
|
|
192
|
+
this.currentTaskId = undefined;
|
|
193
|
+
// Update session status back to idle
|
|
194
|
+
sessionStatusManager.setIdle(this.id, this.eventBus);
|
|
143
195
|
}
|
|
144
196
|
}
|
|
145
197
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
198
|
+
* Send a message, queuing if the session is busy executing.
|
|
199
|
+
* If the session is idle, executes immediately via run().
|
|
200
|
+
* If the session is busy, queues the message and returns the queue position.
|
|
201
|
+
*
|
|
202
|
+
* @param input - User message content
|
|
203
|
+
* @param options - Optional execution options and attachments
|
|
204
|
+
* @param options.executionContext - Optional execution context for the LLM
|
|
205
|
+
* @param options.fileData - Optional file attachment
|
|
206
|
+
* @param options.imageData - Optional image attachment
|
|
207
|
+
* @returns Response string if executed, or queue info if queued
|
|
208
|
+
*/
|
|
209
|
+
async sendMessage(input, options) {
|
|
210
|
+
if (this.isExecuting) {
|
|
211
|
+
// Queue the message for later processing
|
|
212
|
+
const position = this.messageQueue.enqueue({
|
|
213
|
+
content: input,
|
|
214
|
+
fileData: options?.fileData,
|
|
215
|
+
imageData: options?.imageData,
|
|
216
|
+
});
|
|
217
|
+
return { position, queued: true };
|
|
218
|
+
}
|
|
219
|
+
// Execute immediately
|
|
220
|
+
return this.run(input, { executionContext: options?.executionContext });
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Stream execution with real-time event emission.
|
|
224
|
+
* Unlike run(), this does not return a response directly - events are yielded via the agent's stream().
|
|
225
|
+
* Emits run:complete event when finished.
|
|
148
226
|
*
|
|
149
|
-
*
|
|
227
|
+
* @param input - User message
|
|
228
|
+
* @param options - Execution options with optional signal for cancellation
|
|
229
|
+
* @param options.executionContext - Optional execution context for the LLM
|
|
230
|
+
* @param options.signal - Optional AbortSignal for cancellation
|
|
231
|
+
* @param options.taskId - Optional task ID for concurrent task isolation
|
|
232
|
+
*/
|
|
233
|
+
async streamRun(input, options) {
|
|
234
|
+
const startTime = Date.now();
|
|
235
|
+
let finishReason = 'stop';
|
|
236
|
+
let error;
|
|
237
|
+
// Create abort controller for cancellation
|
|
238
|
+
this.currentController = new AbortController();
|
|
239
|
+
this.isExecuting = true;
|
|
240
|
+
// Store taskId for event forwarding
|
|
241
|
+
this.currentTaskId = options?.taskId;
|
|
242
|
+
// Update session status to busy
|
|
243
|
+
sessionStatusManager.setBusy(this.id, this.eventBus);
|
|
244
|
+
// Store reference to controller for use in catch/finally blocks
|
|
245
|
+
// This prevents race conditions where currentController might be undefined
|
|
246
|
+
const controller = this.currentController;
|
|
247
|
+
// Link external signal if provided (use {once: true} to prevent listener accumulation)
|
|
248
|
+
if (options?.signal) {
|
|
249
|
+
options.signal.addEventListener('abort', () => controller?.abort(), { once: true });
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
// Process any queued messages first, coalescing with current input
|
|
253
|
+
const queued = this.messageQueue.dequeueAll();
|
|
254
|
+
const finalInput = queued ? `${queued.content}\n\nAlso: ${input}` : input;
|
|
255
|
+
// Delegate to service - it handles everything and emits events
|
|
256
|
+
// Pass taskId for billing tracking
|
|
257
|
+
await this.llmService.completeTask(finalInput, {
|
|
258
|
+
executionContext: options?.executionContext,
|
|
259
|
+
signal: controller.signal,
|
|
260
|
+
taskId: options?.taskId,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch (error_) {
|
|
264
|
+
// Check if cancelled - use stored controller reference to avoid undefined access
|
|
265
|
+
if (controller.signal.aborted) {
|
|
266
|
+
finishReason = 'cancelled';
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
finishReason = 'error';
|
|
270
|
+
error = error_ instanceof Error ? error_ : new Error(String(error_));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
this.isExecuting = false;
|
|
275
|
+
this.currentController = undefined;
|
|
276
|
+
// Save taskId before clearing for run:complete event
|
|
277
|
+
const completedTaskId = this.currentTaskId;
|
|
278
|
+
this.currentTaskId = undefined;
|
|
279
|
+
// Update session status back to idle
|
|
280
|
+
sessionStatusManager.setIdle(this.id, this.eventBus);
|
|
281
|
+
// Emit run:complete event with taskId for billing tracking
|
|
282
|
+
const durationMs = Date.now() - startTime;
|
|
283
|
+
this.eventBus.emit('run:complete', {
|
|
284
|
+
durationMs,
|
|
285
|
+
error,
|
|
286
|
+
finishReason,
|
|
287
|
+
stepCount: 0, // Can be enhanced later to track actual step count
|
|
288
|
+
...(completedTaskId && { taskId: completedTaskId }),
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Setup automatic event forwarding from SessionEventBus to AgentEventBus.
|
|
294
|
+
* All session events are forwarded with sessionId and taskId added to the payload.
|
|
150
295
|
*/
|
|
151
296
|
setupEventForwarding() {
|
|
152
297
|
for (const eventName of SESSION_EVENT_NAMES) {
|
|
153
298
|
const forwarder = (payload) => {
|
|
154
|
-
// Add sessionId to payload
|
|
155
|
-
const
|
|
299
|
+
// Add sessionId and taskId to payload
|
|
300
|
+
const basePayload = payload && typeof payload === 'object' ? payload : {};
|
|
301
|
+
const payloadWithSession = {
|
|
302
|
+
...basePayload,
|
|
303
|
+
sessionId: this.id,
|
|
304
|
+
...(this.currentTaskId && { taskId: this.currentTaskId }),
|
|
305
|
+
};
|
|
156
306
|
// Forward to agent bus - eventName is properly typed from SESSION_EVENT_NAMES
|
|
157
307
|
this.sharedServices.agentEventBus.emit(eventName, payloadWithSession);
|
|
158
308
|
};
|
|
@@ -4,3 +4,4 @@ export type { IChatSession } from '../../../core/interfaces/cipher/i-chat-sessio
|
|
|
4
4
|
export type { ILLMService } from '../../../core/interfaces/cipher/i-llm-service.js';
|
|
5
5
|
export { ChatSession } from './chat-session.js';
|
|
6
6
|
export { SessionManager } from './session-manager.js';
|
|
7
|
+
export { SessionStatusManager, sessionStatusManager } from './session-status.js';
|
|
@@ -3,3 +3,5 @@ export { LLMError, MaxIterationsExceededError, SessionCancelledError, SessionErr
|
|
|
3
3
|
export { ChatSession } from './chat-session.js';
|
|
4
4
|
// Session manager
|
|
5
5
|
export { SessionManager } from './session-manager.js';
|
|
6
|
+
// Session status
|
|
7
|
+
export { SessionStatusManager, sessionStatusManager } from './session-status.js';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SessionEventBus } from '../events/event-emitter.js';
|
|
2
|
+
import type { FileData, ImageData } from '../llm/context/context-manager.js';
|
|
3
|
+
/**
|
|
4
|
+
* A message that has been queued for later processing.
|
|
5
|
+
*/
|
|
6
|
+
export interface QueuedMessage {
|
|
7
|
+
/** Message text content */
|
|
8
|
+
content: string;
|
|
9
|
+
/** Optional file attachment */
|
|
10
|
+
fileData?: FileData;
|
|
11
|
+
/** Unique identifier for this queued message */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Optional image attachment */
|
|
14
|
+
imageData?: ImageData;
|
|
15
|
+
/** Timestamp when the message was queued */
|
|
16
|
+
queuedAt: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Service for buffering user messages when a session is busy executing.
|
|
20
|
+
*
|
|
21
|
+
* When the LLM is processing a request, new messages from the user are
|
|
22
|
+
* queued and coalesced into a single input when the session becomes available.
|
|
23
|
+
*
|
|
24
|
+
* This improves UX by allowing users to add context while waiting for responses.
|
|
25
|
+
*/
|
|
26
|
+
export declare class MessageQueueService {
|
|
27
|
+
private readonly eventBus?;
|
|
28
|
+
private readonly queue;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new message queue service.
|
|
31
|
+
*
|
|
32
|
+
* @param eventBus - Optional session event bus for queue events
|
|
33
|
+
*/
|
|
34
|
+
constructor(eventBus?: SessionEventBus);
|
|
35
|
+
/**
|
|
36
|
+
* Clear all queued messages without processing.
|
|
37
|
+
*/
|
|
38
|
+
clear(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Dequeue all messages and coalesce into single input.
|
|
41
|
+
* Messages are combined intelligently based on count.
|
|
42
|
+
*
|
|
43
|
+
* @returns Coalesced content with images/files, or null if queue is empty
|
|
44
|
+
*/
|
|
45
|
+
dequeueAll(): null | {
|
|
46
|
+
content: string;
|
|
47
|
+
files: FileData[];
|
|
48
|
+
images: ImageData[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Queue a message for later processing.
|
|
52
|
+
*
|
|
53
|
+
* @param message - Message to queue (without id and queuedAt)
|
|
54
|
+
* @returns Queue position (1-based)
|
|
55
|
+
*/
|
|
56
|
+
enqueue(message: Omit<QueuedMessage, 'id' | 'queuedAt'>): number;
|
|
57
|
+
/**
|
|
58
|
+
* Check if there are pending messages in the queue.
|
|
59
|
+
*/
|
|
60
|
+
hasPending(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Get the number of pending messages.
|
|
63
|
+
*/
|
|
64
|
+
pendingCount(): number;
|
|
65
|
+
}
|