byterover-cli 0.2.1 → 0.3.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 +56 -56
- package/bin/dev.js +1 -1
- package/dist/commands/cipher-agent/run.d.ts +111 -0
- package/dist/commands/cipher-agent/run.js +493 -0
- package/dist/commands/cipher-agent/set-prompt.d.ts +14 -0
- package/dist/commands/cipher-agent/set-prompt.js +53 -0
- package/dist/commands/cipher-agent/show-prompt.d.ts +11 -0
- package/dist/commands/cipher-agent/show-prompt.js +48 -0
- package/dist/commands/clear.d.ts +6 -0
- package/dist/commands/clear.js +36 -15
- package/dist/commands/curate.d.ts +74 -0
- package/dist/commands/curate.js +396 -0
- package/dist/commands/foo.d.ts +12 -0
- package/dist/commands/foo.js +61 -0
- package/dist/commands/gen-rules.d.ts +3 -0
- package/dist/commands/gen-rules.js +39 -20
- package/dist/commands/init.d.ts +48 -3
- package/dist/commands/init.js +242 -70
- package/dist/commands/login.js +9 -4
- package/dist/commands/pull.d.ts +33 -0
- package/dist/commands/pull.js +115 -0
- package/dist/commands/push.d.ts +13 -13
- package/dist/commands/push.js +81 -101
- package/dist/commands/query.d.ts +63 -0
- package/dist/commands/query.js +349 -0
- package/dist/commands/space/list.d.ts +5 -2
- package/dist/commands/space/list.js +60 -56
- package/dist/commands/space/switch.d.ts +16 -0
- package/dist/commands/space/switch.js +102 -53
- package/dist/commands/status.d.ts +5 -2
- package/dist/commands/status.js +43 -33
- package/dist/commands/watch.d.ts +23 -0
- package/dist/commands/watch.js +171 -0
- package/dist/config/auth.config.js +14 -2
- package/dist/config/context-tree-domains.d.ts +12 -0
- package/dist/config/context-tree-domains.js +29 -0
- package/dist/config/environment.d.ts +6 -0
- package/dist/config/environment.js +9 -2
- package/dist/constants.d.ts +5 -0
- package/dist/constants.js +6 -0
- package/dist/core/domain/cipher/agent/agent-state-machine.d.ts +128 -0
- package/dist/core/domain/cipher/agent/agent-state-machine.js +183 -0
- package/dist/core/domain/cipher/agent/agent-state.d.ts +77 -0
- package/dist/core/domain/cipher/agent/agent-state.js +59 -0
- package/dist/core/domain/cipher/agent/index.d.ts +7 -0
- package/dist/core/domain/cipher/agent/index.js +7 -0
- package/dist/core/domain/cipher/agent-events/index.d.ts +8 -0
- package/dist/core/domain/cipher/agent-events/index.js +7 -0
- package/dist/core/domain/cipher/agent-events/types.d.ts +419 -0
- package/dist/core/domain/cipher/agent-events/types.js +42 -0
- package/dist/core/domain/cipher/blob/types.d.ts +108 -0
- package/dist/core/domain/cipher/errors/blob-error.d.ts +36 -0
- package/dist/core/domain/cipher/errors/blob-error.js +68 -0
- package/dist/core/domain/cipher/errors/file-system-error.d.ts +211 -0
- package/dist/core/domain/cipher/errors/file-system-error.js +291 -0
- package/dist/core/domain/cipher/errors/llm-error.d.ts +120 -0
- package/dist/core/domain/cipher/errors/llm-error.js +161 -0
- package/dist/core/domain/cipher/errors/memory-error.d.ts +35 -0
- package/dist/core/domain/cipher/errors/memory-error.js +62 -0
- package/dist/core/domain/cipher/errors/process-error-code.d.ts +97 -0
- package/dist/core/domain/cipher/errors/process-error-code.js +98 -0
- package/dist/core/domain/cipher/errors/process-error.d.ts +135 -0
- package/dist/core/domain/cipher/errors/process-error.js +173 -0
- package/dist/core/domain/cipher/errors/session-error.d.ts +56 -0
- package/dist/core/domain/cipher/errors/session-error.js +74 -0
- package/dist/core/domain/cipher/errors/tool-error.d.ts +57 -0
- package/dist/core/domain/cipher/errors/tool-error.js +81 -0
- package/dist/core/domain/cipher/file-system/types.d.ts +203 -0
- package/dist/core/domain/cipher/memory/types.d.ts +102 -0
- package/dist/core/domain/cipher/memory/types.js +4 -0
- package/dist/core/domain/cipher/parsed-interaction.d.ts +47 -0
- package/dist/core/domain/cipher/parsed-interaction.js +25 -0
- package/dist/core/domain/cipher/process/types.d.ts +286 -0
- package/dist/core/domain/cipher/session/types.d.ts +54 -0
- package/dist/core/domain/cipher/storage/history-types.d.ts +38 -0
- package/dist/core/domain/cipher/system-prompt/types.d.ts +131 -0
- package/dist/core/domain/cipher/todos/index.d.ts +4 -0
- package/dist/core/domain/cipher/todos/index.js +4 -0
- package/dist/core/domain/cipher/todos/types.d.ts +57 -0
- package/dist/core/domain/cipher/todos/types.js +5 -0
- package/dist/core/domain/cipher/tools/constants.d.ts +28 -0
- package/dist/core/domain/cipher/tools/constants.js +24 -0
- package/dist/core/domain/cipher/tools/tool-error.d.ts +183 -0
- package/dist/core/domain/cipher/tools/tool-error.js +246 -0
- package/dist/core/domain/cipher/tools/types.d.ts +145 -0
- package/dist/core/domain/entities/brv-config.d.ts +42 -6
- package/dist/core/domain/entities/brv-config.js +115 -17
- package/dist/core/domain/entities/cogit-push-context.d.ts +38 -0
- package/dist/core/domain/entities/cogit-push-context.js +91 -0
- package/dist/core/domain/entities/cogit-push-response.d.ts +20 -0
- package/dist/core/domain/entities/cogit-push-response.js +31 -0
- package/dist/core/domain/entities/cogit-snapshot-author.d.ts +24 -0
- package/dist/core/domain/entities/cogit-snapshot-author.js +39 -0
- package/dist/core/domain/entities/cogit-snapshot-file.d.ts +34 -0
- package/dist/core/domain/entities/cogit-snapshot-file.js +59 -0
- package/dist/core/domain/entities/cogit-snapshot.d.ts +31 -0
- package/dist/core/domain/entities/cogit-snapshot.js +58 -0
- package/dist/core/domain/entities/context-tree-index.d.ts +26 -0
- package/dist/core/domain/entities/context-tree-index.js +27 -0
- package/dist/core/domain/entities/context-tree-snapshot.d.ts +56 -0
- package/dist/core/domain/entities/context-tree-snapshot.js +83 -0
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +3 -1
- package/dist/core/domain/entities/parser.d.ts +567 -0
- package/dist/core/domain/entities/parser.js +10 -0
- package/dist/core/domain/entities/playbook.d.ts +2 -23
- package/dist/core/domain/entities/playbook.js +2 -70
- package/dist/core/domain/errors/brv-config-version-error.d.ts +16 -0
- package/dist/core/domain/errors/brv-config-version-error.js +21 -0
- package/dist/core/domain/knowledge/directory-manager.d.ts +80 -0
- package/dist/core/domain/knowledge/directory-manager.js +145 -0
- package/dist/core/domain/knowledge/markdown-writer.d.ts +18 -0
- package/dist/core/domain/knowledge/markdown-writer.js +18 -0
- package/dist/core/domain/knowledge/relation-parser.d.ts +90 -0
- package/dist/core/domain/knowledge/relation-parser.js +131 -0
- package/dist/core/interfaces/cipher/cipher-services.d.ts +71 -0
- package/dist/core/interfaces/cipher/cipher-services.js +1 -0
- package/dist/core/interfaces/cipher/i-blob-storage.d.ts +78 -0
- package/dist/core/interfaces/cipher/i-blob-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-chat-session.d.ts +62 -0
- package/dist/core/interfaces/cipher/i-chat-session.js +1 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +88 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.js +1 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-parser.d.ts +20 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-parser.js +1 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.d.ts +31 -0
- package/dist/core/interfaces/cipher/i-coding-agent-log-watcher.js +1 -0
- package/dist/core/interfaces/cipher/i-content-generator.d.ts +120 -0
- package/dist/core/interfaces/cipher/i-content-generator.js +12 -0
- package/dist/core/interfaces/cipher/i-event-emitter.d.ts +76 -0
- package/dist/core/interfaces/cipher/i-event-emitter.js +1 -0
- package/dist/core/interfaces/cipher/i-file-system.d.ts +68 -0
- package/dist/core/interfaces/cipher/i-file-system.js +1 -0
- package/dist/core/interfaces/cipher/i-history-storage.d.ts +53 -0
- package/dist/core/interfaces/cipher/i-history-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-llm-provider.d.ts +14 -0
- package/dist/core/interfaces/cipher/i-llm-provider.js +1 -0
- package/dist/core/interfaces/cipher/i-llm-service.d.ts +62 -0
- package/dist/core/interfaces/cipher/i-llm-service.js +1 -0
- package/dist/core/interfaces/cipher/i-logger.d.ts +78 -0
- package/dist/core/interfaces/cipher/i-logger.js +28 -0
- package/dist/core/interfaces/cipher/i-message-formatter.d.ts +44 -0
- package/dist/core/interfaces/cipher/i-message-formatter.js +1 -0
- package/dist/core/interfaces/cipher/i-policy-engine.d.ts +102 -0
- package/dist/core/interfaces/cipher/i-policy-engine.js +9 -0
- package/dist/core/interfaces/cipher/i-process-service.d.ts +65 -0
- package/dist/core/interfaces/cipher/i-process-service.js +1 -0
- package/dist/core/interfaces/cipher/i-system-prompt-contributor.d.ts +25 -0
- package/dist/core/interfaces/cipher/i-system-prompt-contributor.js +1 -0
- package/dist/core/interfaces/cipher/i-tokenizer.d.ts +15 -0
- package/dist/core/interfaces/cipher/i-tokenizer.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-provider.d.ts +64 -0
- package/dist/core/interfaces/cipher/i-tool-provider.js +1 -0
- package/dist/core/interfaces/cipher/i-tool-scheduler.d.ts +103 -0
- package/dist/core/interfaces/cipher/i-tool-scheduler.js +11 -0
- package/dist/core/interfaces/cipher/llm-types.d.ts +46 -0
- package/dist/core/interfaces/cipher/llm-types.js +5 -0
- package/dist/core/interfaces/cipher/message-types.d.ts +118 -0
- package/dist/core/interfaces/cipher/message-types.js +5 -0
- package/dist/core/interfaces/cipher/tokenizer-types.d.ts +11 -0
- package/dist/core/interfaces/cipher/tokenizer-types.js +14 -0
- package/dist/core/interfaces/i-cogit-pull-service.d.ts +24 -0
- package/dist/core/interfaces/i-cogit-pull-service.js +1 -0
- package/dist/core/interfaces/i-cogit-push-service.d.ts +27 -0
- package/dist/core/interfaces/i-cogit-push-service.js +1 -0
- package/dist/core/interfaces/i-context-file-reader.d.ts +32 -0
- package/dist/core/interfaces/i-context-file-reader.js +1 -0
- package/dist/core/interfaces/i-context-tree-service.d.ts +21 -0
- package/dist/core/interfaces/i-context-tree-service.js +1 -0
- package/dist/core/interfaces/i-context-tree-snapshot-service.d.ts +36 -0
- package/dist/core/interfaces/i-context-tree-snapshot-service.js +1 -0
- package/dist/core/interfaces/i-context-tree-writer-service.d.ts +32 -0
- package/dist/core/interfaces/i-context-tree-writer-service.js +1 -0
- package/dist/core/interfaces/i-file-watcher-service.d.ts +41 -0
- package/dist/core/interfaces/i-file-watcher-service.js +1 -0
- package/dist/core/interfaces/parser/i-clean-parser-service.d.ts +18 -0
- package/dist/core/interfaces/parser/i-clean-parser-service.js +1 -0
- package/dist/core/interfaces/parser/i-raw-parser-service.d.ts +17 -0
- package/dist/core/interfaces/parser/i-raw-parser-service.js +1 -0
- package/dist/core/interfaces/parser/i-session-normalizer.d.ts +56 -0
- package/dist/core/interfaces/parser/i-session-normalizer.js +1 -0
- package/dist/hooks/command_not_found/handle-invalid-commands.d.ts +7 -0
- package/dist/hooks/command_not_found/handle-invalid-commands.js +32 -0
- package/dist/hooks/error/clean-errors.d.ts +7 -0
- package/dist/hooks/error/clean-errors.js +50 -0
- package/dist/hooks/init/welcome.js +72 -1
- package/dist/hooks/prerun/validate-brv-config-version.d.ts +28 -0
- package/dist/hooks/prerun/validate-brv-config-version.js +43 -0
- package/dist/infra/cipher/agent-service-factory.d.ts +86 -0
- package/dist/infra/cipher/agent-service-factory.js +212 -0
- package/dist/infra/cipher/blob/blob-storage-factory.d.ts +13 -0
- package/dist/infra/cipher/blob/blob-storage-factory.js +14 -0
- package/dist/infra/cipher/blob/index.d.ts +10 -0
- package/dist/infra/cipher/blob/index.js +12 -0
- package/dist/infra/cipher/blob/migrations.d.ts +63 -0
- package/dist/infra/cipher/blob/migrations.js +148 -0
- package/dist/infra/cipher/blob/sqlite-blob-storage.d.ts +82 -0
- package/dist/infra/cipher/blob/sqlite-blob-storage.js +307 -0
- package/dist/infra/cipher/cipher-agent-state-manager.d.ts +63 -0
- package/dist/infra/cipher/cipher-agent-state-manager.js +108 -0
- package/dist/infra/cipher/cipher-agent.d.ts +182 -0
- package/dist/infra/cipher/cipher-agent.js +317 -0
- package/dist/infra/cipher/command-parser.d.ts +23 -0
- package/dist/infra/cipher/command-parser.js +85 -0
- package/dist/infra/cipher/display/todo-display.d.ts +23 -0
- package/dist/infra/cipher/display/todo-display.js +129 -0
- package/dist/infra/cipher/events/event-emitter.d.ts +137 -0
- package/dist/infra/cipher/events/event-emitter.js +158 -0
- package/dist/infra/cipher/exit-codes.d.ts +44 -0
- package/dist/infra/cipher/exit-codes.js +58 -0
- package/dist/infra/cipher/file-system/file-system-service.d.ts +105 -0
- package/dist/infra/cipher/file-system/file-system-service.js +641 -0
- package/dist/infra/cipher/file-system/gitignore-filter.d.ts +77 -0
- package/dist/infra/cipher/file-system/gitignore-filter.js +120 -0
- package/dist/infra/cipher/file-system/glob-utils.d.ts +60 -0
- package/dist/infra/cipher/file-system/glob-utils.js +120 -0
- package/dist/infra/cipher/file-system/path-validator.d.ts +69 -0
- package/dist/infra/cipher/file-system/path-validator.js +184 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +149 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +364 -0
- package/dist/infra/cipher/grpc/internal-llm-grpc.proto +94 -0
- package/dist/infra/cipher/interactive-commands.d.ts +16 -0
- package/dist/infra/cipher/interactive-commands.js +198 -0
- package/dist/infra/cipher/interactive-loop.d.ts +24 -0
- package/dist/infra/cipher/interactive-loop.js +352 -0
- package/dist/infra/cipher/llm/context/async-mutex.d.ts +59 -0
- package/dist/infra/cipher/llm/context/async-mutex.js +92 -0
- package/dist/infra/cipher/llm/context/compression/index.d.ts +6 -0
- package/dist/infra/cipher/llm/context/compression/index.js +5 -0
- package/dist/infra/cipher/llm/context/compression/middle-removal.d.ts +40 -0
- package/dist/infra/cipher/llm/context/compression/middle-removal.js +76 -0
- package/dist/infra/cipher/llm/context/compression/oldest-removal.d.ts +38 -0
- package/dist/infra/cipher/llm/context/compression/oldest-removal.js +53 -0
- package/dist/infra/cipher/llm/context/compression/types.d.ts +36 -0
- package/dist/infra/cipher/llm/context/compression/types.js +1 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +234 -0
- package/dist/infra/cipher/llm/context/context-manager.js +419 -0
- package/dist/infra/cipher/llm/context/index.d.ts +2 -0
- package/dist/infra/cipher/llm/context/index.js +2 -0
- package/dist/infra/cipher/llm/context/loop-detector.d.ts +125 -0
- package/dist/infra/cipher/llm/context/loop-detector.js +194 -0
- package/dist/infra/cipher/llm/context/utils.d.ts +17 -0
- package/dist/infra/cipher/llm/context/utils.js +89 -0
- package/dist/infra/cipher/llm/formatters/claude-formatter.d.ts +54 -0
- package/dist/infra/cipher/llm/formatters/claude-formatter.js +182 -0
- package/dist/infra/cipher/llm/formatters/gemini-formatter.d.ts +69 -0
- package/dist/infra/cipher/llm/formatters/gemini-formatter.js +253 -0
- package/dist/infra/cipher/llm/formatters/openrouter-formatter.d.ts +47 -0
- package/dist/infra/cipher/llm/formatters/openrouter-formatter.js +238 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +92 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +211 -0
- package/dist/infra/cipher/llm/generators/index.d.ts +13 -0
- package/dist/infra/cipher/llm/generators/index.js +13 -0
- package/dist/infra/cipher/llm/generators/logging-content-generator.d.ts +104 -0
- package/dist/infra/cipher/llm/generators/logging-content-generator.js +182 -0
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.d.ts +93 -0
- package/dist/infra/cipher/llm/generators/openrouter-content-generator.js +254 -0
- package/dist/infra/cipher/llm/generators/retryable-content-generator.d.ts +90 -0
- package/dist/infra/cipher/llm/generators/retryable-content-generator.js +157 -0
- package/dist/infra/cipher/llm/index.d.ts +9 -0
- package/dist/infra/cipher/llm/index.js +13 -0
- package/dist/infra/cipher/llm/internal-llm-service.d.ts +308 -0
- package/dist/infra/cipher/llm/internal-llm-service.js +724 -0
- package/dist/infra/cipher/llm/openrouter-llm-service.d.ts +183 -0
- package/dist/infra/cipher/llm/openrouter-llm-service.js +386 -0
- package/dist/infra/cipher/llm/response-validator.d.ts +89 -0
- package/dist/infra/cipher/llm/response-validator.js +157 -0
- package/dist/infra/cipher/llm/retry/index.d.ts +10 -0
- package/dist/infra/cipher/llm/retry/index.js +10 -0
- package/dist/infra/cipher/llm/retry/retry-policy.d.ts +74 -0
- package/dist/infra/cipher/llm/retry/retry-policy.js +146 -0
- package/dist/infra/cipher/llm/retry/retry-with-backoff.d.ts +113 -0
- package/dist/infra/cipher/llm/retry/retry-with-backoff.js +247 -0
- package/dist/infra/cipher/llm/thought-parser.d.ts +145 -0
- package/dist/infra/cipher/llm/thought-parser.js +190 -0
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.d.ts +47 -0
- package/dist/infra/cipher/llm/tokenizers/claude-tokenizer.js +55 -0
- package/dist/infra/cipher/llm/tokenizers/default-tokenizer.d.ts +31 -0
- package/dist/infra/cipher/llm/tokenizers/default-tokenizer.js +38 -0
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.d.ts +37 -0
- package/dist/infra/cipher/llm/tokenizers/gemini-tokenizer.js +45 -0
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.d.ts +29 -0
- package/dist/infra/cipher/llm/tokenizers/openrouter-tokenizer.js +37 -0
- package/dist/infra/cipher/llm/tool-output-processor.d.ts +117 -0
- package/dist/infra/cipher/llm/tool-output-processor.js +153 -0
- package/dist/infra/cipher/logger/console-logger.d.ts +42 -0
- package/dist/infra/cipher/logger/console-logger.js +63 -0
- package/dist/infra/cipher/logger/event-based-logger.d.ts +54 -0
- package/dist/infra/cipher/logger/event-based-logger.js +92 -0
- package/dist/infra/cipher/memory/index.d.ts +6 -0
- package/dist/infra/cipher/memory/index.js +7 -0
- package/dist/infra/cipher/memory/memory-manager.d.ts +136 -0
- package/dist/infra/cipher/memory/memory-manager.js +523 -0
- package/dist/infra/cipher/parsers/coding-agent-log-parser.d.ts +24 -0
- package/dist/infra/cipher/parsers/coding-agent-log-parser.js +51 -0
- package/dist/infra/cipher/process/command-validator.d.ts +59 -0
- package/dist/infra/cipher/process/command-validator.js +266 -0
- package/dist/infra/cipher/process/index.d.ts +8 -0
- package/dist/infra/cipher/process/index.js +8 -0
- package/dist/infra/cipher/process/process-service.d.ts +95 -0
- package/dist/infra/cipher/process/process-service.js +439 -0
- package/dist/infra/cipher/session/chat-session.d.ts +80 -0
- package/dist/infra/cipher/session/chat-session.js +165 -0
- package/dist/infra/cipher/session/index.d.ts +6 -0
- package/dist/infra/cipher/session/index.js +5 -0
- package/dist/infra/cipher/session/session-event-forwarder.d.ts +37 -0
- package/dist/infra/cipher/session/session-event-forwarder.js +83 -0
- package/dist/infra/cipher/session/session-manager.d.ts +109 -0
- package/dist/infra/cipher/session/session-manager.js +172 -0
- package/dist/infra/cipher/storage/blob-history-storage.d.ts +76 -0
- package/dist/infra/cipher/storage/blob-history-storage.js +178 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +105 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +290 -0
- package/dist/infra/cipher/tools/core-tool-scheduler.d.ts +99 -0
- package/dist/infra/cipher/tools/core-tool-scheduler.js +161 -0
- package/dist/infra/cipher/tools/default-policy-rules.d.ts +26 -0
- package/dist/infra/cipher/tools/default-policy-rules.js +125 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/bash-exec-tool.js +93 -0
- package/dist/infra/cipher/tools/implementations/bash-output-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/bash-output-tool.js +47 -0
- package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.d.ts +11 -0
- package/dist/infra/cipher/tools/implementations/create-knowledge-topic-tool.js +142 -0
- package/dist/infra/cipher/tools/implementations/delete-memory-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/delete-memory-tool.js +37 -0
- package/dist/infra/cipher/tools/implementations/detect-domains-tool.d.ts +7 -0
- package/dist/infra/cipher/tools/implementations/detect-domains-tool.js +73 -0
- package/dist/infra/cipher/tools/implementations/edit-file-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/edit-file-tool.js +50 -0
- package/dist/infra/cipher/tools/implementations/edit-memory-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/edit-memory-tool.js +53 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.d.ts +7 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +421 -0
- package/dist/infra/cipher/tools/implementations/glob-files-tool.d.ts +18 -0
- package/dist/infra/cipher/tools/implementations/glob-files-tool.js +70 -0
- package/dist/infra/cipher/tools/implementations/grep-content-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/grep-content-tool.js +77 -0
- package/dist/infra/cipher/tools/implementations/kill-process-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/kill-process-tool.js +55 -0
- package/dist/infra/cipher/tools/implementations/list-memories-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/list-memories-tool.js +63 -0
- package/dist/infra/cipher/tools/implementations/read-file-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/read-file-tool.js +54 -0
- package/dist/infra/cipher/tools/implementations/read-memory-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/read-memory-tool.js +39 -0
- package/dist/infra/cipher/tools/implementations/search-history-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/search-history-tool.js +36 -0
- package/dist/infra/cipher/tools/implementations/write-file-tool.d.ts +12 -0
- package/dist/infra/cipher/tools/implementations/write-file-tool.js +52 -0
- package/dist/infra/cipher/tools/implementations/write-memory-tool.d.ts +13 -0
- package/dist/infra/cipher/tools/implementations/write-memory-tool.js +52 -0
- package/dist/infra/cipher/tools/implementations/write-todos-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/write-todos-tool.js +165 -0
- package/dist/infra/cipher/tools/index.d.ts +18 -0
- package/dist/infra/cipher/tools/index.js +19 -0
- package/dist/infra/cipher/tools/policy-engine.d.ts +80 -0
- package/dist/infra/cipher/tools/policy-engine.js +110 -0
- package/dist/infra/cipher/tools/tool-invocation-queue.d.ts +191 -0
- package/dist/infra/cipher/tools/tool-invocation-queue.js +254 -0
- package/dist/infra/cipher/tools/tool-invocation.d.ts +216 -0
- package/dist/infra/cipher/tools/tool-invocation.js +294 -0
- package/dist/infra/cipher/tools/tool-manager.d.ts +135 -0
- package/dist/infra/cipher/tools/tool-manager.js +209 -0
- package/dist/infra/cipher/tools/tool-markers.d.ts +48 -0
- package/dist/infra/cipher/tools/tool-markers.js +49 -0
- package/dist/infra/cipher/tools/tool-provider.d.ts +77 -0
- package/dist/infra/cipher/tools/tool-provider.js +196 -0
- package/dist/infra/cipher/tools/tool-registry.d.ts +52 -0
- package/dist/infra/cipher/tools/tool-registry.js +144 -0
- package/dist/infra/cipher/tools/utils/schema-converter.d.ts +10 -0
- package/dist/infra/cipher/tools/utils/schema-converter.js +29 -0
- package/dist/infra/cipher/validation/workspace-validator.d.ts +19 -0
- package/dist/infra/cipher/validation/workspace-validator.js +37 -0
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.d.ts +14 -0
- package/dist/infra/cipher/watcher/coding-agent-log-watcher.js +55 -0
- package/dist/infra/cogit/context-tree-to-push-context-mapper.d.ts +21 -0
- package/dist/infra/cogit/context-tree-to-push-context-mapper.js +32 -0
- package/dist/infra/cogit/http-cogit-pull-service.d.ts +15 -0
- package/dist/infra/cogit/http-cogit-pull-service.js +30 -0
- package/dist/infra/cogit/http-cogit-push-service.d.ts +17 -0
- package/dist/infra/cogit/http-cogit-push-service.js +104 -0
- package/dist/infra/config/file-config-store.js +9 -3
- package/dist/infra/context-tree/file-context-file-reader.d.ts +14 -0
- package/dist/infra/context-tree/file-context-file-reader.js +46 -0
- package/dist/infra/context-tree/file-context-tree-service.d.ts +14 -0
- package/dist/infra/context-tree/file-context-tree-service.js +46 -0
- package/dist/infra/context-tree/file-context-tree-snapshot-service.d.ts +34 -0
- package/dist/infra/context-tree/file-context-tree-snapshot-service.js +117 -0
- package/dist/infra/context-tree/file-context-tree-writer-service.d.ts +22 -0
- package/dist/infra/context-tree/file-context-tree-writer-service.js +61 -0
- package/dist/infra/memory/http-memory-retrieval-service.js +2 -1
- package/dist/infra/memory/http-memory-storage-service.js +4 -3
- package/dist/infra/parsers/clean/clean-claude-service.d.ts +111 -0
- package/dist/infra/parsers/clean/clean-claude-service.js +271 -0
- package/dist/infra/parsers/clean/clean-codex-service.d.ts +231 -0
- package/dist/infra/parsers/clean/clean-codex-service.js +534 -0
- package/dist/infra/parsers/clean/clean-copilot-service.d.ts +255 -0
- package/dist/infra/parsers/clean/clean-copilot-service.js +729 -0
- package/dist/infra/parsers/clean/clean-cursor-service.d.ts +161 -0
- package/dist/infra/parsers/clean/clean-cursor-service.js +432 -0
- package/dist/infra/parsers/clean/clean-parser-service-factory.d.ts +54 -0
- package/dist/infra/parsers/clean/clean-parser-service-factory.js +80 -0
- package/dist/infra/parsers/clean/shared.d.ts +84 -0
- package/dist/infra/parsers/clean/shared.js +273 -0
- package/dist/infra/parsers/raw/raw-claude-service.d.ts +195 -0
- package/dist/infra/parsers/raw/raw-claude-service.js +548 -0
- package/dist/infra/parsers/raw/raw-codex-service.d.ts +313 -0
- package/dist/infra/parsers/raw/raw-codex-service.js +782 -0
- package/dist/infra/parsers/raw/raw-copilot-service.d.ts +196 -0
- package/dist/infra/parsers/raw/raw-copilot-service.js +558 -0
- package/dist/infra/parsers/raw/raw-cursor-service.d.ts +316 -0
- package/dist/infra/parsers/raw/raw-cursor-service.js +818 -0
- package/dist/infra/parsers/raw/raw-parser-service-factory.d.ts +54 -0
- package/dist/infra/parsers/raw/raw-parser-service-factory.js +81 -0
- package/dist/infra/space/http-space-service.js +2 -1
- package/dist/infra/team/http-team-service.js +2 -1
- package/dist/infra/user/http-user-service.js +2 -1
- package/dist/infra/watcher/file-watcher-service.d.ts +10 -0
- package/dist/infra/watcher/file-watcher-service.js +81 -0
- package/dist/infra/workspace/workspace-detector-service.d.ts +60 -0
- package/dist/infra/workspace/workspace-detector-service.js +165 -0
- package/dist/resources/prompts/curate-context-tree-curation.yml +48 -0
- package/dist/resources/prompts/modes/autonomous.yml +9 -0
- package/dist/resources/prompts/query-context-tree-retrieval.yml +49 -0
- package/dist/resources/prompts/reflection.yml +27 -0
- package/dist/resources/prompts/system-prompt.yml +82 -0
- package/dist/resources/prompts/tool-outputs.yml +30 -0
- package/dist/templates/README.md +6 -7
- package/dist/templates/sections/command-reference.md +40 -111
- package/dist/templates/sections/workflow.md +3 -30
- package/dist/utils/emoji-helpers.d.ts +38 -0
- package/dist/utils/emoji-helpers.js +42 -0
- package/dist/utils/error-handler.d.ts +51 -0
- package/dist/utils/error-handler.js +169 -0
- package/dist/utils/error-helpers.d.ts +30 -0
- package/dist/utils/error-helpers.js +47 -0
- package/dist/utils/file-helpers.d.ts +15 -0
- package/dist/utils/file-helpers.js +44 -0
- package/dist/utils/oclif-error-helpers.d.ts +40 -0
- package/dist/utils/oclif-error-helpers.js +46 -0
- package/dist/utils/tool-display-formatter.d.ts +53 -0
- package/dist/utils/tool-display-formatter.js +257 -0
- package/oclif.manifest.json +381 -141
- package/package.json +27 -6
- package/dist/commands/add.d.ts +0 -49
- package/dist/commands/add.js +0 -192
- package/dist/commands/complete.d.ts +0 -108
- package/dist/commands/complete.js +0 -340
- package/dist/commands/retrieve.d.ts +0 -26
- package/dist/commands/retrieve.js +0 -101
- package/dist/core/domain/entities/curator-output.d.ts +0 -14
- package/dist/core/domain/entities/curator-output.js +0 -23
- package/dist/core/domain/entities/delta-batch.d.ts +0 -30
- package/dist/core/domain/entities/delta-batch.js +0 -52
- package/dist/core/domain/entities/delta-operation.d.ts +0 -31
- package/dist/core/domain/entities/delta-operation.js +0 -50
- package/dist/core/domain/entities/executor-output.d.ts +0 -27
- package/dist/core/domain/entities/executor-output.js +0 -33
- package/dist/core/domain/entities/reflector-output.d.ts +0 -38
- package/dist/core/domain/entities/reflector-output.js +0 -44
- package/dist/core/interfaces/i-ace-prompt-builder.d.ts +0 -48
- package/dist/core/interfaces/i-bullet-content-store.d.ts +0 -36
- package/dist/core/interfaces/i-delta-store.d.ts +0 -15
- package/dist/core/interfaces/i-executor-output-store.d.ts +0 -14
- package/dist/core/interfaces/i-playbook-service.d.ts +0 -69
- package/dist/core/interfaces/i-playbook-store.d.ts +0 -38
- package/dist/core/interfaces/i-reflection-store.d.ts +0 -21
- package/dist/infra/ace/ace-file-utils.d.ts +0 -46
- package/dist/infra/ace/ace-file-utils.js +0 -83
- package/dist/infra/ace/ace-prompt-templates.d.ts +0 -13
- package/dist/infra/ace/ace-prompt-templates.js +0 -177
- package/dist/infra/ace/file-bullet-content-store.d.ts +0 -27
- package/dist/infra/ace/file-bullet-content-store.js +0 -89
- package/dist/infra/ace/file-delta-store.d.ts +0 -9
- package/dist/infra/ace/file-delta-store.js +0 -26
- package/dist/infra/ace/file-executor-output-store.d.ts +0 -9
- package/dist/infra/ace/file-executor-output-store.js +0 -26
- package/dist/infra/ace/file-playbook-store.d.ts +0 -29
- package/dist/infra/ace/file-playbook-store.js +0 -107
- package/dist/infra/ace/file-reflection-store.d.ts +0 -10
- package/dist/infra/ace/file-reflection-store.js +0 -55
- package/dist/infra/playbook/file-playbook-service.d.ts +0 -42
- package/dist/infra/playbook/file-playbook-service.js +0 -132
- /package/dist/core/{interfaces/i-ace-prompt-builder.js → domain/cipher/blob/types.js} +0 -0
- /package/dist/core/{interfaces/i-bullet-content-store.js → domain/cipher/file-system/types.js} +0 -0
- /package/dist/core/{interfaces/i-delta-store.js → domain/cipher/process/types.js} +0 -0
- /package/dist/core/{interfaces/i-executor-output-store.js → domain/cipher/session/types.js} +0 -0
- /package/dist/core/{interfaces/i-playbook-service.js → domain/cipher/storage/history-types.js} +0 -0
- /package/dist/core/{interfaces/i-playbook-store.js → domain/cipher/system-prompt/types.js} +0 -0
- /package/dist/core/{interfaces/i-reflection-store.js → domain/cipher/tools/types.js} +0 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { NoOpLogger } from '../../../../core/interfaces/cipher/i-logger.js';
|
|
2
|
+
import { getErrorMessage } from '../../../../utils/error-helpers.js';
|
|
3
|
+
import { AsyncMutex } from './async-mutex.js';
|
|
4
|
+
import { MiddleRemovalStrategy, OldestRemovalStrategy } from './compression/index.js';
|
|
5
|
+
import { countMessagesTokens } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Context Manager for managing conversation history.
|
|
8
|
+
*
|
|
9
|
+
* Responsibilities:
|
|
10
|
+
* - Store and manage internal message history
|
|
11
|
+
* - Format messages for specific LLM providers
|
|
12
|
+
* - Handle message compression (future)
|
|
13
|
+
* - Count tokens for context management
|
|
14
|
+
*
|
|
15
|
+
* Generic type T represents the provider-specific message format
|
|
16
|
+
* (e.g., GeminiContent for Gemini, MessageParam for Anthropic)
|
|
17
|
+
*/
|
|
18
|
+
export class ContextManager {
|
|
19
|
+
compressionStrategies;
|
|
20
|
+
formatter;
|
|
21
|
+
historyStorage;
|
|
22
|
+
isInitialized = false;
|
|
23
|
+
logger;
|
|
24
|
+
maxInputTokens;
|
|
25
|
+
messages = [];
|
|
26
|
+
/**
|
|
27
|
+
* Mutex for thread-safe operations on messages array.
|
|
28
|
+
* Used during parallel tool execution to prevent race conditions.
|
|
29
|
+
*/
|
|
30
|
+
mutex = new AsyncMutex();
|
|
31
|
+
sessionId;
|
|
32
|
+
tokenizer;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new context manager
|
|
35
|
+
*
|
|
36
|
+
* @param options - Configuration options
|
|
37
|
+
* @param options.sessionId - Unique session identifier
|
|
38
|
+
* @param options.formatter - Message formatter for provider-specific format
|
|
39
|
+
* @param options.tokenizer - Token counter for the model
|
|
40
|
+
* @param options.maxInputTokens - Maximum input tokens allowed
|
|
41
|
+
* @param options.historyStorage - Optional history storage for persistence
|
|
42
|
+
* @param options.compressionStrategies - Optional compression strategies (defaults to MiddleRemoval + OldestRemoval)
|
|
43
|
+
*/
|
|
44
|
+
constructor(options) {
|
|
45
|
+
this.sessionId = options.sessionId;
|
|
46
|
+
this.formatter = options.formatter;
|
|
47
|
+
this.tokenizer = options.tokenizer;
|
|
48
|
+
this.maxInputTokens = options.maxInputTokens;
|
|
49
|
+
this.historyStorage = options.historyStorage;
|
|
50
|
+
this.logger = options.logger ?? new NoOpLogger();
|
|
51
|
+
// Initialize compression strategies with defaults
|
|
52
|
+
this.compressionStrategies = options.compressionStrategies ?? [
|
|
53
|
+
new MiddleRemovalStrategy({ preserveEnd: 5, preserveStart: 4 }),
|
|
54
|
+
new OldestRemovalStrategy({ minMessagesToKeep: 4 }),
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Add an assistant message to the conversation.
|
|
59
|
+
*
|
|
60
|
+
* @param content - Message content (text or null if only tool calls)
|
|
61
|
+
* @param toolCalls - Optional tool calls made by the assistant
|
|
62
|
+
*/
|
|
63
|
+
async addAssistantMessage(content, toolCalls) {
|
|
64
|
+
const message = {
|
|
65
|
+
content,
|
|
66
|
+
role: 'assistant',
|
|
67
|
+
toolCalls,
|
|
68
|
+
};
|
|
69
|
+
this.messages.push(message);
|
|
70
|
+
// Auto-save to persistent storage (non-blocking)
|
|
71
|
+
this.persistHistory().catch((error) => {
|
|
72
|
+
this.logger.error('Failed to persist history after assistant message', { error, sessionId: this.sessionId });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Add a system message to the conversation.
|
|
77
|
+
*
|
|
78
|
+
* @param content - System message content
|
|
79
|
+
*/
|
|
80
|
+
async addSystemMessage(content) {
|
|
81
|
+
const message = {
|
|
82
|
+
content,
|
|
83
|
+
role: 'system',
|
|
84
|
+
};
|
|
85
|
+
this.messages.push(message);
|
|
86
|
+
// Auto-save to persistent storage (non-blocking)
|
|
87
|
+
this.persistHistory().catch((error) => {
|
|
88
|
+
this.logger.error('Failed to persist history after system message', { error, sessionId: this.sessionId });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Add a tool result message to the conversation.
|
|
93
|
+
* Thread-safe: Uses mutex to protect shared state during parallel tool execution.
|
|
94
|
+
*
|
|
95
|
+
* @param toolCallId - ID of the tool call this result responds to
|
|
96
|
+
* @param toolName - Name of the tool that was executed
|
|
97
|
+
* @param result - Result from tool execution
|
|
98
|
+
* @param _metadata - Additional metadata (success status, error type, execution metadata)
|
|
99
|
+
* @param _metadata.success - Whether the tool execution succeeded
|
|
100
|
+
* @param _metadata.errorType - Classified error type (if failed)
|
|
101
|
+
* @param _metadata.metadata - Execution metadata (duration, tokens, etc.)
|
|
102
|
+
* @returns The content that was added
|
|
103
|
+
*/
|
|
104
|
+
async addToolResult(toolCallId, toolName, result, _metadata) {
|
|
105
|
+
// Sanitize result - convert to string representation (can be done outside lock)
|
|
106
|
+
const sanitized = this.sanitizeToolResult(result);
|
|
107
|
+
const message = {
|
|
108
|
+
content: sanitized,
|
|
109
|
+
name: toolName,
|
|
110
|
+
role: 'tool',
|
|
111
|
+
toolCallId,
|
|
112
|
+
};
|
|
113
|
+
// Use mutex to protect message array modification and persistence
|
|
114
|
+
await this.mutex.withLock(async () => {
|
|
115
|
+
this.messages.push(message);
|
|
116
|
+
// Persist within the lock to ensure ordering consistency
|
|
117
|
+
try {
|
|
118
|
+
await this.persistHistory();
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
this.logger.error('Failed to persist history after tool result', { error, sessionId: this.sessionId });
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return sanitized;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Add a user message to the conversation.
|
|
128
|
+
*
|
|
129
|
+
* @param content - User message text
|
|
130
|
+
* @param _imageData - Optional image data (not yet implemented)
|
|
131
|
+
* @param _fileData - Optional file data (not yet implemented)
|
|
132
|
+
*/
|
|
133
|
+
async addUserMessage(content, _imageData, _fileData) {
|
|
134
|
+
// Simple implementation: just use text content
|
|
135
|
+
// Image and file support can be added later
|
|
136
|
+
const message = {
|
|
137
|
+
content,
|
|
138
|
+
role: 'user',
|
|
139
|
+
};
|
|
140
|
+
this.messages.push(message);
|
|
141
|
+
// Auto-save to persistent storage (non-blocking)
|
|
142
|
+
this.persistHistory().catch((error) => {
|
|
143
|
+
this.logger.error('Failed to persist history after user message', { error, sessionId: this.sessionId });
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clear all messages from the conversation history.
|
|
148
|
+
* Also clears persisted history if storage is enabled.
|
|
149
|
+
*/
|
|
150
|
+
async clearHistory() {
|
|
151
|
+
this.messages = [];
|
|
152
|
+
// Clear persisted history if storage enabled
|
|
153
|
+
if (this.historyStorage) {
|
|
154
|
+
try {
|
|
155
|
+
await this.historyStorage.deleteHistory(this.sessionId);
|
|
156
|
+
// Debug logging removed for cleaner user experience
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
this.logger.error('Failed to clear persisted history', { error, sessionId: this.sessionId });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get comprehensive messages (all messages, for persistence/debugging).
|
|
165
|
+
* This includes all messages including invalid ones.
|
|
166
|
+
*
|
|
167
|
+
* @returns All messages in the conversation history
|
|
168
|
+
*/
|
|
169
|
+
getComprehensiveMessages() {
|
|
170
|
+
return [...this.messages];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get curated messages (valid messages only, for API calls).
|
|
174
|
+
* Filters out invalid messages that would waste tokens or confuse the LLM.
|
|
175
|
+
*
|
|
176
|
+
* @returns Only valid messages suitable for API calls
|
|
177
|
+
*/
|
|
178
|
+
getCuratedMessages() {
|
|
179
|
+
return this.messages.filter((msg) => this.validateMessage(msg).isValid);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get formatted messages with compression applied.
|
|
183
|
+
* Uses curated (valid-only) messages for better LLM context quality.
|
|
184
|
+
*
|
|
185
|
+
* @param systemPrompt - Optional system prompt (for token accounting)
|
|
186
|
+
* @returns Formatted messages, system prompt, token count, and filter stats
|
|
187
|
+
*/
|
|
188
|
+
async getFormattedMessagesWithCompression(systemPrompt) {
|
|
189
|
+
// Get curated messages (filter invalid ones)
|
|
190
|
+
const curatedMessages = this.getCuratedMessages();
|
|
191
|
+
const messagesFiltered = this.messages.length - curatedMessages.length;
|
|
192
|
+
// Calculate system prompt tokens
|
|
193
|
+
const systemPromptTokens = systemPrompt ? this.tokenizer.countTokens(systemPrompt) : 0;
|
|
194
|
+
// Compress curated history if needed
|
|
195
|
+
const compressedHistory = await this.compressHistoryIfNeeded(systemPromptTokens, curatedMessages);
|
|
196
|
+
// Format compressed messages
|
|
197
|
+
const formattedMessages = this.formatter.format(compressedHistory);
|
|
198
|
+
// Count total tokens (system + history)
|
|
199
|
+
const historyTokens = countMessagesTokens(compressedHistory, this.tokenizer);
|
|
200
|
+
const tokensUsed = systemPromptTokens + historyTokens;
|
|
201
|
+
return {
|
|
202
|
+
formattedMessages,
|
|
203
|
+
messagesFiltered,
|
|
204
|
+
systemPrompt,
|
|
205
|
+
tokensUsed,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get the maximum input tokens allowed.
|
|
210
|
+
*/
|
|
211
|
+
getMaxInputTokens() {
|
|
212
|
+
return this.maxInputTokens;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get all messages in the conversation.
|
|
216
|
+
*/
|
|
217
|
+
getMessages() {
|
|
218
|
+
return [...this.messages];
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get the session ID.
|
|
222
|
+
*/
|
|
223
|
+
getSessionId() {
|
|
224
|
+
return this.sessionId;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Initialize the context manager by loading persisted history.
|
|
228
|
+
* Should be called after construction to restore previous conversation.
|
|
229
|
+
*
|
|
230
|
+
* @returns True if history was loaded, false otherwise
|
|
231
|
+
*/
|
|
232
|
+
async initialize() {
|
|
233
|
+
if (this.isInitialized) {
|
|
234
|
+
this.logger.warn('ContextManager already initialized', { sessionId: this.sessionId });
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
if (!this.historyStorage) {
|
|
238
|
+
this.isInitialized = true;
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const history = await this.historyStorage.loadHistory(this.sessionId);
|
|
243
|
+
if (history && history.length > 0) {
|
|
244
|
+
this.messages = history;
|
|
245
|
+
this.isInitialized = true;
|
|
246
|
+
// Debug logging removed for cleaner user experience
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
this.isInitialized = true;
|
|
250
|
+
// Debug logging removed for cleaner user experience
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
this.logger.error('Failed to load history for session', { error, sessionId: this.sessionId });
|
|
255
|
+
this.isInitialized = true;
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Compress conversation history if needed to fit within token limits.
|
|
261
|
+
*
|
|
262
|
+
* This method applies compression strategies sequentially until the history
|
|
263
|
+
* fits within the available token budget (maxInputTokens - systemPromptTokens).
|
|
264
|
+
*
|
|
265
|
+
* @param systemPromptTokens - Tokens used by system prompt (reserved, not compressible)
|
|
266
|
+
* @param messagesToCompress - Messages to compress (defaults to all messages)
|
|
267
|
+
* @returns Compressed message history
|
|
268
|
+
*/
|
|
269
|
+
async compressHistoryIfNeeded(systemPromptTokens, messagesToCompress) {
|
|
270
|
+
const messages = messagesToCompress ?? this.messages;
|
|
271
|
+
// Calculate current token usage
|
|
272
|
+
const currentHistoryTokens = countMessagesTokens(messages, this.tokenizer);
|
|
273
|
+
const totalTokens = systemPromptTokens + currentHistoryTokens;
|
|
274
|
+
// No compression needed
|
|
275
|
+
if (totalTokens <= this.maxInputTokens) {
|
|
276
|
+
// Debug logging removed for cleaner user experience
|
|
277
|
+
return messages;
|
|
278
|
+
}
|
|
279
|
+
// Debug logging removed for cleaner user experience
|
|
280
|
+
// Calculate target token budget for history
|
|
281
|
+
// Reserve space for system prompt
|
|
282
|
+
const maxHistoryTokens = this.maxInputTokens - systemPromptTokens;
|
|
283
|
+
// Apply compression strategies sequentially
|
|
284
|
+
let compressedHistory = messages;
|
|
285
|
+
for (const strategy of this.compressionStrategies) {
|
|
286
|
+
// Debug logging removed for cleaner user experience
|
|
287
|
+
// eslint-disable-next-line no-await-in-loop
|
|
288
|
+
compressedHistory = await strategy.compress(compressedHistory, maxHistoryTokens, this.tokenizer);
|
|
289
|
+
// Check if we've met the token limit
|
|
290
|
+
const compressedTokens = countMessagesTokens(compressedHistory, this.tokenizer);
|
|
291
|
+
const newTotal = systemPromptTokens + compressedTokens;
|
|
292
|
+
if (newTotal <= this.maxInputTokens) {
|
|
293
|
+
// Debug logging removed for cleaner user experience
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Final token count
|
|
298
|
+
const finalTokens = countMessagesTokens(compressedHistory, this.tokenizer);
|
|
299
|
+
const finalTotal = systemPromptTokens + finalTokens;
|
|
300
|
+
if (finalTotal > this.maxInputTokens) {
|
|
301
|
+
// Keep warning as it's important for users to know
|
|
302
|
+
this.logger.warn('Unable to compress below token limit', {
|
|
303
|
+
finalTokens,
|
|
304
|
+
finalTotal,
|
|
305
|
+
maxInputTokens: this.maxInputTokens,
|
|
306
|
+
sessionId: this.sessionId,
|
|
307
|
+
systemPromptTokens,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return compressedHistory;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Count tokens in formatted messages.
|
|
314
|
+
*
|
|
315
|
+
* @param _formattedMessages - Messages in provider-specific format
|
|
316
|
+
* @returns Token count
|
|
317
|
+
*/
|
|
318
|
+
async countTokens(_formattedMessages) {
|
|
319
|
+
// Use tokenizer to count tokens
|
|
320
|
+
// This is simplified - actual implementation would convert formatted messages back
|
|
321
|
+
// For now, estimate based on internal messages
|
|
322
|
+
const text = this.messages
|
|
323
|
+
.map((m) => {
|
|
324
|
+
if (typeof m.content === 'string') {
|
|
325
|
+
return m.content;
|
|
326
|
+
}
|
|
327
|
+
if (Array.isArray(m.content)) {
|
|
328
|
+
return m.content
|
|
329
|
+
.map((part) => {
|
|
330
|
+
if (part.type === 'text') {
|
|
331
|
+
return part.text;
|
|
332
|
+
}
|
|
333
|
+
return '';
|
|
334
|
+
})
|
|
335
|
+
.join('');
|
|
336
|
+
}
|
|
337
|
+
return '';
|
|
338
|
+
})
|
|
339
|
+
.join('\n');
|
|
340
|
+
return this.tokenizer.countTokens(text);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Check if a system message is noise (empty or whitespace only).
|
|
344
|
+
*
|
|
345
|
+
* @param message - Message to check
|
|
346
|
+
* @returns True if the message is noise
|
|
347
|
+
*/
|
|
348
|
+
isSystemNoise(message) {
|
|
349
|
+
const content = typeof message.content === 'string' ? message.content : '';
|
|
350
|
+
return content.trim().length === 0;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Persist current conversation history to storage.
|
|
354
|
+
* This is called automatically after each message is added.
|
|
355
|
+
*
|
|
356
|
+
* @returns Promise that resolves when history is persisted
|
|
357
|
+
*/
|
|
358
|
+
async persistHistory() {
|
|
359
|
+
if (!this.historyStorage) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
// Store InternalMessage directly (no conversion needed)
|
|
363
|
+
await this.historyStorage.saveHistory(this.sessionId, this.messages);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Sanitize tool result for storage.
|
|
367
|
+
* Handles large outputs, binary data, circular references, etc.
|
|
368
|
+
*
|
|
369
|
+
* @param result - Raw tool result
|
|
370
|
+
* @returns Sanitized string representation
|
|
371
|
+
*/
|
|
372
|
+
sanitizeToolResult(result) {
|
|
373
|
+
try {
|
|
374
|
+
// If already a string, return as-is
|
|
375
|
+
if (typeof result === 'string') {
|
|
376
|
+
return result;
|
|
377
|
+
}
|
|
378
|
+
// Convert to JSON string
|
|
379
|
+
const jsonString = JSON.stringify(result, null, 2);
|
|
380
|
+
// Limit size to prevent extremely large results
|
|
381
|
+
const MAX_RESULT_LENGTH = 50_000;
|
|
382
|
+
if (jsonString.length > MAX_RESULT_LENGTH) {
|
|
383
|
+
return jsonString.slice(0, MAX_RESULT_LENGTH) + '\n... (truncated)';
|
|
384
|
+
}
|
|
385
|
+
return jsonString;
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
// Handle circular references or other serialization errors
|
|
389
|
+
return `[Tool result serialization failed: ${getErrorMessage(error)}]`;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Validate a message for API inclusion.
|
|
394
|
+
* Filters out invalid messages that would waste tokens or confuse the LLM.
|
|
395
|
+
*
|
|
396
|
+
* Rules:
|
|
397
|
+
* 1. Empty content (non-tool messages without content or tool calls)
|
|
398
|
+
* 2. Tool result without corresponding tool call ID
|
|
399
|
+
* 3. System messages with only noise (empty or whitespace)
|
|
400
|
+
*
|
|
401
|
+
* @param message - Message to validate
|
|
402
|
+
* @returns Validation result indicating if message is valid for API
|
|
403
|
+
*/
|
|
404
|
+
validateMessage(message) {
|
|
405
|
+
// Rule 1: Empty content check (skip for tool messages which always have content)
|
|
406
|
+
if (message.role !== 'tool' && !message.content && (!message.toolCalls || message.toolCalls.length === 0)) {
|
|
407
|
+
return { isValid: false, reason: 'empty_content' };
|
|
408
|
+
}
|
|
409
|
+
// Rule 2: Tool result without corresponding call ID
|
|
410
|
+
if (message.role === 'tool' && !message.toolCallId) {
|
|
411
|
+
return { isValid: false, reason: 'incomplete_tool_call' };
|
|
412
|
+
}
|
|
413
|
+
// Rule 3: System messages with only noise (empty or whitespace)
|
|
414
|
+
if (message.role === 'system' && this.isSystemNoise(message)) {
|
|
415
|
+
return { isValid: false, reason: 'system_noise' };
|
|
416
|
+
}
|
|
417
|
+
return { isValid: true };
|
|
418
|
+
}
|
|
419
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loop Detector for Agent Tool Calls
|
|
3
|
+
*
|
|
4
|
+
* Detects repetitive tool call patterns to prevent the agent from:
|
|
5
|
+
* - Making the same tool call with identical arguments multiple times
|
|
6
|
+
* - Oscillating between two tool calls (A→B→A→B pattern)
|
|
7
|
+
*
|
|
8
|
+
* When a loop is detected, the caller should skip tool execution
|
|
9
|
+
* and inject a warning message to guide the LLM to try a different approach.
|
|
10
|
+
*
|
|
11
|
+
* Thread-safe: Uses AsyncMutex to protect shared state during parallel tool execution.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Signature of a tool call for comparison.
|
|
15
|
+
*/
|
|
16
|
+
export interface ToolCallSignature {
|
|
17
|
+
/** Hash of the serialized arguments for fast comparison */
|
|
18
|
+
argsHash: string;
|
|
19
|
+
/** Timestamp when the call was recorded */
|
|
20
|
+
timestamp: number;
|
|
21
|
+
/** Name of the tool being called */
|
|
22
|
+
toolName: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Result of loop detection check.
|
|
26
|
+
*/
|
|
27
|
+
export interface LoopDetectionResult {
|
|
28
|
+
/** Whether a loop pattern was detected */
|
|
29
|
+
isLoop: boolean;
|
|
30
|
+
/** Type of loop pattern detected */
|
|
31
|
+
loopType?: 'exact_repeat' | 'oscillation';
|
|
32
|
+
/** Number of times the pattern repeated */
|
|
33
|
+
repeatCount?: number;
|
|
34
|
+
/** Human-readable suggestion for the LLM */
|
|
35
|
+
suggestion?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Configuration for loop detection thresholds.
|
|
39
|
+
*/
|
|
40
|
+
export interface LoopDetectorConfig {
|
|
41
|
+
/** Same tool+args called N times consecutively = loop (default: 3) */
|
|
42
|
+
exactRepeatThreshold: number;
|
|
43
|
+
/** A→B→A→B pattern cycles before detection (default: 2) */
|
|
44
|
+
oscillationThreshold: number;
|
|
45
|
+
/** How many recent calls to track (default: 10) */
|
|
46
|
+
windowSize: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Loop Detector.
|
|
50
|
+
*
|
|
51
|
+
* Tracks recent tool calls and detects repetitive patterns.
|
|
52
|
+
* This helps prevent the agent from wasting tokens and time
|
|
53
|
+
* on repeated unsuccessful attempts.
|
|
54
|
+
*
|
|
55
|
+
* Thread-safe: All mutating operations use AsyncMutex to ensure
|
|
56
|
+
* safe concurrent access during parallel tool execution.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const detector = new LoopDetector()
|
|
61
|
+
*
|
|
62
|
+
* // Before executing each tool call (async for thread safety)
|
|
63
|
+
* const result = await detector.recordAndCheck('read_file', { path: '/foo.ts' })
|
|
64
|
+
* if (result.isLoop) {
|
|
65
|
+
* // Skip execution, inject warning to LLM
|
|
66
|
+
* console.log(result.suggestion)
|
|
67
|
+
* } else {
|
|
68
|
+
* // Execute tool normally
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare class LoopDetector {
|
|
73
|
+
private readonly config;
|
|
74
|
+
private readonly mutex;
|
|
75
|
+
private recentCalls;
|
|
76
|
+
constructor(config?: Partial<LoopDetectorConfig>);
|
|
77
|
+
/**
|
|
78
|
+
* Get the current configuration.
|
|
79
|
+
*/
|
|
80
|
+
getConfig(): Readonly<LoopDetectorConfig>;
|
|
81
|
+
/**
|
|
82
|
+
* Get the number of recorded calls in the window.
|
|
83
|
+
*/
|
|
84
|
+
getRecentCallCount(): number;
|
|
85
|
+
/**
|
|
86
|
+
* Record a tool call and check for loop patterns.
|
|
87
|
+
* Thread-safe: Uses mutex to protect shared state during parallel execution.
|
|
88
|
+
*
|
|
89
|
+
* @param toolName - Name of the tool being called
|
|
90
|
+
* @param args - Arguments passed to the tool
|
|
91
|
+
* @returns Detection result indicating if a loop was found
|
|
92
|
+
*/
|
|
93
|
+
recordAndCheck(toolName: string, args: Record<string, unknown>): Promise<LoopDetectionResult>;
|
|
94
|
+
/**
|
|
95
|
+
* Reset the detector state.
|
|
96
|
+
* Should be called when starting a new conversation or task.
|
|
97
|
+
* Thread-safe: Uses mutex to protect shared state.
|
|
98
|
+
*/
|
|
99
|
+
reset(): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Create a signature for a tool call.
|
|
102
|
+
*/
|
|
103
|
+
private createSignature;
|
|
104
|
+
/**
|
|
105
|
+
* Detect exact repeat pattern: same call N times consecutively.
|
|
106
|
+
*/
|
|
107
|
+
private detectExactRepeat;
|
|
108
|
+
/**
|
|
109
|
+
* Detect loop patterns in recent calls.
|
|
110
|
+
*/
|
|
111
|
+
private detectLoop;
|
|
112
|
+
/**
|
|
113
|
+
* Detect oscillation pattern: A→B→A→B.
|
|
114
|
+
*/
|
|
115
|
+
private detectOscillation;
|
|
116
|
+
/**
|
|
117
|
+
* Create a deterministic hash of tool arguments.
|
|
118
|
+
* Sorts keys to ensure consistent ordering.
|
|
119
|
+
*/
|
|
120
|
+
private hashArgs;
|
|
121
|
+
/**
|
|
122
|
+
* Check if two signatures represent the same tool call.
|
|
123
|
+
*/
|
|
124
|
+
private signaturesMatch;
|
|
125
|
+
}
|