byterover-cli 0.3.4 → 0.4.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 +119 -63
- package/bin/dev.js +8 -1
- package/bin/run.js +7 -0
- package/dist/commands/cipher-agent/run.d.ts +30 -0
- package/dist/commands/cipher-agent/run.js +123 -61
- package/dist/commands/cipher-agent/set-prompt.d.ts +2 -0
- package/dist/commands/cipher-agent/set-prompt.js +13 -8
- package/dist/commands/cipher-agent/show-prompt.d.ts +2 -0
- package/dist/commands/cipher-agent/show-prompt.js +17 -12
- package/dist/commands/curate.d.ts +3 -60
- package/dist/commands/curate.js +45 -341
- package/dist/commands/foo.d.ts +4 -2
- package/dist/commands/foo.js +21 -16
- package/dist/commands/main.d.ts +9 -0
- package/dist/commands/main.js +34 -0
- package/dist/commands/query.d.ts +2 -48
- package/dist/commands/query.js +19 -287
- package/dist/commands/status.d.ts +2 -13
- package/dist/commands/status.js +12 -91
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.js +23 -19
- package/dist/config/environment.d.ts +1 -1
- package/dist/config/environment.js +2 -2
- package/dist/constants.d.ts +4 -5
- package/dist/constants.js +5 -5
- package/dist/core/domain/cipher/errors/storage-error.d.ts +89 -0
- package/dist/core/domain/cipher/errors/storage-error.js +130 -0
- package/dist/core/domain/cipher/queue/types.d.ts +71 -0
- package/dist/core/domain/cipher/queue/types.js +9 -0
- package/dist/core/domain/cipher/storage/message-storage-types.d.ts +218 -0
- package/dist/core/domain/cipher/storage/message-storage-types.js +18 -0
- package/dist/core/domain/cipher/tools/constants.d.ts +1 -0
- package/dist/core/domain/cipher/tools/constants.js +1 -0
- package/dist/core/domain/entities/event.d.ts +1 -1
- package/dist/core/domain/entities/event.js +5 -0
- package/dist/core/domain/entities/global-config.d.ts +36 -0
- package/dist/core/domain/entities/global-config.js +66 -0
- package/dist/core/domain/knowledge/directory-manager.d.ts +10 -0
- package/dist/core/domain/knowledge/directory-manager.js +18 -0
- package/dist/core/domain/knowledge/markdown-writer.d.ts +9 -0
- package/dist/core/domain/knowledge/markdown-writer.js +51 -1
- package/dist/core/interfaces/cipher/i-agent-storage.d.ts +152 -0
- package/dist/core/interfaces/cipher/i-agent-storage.js +1 -0
- package/dist/core/interfaces/cipher/i-cipher-agent.d.ts +2 -0
- package/dist/core/interfaces/cipher/i-key-storage.d.ts +91 -0
- package/dist/core/interfaces/cipher/i-key-storage.js +1 -0
- package/dist/core/interfaces/i-global-config-store.d.ts +34 -0
- package/dist/core/interfaces/i-global-config-store.js +1 -0
- package/dist/core/interfaces/i-onboarding-preference-store.d.ts +20 -0
- package/dist/core/interfaces/i-onboarding-preference-store.js +1 -0
- package/dist/core/interfaces/i-terminal.d.ts +146 -0
- package/dist/core/interfaces/i-terminal.js +1 -0
- package/dist/core/interfaces/i-workspace-detector-service.d.ts +8 -0
- package/dist/core/interfaces/i-workspace-detector-service.js +1 -0
- package/dist/core/interfaces/usecase/i-clear-use-case.d.ts +6 -0
- package/dist/core/interfaces/usecase/i-clear-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-curate-use-case.d.ts +10 -0
- package/dist/core/interfaces/usecase/i-curate-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-generate-rules-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-generate-rules-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-init-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-init-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-login-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-login-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-logout-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-logout-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-pull-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-pull-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-push-use-case.d.ts +6 -0
- package/dist/core/interfaces/usecase/i-push-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-query-use-case.d.ts +9 -0
- package/dist/core/interfaces/usecase/i-query-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-space-list-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-space-list-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-space-switch-use-case.d.ts +3 -0
- package/dist/core/interfaces/usecase/i-space-switch-use-case.js +1 -0
- package/dist/core/interfaces/usecase/i-status-use-case.d.ts +5 -0
- package/dist/core/interfaces/usecase/i-status-use-case.js +1 -0
- package/dist/hooks/init/update-notifier.js +1 -5
- package/dist/hooks/init/welcome.js +1 -2
- package/dist/infra/cipher/agent-service-factory.d.ts +13 -6
- package/dist/infra/cipher/agent-service-factory.js +40 -16
- package/dist/infra/cipher/cipher-agent.js +4 -4
- package/dist/infra/cipher/consumer/consumer-lock.d.ts +20 -0
- package/dist/infra/cipher/consumer/consumer-lock.js +40 -0
- package/dist/infra/cipher/consumer/consumer-service.d.ts +99 -0
- package/dist/infra/cipher/consumer/consumer-service.js +165 -0
- package/dist/infra/cipher/consumer/execution-consumer.d.ts +121 -0
- package/dist/infra/cipher/consumer/execution-consumer.js +523 -0
- package/dist/infra/cipher/consumer/index.d.ts +33 -0
- package/dist/infra/cipher/consumer/index.js +33 -0
- package/dist/infra/cipher/consumer/queue-polling-service.d.ts +120 -0
- package/dist/infra/cipher/consumer/queue-polling-service.js +248 -0
- package/dist/infra/cipher/http/internal-llm-http-service.d.ts +94 -0
- package/dist/infra/cipher/http/internal-llm-http-service.js +118 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.d.ts +106 -0
- package/dist/infra/cipher/llm/context/compaction/compaction-service.js +132 -0
- package/dist/infra/cipher/llm/context/compaction/index.d.ts +9 -0
- package/dist/infra/cipher/llm/context/compaction/index.js +9 -0
- package/dist/infra/cipher/llm/context/context-manager.d.ts +46 -2
- package/dist/infra/cipher/llm/context/context-manager.js +68 -4
- package/dist/infra/cipher/llm/context/rw-lock.d.ts +72 -0
- package/dist/infra/cipher/llm/context/rw-lock.js +145 -0
- package/dist/infra/cipher/llm/generators/byterover-content-generator.d.ts +7 -7
- package/dist/infra/cipher/llm/generators/byterover-content-generator.js +8 -8
- package/dist/infra/cipher/llm/internal-llm-service.js +2 -0
- package/dist/infra/cipher/session/session-manager.d.ts +4 -4
- package/dist/infra/cipher/session/session-manager.js +5 -5
- package/dist/infra/cipher/storage/agent-storage.d.ts +246 -0
- package/dist/infra/cipher/storage/agent-storage.js +956 -0
- package/dist/infra/cipher/storage/dual-format-history-storage.d.ts +77 -0
- package/dist/infra/cipher/storage/dual-format-history-storage.js +149 -0
- package/dist/infra/cipher/storage/granular-history-storage.d.ts +65 -0
- package/dist/infra/cipher/storage/granular-history-storage.js +118 -0
- package/dist/infra/cipher/storage/message-storage-service.d.ts +108 -0
- package/dist/infra/cipher/storage/message-storage-service.js +529 -0
- package/dist/infra/cipher/storage/process-utils.d.ts +16 -0
- package/dist/infra/cipher/storage/process-utils.js +43 -0
- package/dist/infra/cipher/storage/sqlite-key-storage.d.ts +105 -0
- package/dist/infra/cipher/storage/sqlite-key-storage.js +404 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.d.ts +1 -0
- package/dist/infra/cipher/system-prompt/simple-prompt-factory.js +7 -0
- package/dist/infra/cipher/tools/default-policy-rules.js +1 -1
- package/dist/infra/cipher/tools/implementations/curate-tool.d.ts +10 -0
- package/dist/infra/cipher/tools/implementations/curate-tool.js +371 -0
- package/dist/infra/cipher/tools/implementations/find-knowledge-topics-tool.js +11 -8
- package/dist/infra/cipher/tools/tool-manager.d.ts +8 -2
- package/dist/infra/cipher/tools/tool-manager.js +29 -2
- package/dist/infra/cipher/tools/tool-registry.js +7 -0
- package/dist/infra/http/authenticated-http-client.d.ts +21 -0
- package/dist/infra/http/authenticated-http-client.js +38 -0
- package/dist/infra/repl/commands/arg-parser.d.ts +97 -0
- package/dist/infra/repl/commands/arg-parser.js +129 -0
- package/dist/infra/repl/commands/clear-command.d.ts +5 -0
- package/dist/infra/repl/commands/clear-command.js +61 -0
- package/dist/infra/repl/commands/curate-command.d.ts +9 -0
- package/dist/infra/repl/commands/curate-command.js +88 -0
- package/dist/infra/repl/commands/gen-rules-command.d.ts +7 -0
- package/dist/infra/repl/commands/gen-rules-command.js +38 -0
- package/dist/infra/repl/commands/index.d.ts +8 -0
- package/dist/infra/repl/commands/index.js +36 -0
- package/dist/infra/repl/commands/init-command.d.ts +7 -0
- package/dist/infra/repl/commands/init-command.js +83 -0
- package/dist/infra/repl/commands/login-command.d.ts +7 -0
- package/dist/infra/repl/commands/login-command.js +50 -0
- package/dist/infra/repl/commands/logout-command.d.ts +5 -0
- package/dist/infra/repl/commands/logout-command.js +48 -0
- package/dist/infra/repl/commands/pull-command.d.ts +5 -0
- package/dist/infra/repl/commands/pull-command.js +61 -0
- package/dist/infra/repl/commands/push-command.d.ts +5 -0
- package/dist/infra/repl/commands/push-command.js +66 -0
- package/dist/infra/repl/commands/query-command.d.ts +5 -0
- package/dist/infra/repl/commands/query-command.js +66 -0
- package/dist/infra/repl/commands/space/index.d.ts +5 -0
- package/dist/infra/repl/commands/space/index.js +14 -0
- package/dist/infra/repl/commands/space/list-command.d.ts +5 -0
- package/dist/infra/repl/commands/space/list-command.js +70 -0
- package/dist/infra/repl/commands/space/switch-command.d.ts +5 -0
- package/dist/infra/repl/commands/space/switch-command.js +37 -0
- package/dist/infra/repl/commands/status-command.d.ts +5 -0
- package/dist/infra/repl/commands/status-command.js +39 -0
- package/dist/infra/repl/repl-startup.d.ts +18 -0
- package/dist/infra/repl/repl-startup.js +26 -0
- package/dist/infra/storage/file-global-config-store.d.ts +22 -0
- package/dist/infra/storage/file-global-config-store.js +65 -0
- package/dist/infra/storage/file-onboarding-preference-store.d.ts +10 -0
- package/dist/infra/storage/file-onboarding-preference-store.js +46 -0
- package/dist/infra/terminal/oclif-terminal.d.ts +19 -0
- package/dist/infra/terminal/oclif-terminal.js +60 -0
- package/dist/infra/terminal/repl-terminal.d.ts +31 -0
- package/dist/infra/terminal/repl-terminal.js +116 -0
- package/dist/infra/tracking/mixpanel-tracking-service.d.ts +11 -1
- package/dist/infra/tracking/mixpanel-tracking-service.js +18 -13
- package/dist/infra/usecase/clear-use-case.d.ts +20 -0
- package/dist/infra/usecase/clear-use-case.js +58 -0
- package/dist/infra/usecase/curate-use-case.d.ts +66 -0
- package/dist/infra/usecase/curate-use-case.js +283 -0
- package/dist/{commands/gen-rules.d.ts → infra/usecase/generate-rules-use-case.d.ts} +14 -20
- package/dist/{commands/gen-rules.js → infra/usecase/generate-rules-use-case.js} +59 -78
- package/dist/infra/usecase/init-use-case.d.ts +139 -0
- package/dist/{commands/init.js → infra/usecase/init-use-case.js} +184 -230
- package/dist/infra/usecase/login-use-case.d.ts +28 -0
- package/dist/infra/usecase/login-use-case.js +88 -0
- package/dist/infra/usecase/logout-use-case.d.ts +22 -0
- package/dist/infra/usecase/logout-use-case.js +51 -0
- package/dist/infra/usecase/pull-use-case.d.ts +35 -0
- package/dist/infra/usecase/pull-use-case.js +89 -0
- package/dist/infra/usecase/push-use-case.d.ts +37 -0
- package/dist/infra/usecase/push-use-case.js +124 -0
- package/dist/infra/usecase/query-use-case.d.ts +78 -0
- package/dist/infra/usecase/query-use-case.js +401 -0
- package/dist/infra/usecase/space-list-use-case.d.ts +27 -0
- package/dist/infra/usecase/space-list-use-case.js +64 -0
- package/dist/infra/usecase/space-switch-use-case.d.ts +36 -0
- package/dist/infra/usecase/space-switch-use-case.js +140 -0
- package/dist/infra/usecase/status-use-case.d.ts +27 -0
- package/dist/infra/usecase/status-use-case.js +97 -0
- package/dist/infra/workspace/workspace-detector-service.d.ts +3 -6
- package/dist/resources/prompts/curate-context-tree-curation.yml +23 -11
- package/dist/resources/prompts/query-context-tree-retrieval.yml +3 -4
- package/dist/resources/prompts/system-prompt.yml +1 -1
- package/dist/resources/prompts/tool-outputs.yml +4 -3
- package/dist/templates/sections/command-reference.md +12 -0
- package/dist/templates/sections/workflow.md +10 -1
- package/dist/tui/app.d.ts +9 -0
- package/dist/tui/app.js +26 -0
- package/dist/tui/components/enter-prompt.d.ts +13 -0
- package/dist/tui/components/enter-prompt.js +15 -0
- package/dist/tui/components/execution/execution-changes.d.ts +14 -0
- package/dist/tui/components/execution/execution-changes.js +15 -0
- package/dist/tui/components/execution/execution-content.d.ts +25 -0
- package/dist/tui/components/execution/execution-content.js +67 -0
- package/dist/tui/components/execution/execution-input.d.ts +12 -0
- package/dist/tui/components/execution/execution-input.js +16 -0
- package/dist/tui/components/execution/execution-progress.d.ts +21 -0
- package/dist/tui/components/execution/execution-progress.js +21 -0
- package/dist/tui/components/execution/execution-status.d.ts +13 -0
- package/dist/tui/components/execution/execution-status.js +19 -0
- package/dist/tui/components/execution/index.d.ts +11 -0
- package/dist/tui/components/execution/index.js +11 -0
- package/dist/tui/components/execution/log-item.d.ts +17 -0
- package/dist/tui/components/execution/log-item.js +25 -0
- package/dist/tui/components/footer.d.ts +5 -0
- package/dist/tui/components/footer.js +12 -0
- package/dist/tui/components/header.d.ts +18 -0
- package/dist/tui/components/header.js +18 -0
- package/dist/tui/components/index.d.ts +17 -0
- package/dist/tui/components/index.js +14 -0
- package/dist/tui/components/inline-prompts/index.d.ts +15 -0
- package/dist/tui/components/inline-prompts/index.js +10 -0
- package/dist/tui/components/inline-prompts/inline-confirm.d.ts +17 -0
- package/dist/tui/components/inline-prompts/inline-confirm.js +32 -0
- package/dist/tui/components/inline-prompts/inline-file-selector.d.ts +43 -0
- package/dist/tui/components/inline-prompts/inline-file-selector.js +185 -0
- package/dist/tui/components/inline-prompts/inline-input.d.ts +19 -0
- package/dist/tui/components/inline-prompts/inline-input.js +32 -0
- package/dist/tui/components/inline-prompts/inline-search.d.ts +20 -0
- package/dist/tui/components/inline-prompts/inline-search.js +50 -0
- package/dist/tui/components/inline-prompts/inline-select.d.ts +20 -0
- package/dist/tui/components/inline-prompts/inline-select.js +34 -0
- package/dist/tui/components/logo.d.ts +43 -0
- package/dist/tui/components/logo.js +103 -0
- package/dist/tui/components/message-item.d.ts +12 -0
- package/dist/tui/components/message-item.js +12 -0
- package/dist/tui/components/onboarding/copyable-prompt.d.ts +15 -0
- package/dist/tui/components/onboarding/copyable-prompt.js +65 -0
- package/dist/tui/components/onboarding/index.d.ts +7 -0
- package/dist/tui/components/onboarding/index.js +6 -0
- package/dist/tui/components/onboarding/onboarding-flow.d.ts +13 -0
- package/dist/tui/components/onboarding/onboarding-flow.js +304 -0
- package/dist/tui/components/onboarding/onboarding-step.d.ts +23 -0
- package/dist/tui/components/onboarding/onboarding-step.js +12 -0
- package/dist/tui/components/output-log.d.ts +14 -0
- package/dist/tui/components/output-log.js +13 -0
- package/dist/tui/components/scrollable-list.d.ts +30 -0
- package/dist/tui/components/scrollable-list.js +121 -0
- package/dist/tui/components/suggestions.d.ts +16 -0
- package/dist/tui/components/suggestions.js +162 -0
- package/dist/tui/components/tab-bar.d.ts +10 -0
- package/dist/tui/components/tab-bar.js +12 -0
- package/dist/tui/constants.d.ts +11 -0
- package/dist/tui/constants.js +13 -0
- package/dist/tui/contexts/auth-context.d.ts +30 -0
- package/dist/tui/contexts/auth-context.js +153 -0
- package/dist/tui/contexts/consumer.d.ts +31 -0
- package/dist/tui/contexts/consumer.js +56 -0
- package/dist/tui/contexts/index.d.ts +6 -0
- package/dist/tui/contexts/index.js +6 -0
- package/dist/tui/contexts/onboarding-context.d.ts +43 -0
- package/dist/tui/contexts/onboarding-context.js +181 -0
- package/dist/tui/contexts/services-context.d.ts +29 -0
- package/dist/tui/contexts/services-context.js +20 -0
- package/dist/tui/contexts/use-commands.d.ts +29 -0
- package/dist/tui/contexts/use-commands.js +53 -0
- package/dist/tui/contexts/use-mode.d.ts +43 -0
- package/dist/tui/contexts/use-mode.js +76 -0
- package/dist/tui/contexts/use-theme.d.ts +53 -0
- package/dist/tui/contexts/use-theme.js +60 -0
- package/dist/tui/hooks/index.d.ts +17 -0
- package/dist/tui/hooks/index.js +14 -0
- package/dist/tui/hooks/use-activity-logs.d.ts +26 -0
- package/dist/tui/hooks/use-activity-logs.js +90 -0
- package/dist/tui/hooks/use-consumer.d.ts +12 -0
- package/dist/tui/hooks/use-consumer.js +50 -0
- package/dist/tui/hooks/use-onboarding.d.ts +7 -0
- package/dist/tui/hooks/use-onboarding.js +6 -0
- package/dist/tui/hooks/use-queue-polling.d.ts +31 -0
- package/dist/tui/hooks/use-queue-polling.js +90 -0
- package/dist/tui/hooks/use-slash-command-processor.d.ts +16 -0
- package/dist/tui/hooks/use-slash-command-processor.js +132 -0
- package/dist/tui/hooks/use-slash-completion.d.ts +30 -0
- package/dist/tui/hooks/use-slash-completion.js +230 -0
- package/dist/tui/hooks/use-tab-navigation.d.ts +10 -0
- package/dist/tui/hooks/use-tab-navigation.js +35 -0
- package/dist/tui/hooks/use-visible-window.d.ts +22 -0
- package/dist/tui/hooks/use-visible-window.js +37 -0
- package/dist/tui/index.d.ts +1 -0
- package/dist/tui/index.js +1 -0
- package/dist/tui/providers/app-providers.d.ts +25 -0
- package/dist/tui/providers/app-providers.js +9 -0
- package/dist/tui/types/commands.d.ts +252 -0
- package/dist/tui/types/commands.js +16 -0
- package/dist/tui/types/dialogs.d.ts +37 -0
- package/dist/tui/types/dialogs.js +4 -0
- package/dist/tui/types/index.d.ts +11 -0
- package/dist/tui/types/index.js +7 -0
- package/dist/tui/types/messages.d.ts +55 -0
- package/dist/tui/types/messages.js +4 -0
- package/dist/tui/types/prompts.d.ts +100 -0
- package/dist/tui/types/prompts.js +4 -0
- package/dist/tui/types/ui.d.ts +14 -0
- package/dist/tui/types/ui.js +4 -0
- package/dist/tui/types.d.ts +1 -0
- package/dist/tui/types.js +1 -0
- package/dist/tui/views/command-view.d.ts +12 -0
- package/dist/tui/views/command-view.js +451 -0
- package/dist/tui/views/index.d.ts +6 -0
- package/dist/tui/views/index.js +6 -0
- package/dist/tui/views/login-view.d.ts +10 -0
- package/dist/tui/views/login-view.js +30 -0
- package/dist/tui/views/logs-view.d.ts +11 -0
- package/dist/tui/views/logs-view.js +73 -0
- package/dist/utils/file-validator.d.ts +16 -0
- package/dist/utils/file-validator.js +81 -0
- package/dist/utils/global-config-path.d.ts +15 -0
- package/dist/utils/global-config-path.js +38 -0
- package/oclif.manifest.json +29 -315
- package/package.json +11 -4
- package/dist/commands/clear.d.ts +0 -19
- package/dist/commands/clear.js +0 -78
- package/dist/commands/init.d.ts +0 -130
- package/dist/commands/login.d.ts +0 -22
- package/dist/commands/login.js +0 -108
- package/dist/commands/logout.d.ts +0 -16
- package/dist/commands/logout.js +0 -61
- package/dist/commands/pull.d.ts +0 -33
- package/dist/commands/pull.js +0 -115
- package/dist/commands/push.d.ts +0 -35
- package/dist/commands/push.js +0 -160
- package/dist/commands/space/list.d.ts +0 -25
- package/dist/commands/space/list.js +0 -114
- package/dist/commands/space/switch.d.ts +0 -36
- package/dist/commands/space/switch.js +0 -160
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.d.ts +0 -149
- package/dist/infra/cipher/grpc/internal-llm-grpc-service.js +0 -364
- package/dist/infra/cipher/grpc/internal-llm-grpc.proto +0 -94
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SessionMetadata } from '../../../core/domain/cipher/storage/history-types.js';
|
|
2
|
+
import type { IHistoryStorage } from '../../../core/interfaces/cipher/i-history-storage.js';
|
|
3
|
+
import type { InternalMessage } from '../../../core/interfaces/cipher/message-types.js';
|
|
4
|
+
import type { BlobHistoryStorage } from './blob-history-storage.js';
|
|
5
|
+
import type { GranularHistoryStorage } from './granular-history-storage.js';
|
|
6
|
+
/**
|
|
7
|
+
* Dual-format history storage that routes between blob and granular storage.
|
|
8
|
+
*
|
|
9
|
+
* This router implements the "no migration" strategy:
|
|
10
|
+
* - NEW sessions → GranularHistoryStorage (message-per-key with streaming)
|
|
11
|
+
* - EXISTING sessions → BlobHistoryStorage (legacy single-blob format)
|
|
12
|
+
*
|
|
13
|
+
* Format detection:
|
|
14
|
+
* - Granular format: has a session record at ["session", sessionId]
|
|
15
|
+
* - Blob format: has a blob at "session-{sessionId}"
|
|
16
|
+
* - New session: neither exists, uses granular format
|
|
17
|
+
*
|
|
18
|
+
* This allows seamless coexistence of both formats without migration.
|
|
19
|
+
*/
|
|
20
|
+
export declare class DualFormatHistoryStorage implements IHistoryStorage {
|
|
21
|
+
private readonly blobStorage;
|
|
22
|
+
private readonly granularStorage;
|
|
23
|
+
constructor(blobStorage: BlobHistoryStorage, granularStorage: GranularHistoryStorage);
|
|
24
|
+
/**
|
|
25
|
+
* Delete all history for a session.
|
|
26
|
+
* Deletes from both storages to ensure complete cleanup.
|
|
27
|
+
*/
|
|
28
|
+
deleteHistory(sessionId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if history exists for a session in either format.
|
|
31
|
+
*/
|
|
32
|
+
exists(sessionId: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Get the underlying granular storage for advanced operations.
|
|
35
|
+
* Returns undefined if session is not in granular format.
|
|
36
|
+
*/
|
|
37
|
+
getGranularStorage(sessionId: string): Promise<GranularHistoryStorage | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* Get metadata for a session from appropriate storage.
|
|
40
|
+
*/
|
|
41
|
+
getSessionMetadata(sessionId: string): Promise<SessionMetadata | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Check if a session uses granular format.
|
|
44
|
+
* Useful for consumers that want to use granular-specific features.
|
|
45
|
+
*/
|
|
46
|
+
isGranularFormat(sessionId: string): Promise<boolean>;
|
|
47
|
+
/**
|
|
48
|
+
* List all session IDs from both storage formats.
|
|
49
|
+
*/
|
|
50
|
+
listSessions(): Promise<string[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Load conversation history for a session.
|
|
53
|
+
* Routes to appropriate storage based on session format.
|
|
54
|
+
*/
|
|
55
|
+
loadHistory(sessionId: string): Promise<InternalMessage[] | undefined>;
|
|
56
|
+
/**
|
|
57
|
+
* Save conversation history for a session.
|
|
58
|
+
* Routes to appropriate storage based on session format.
|
|
59
|
+
*
|
|
60
|
+
* New sessions use granular format.
|
|
61
|
+
* Existing sessions stay in their original format.
|
|
62
|
+
*/
|
|
63
|
+
saveHistory(sessionId: string, messages: InternalMessage[]): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Detect which storage format a session uses.
|
|
66
|
+
*
|
|
67
|
+
* Priority:
|
|
68
|
+
* 1. Granular format (check first as it's the newer format)
|
|
69
|
+
* 2. Blob format (legacy)
|
|
70
|
+
* 3. None (new session)
|
|
71
|
+
*/
|
|
72
|
+
private detectFormat;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Factory function to create DualFormatHistoryStorage.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createDualFormatHistoryStorage(blobStorage: BlobHistoryStorage, granularStorage: GranularHistoryStorage): DualFormatHistoryStorage;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual-format history storage that routes between blob and granular storage.
|
|
3
|
+
*
|
|
4
|
+
* This router implements the "no migration" strategy:
|
|
5
|
+
* - NEW sessions → GranularHistoryStorage (message-per-key with streaming)
|
|
6
|
+
* - EXISTING sessions → BlobHistoryStorage (legacy single-blob format)
|
|
7
|
+
*
|
|
8
|
+
* Format detection:
|
|
9
|
+
* - Granular format: has a session record at ["session", sessionId]
|
|
10
|
+
* - Blob format: has a blob at "session-{sessionId}"
|
|
11
|
+
* - New session: neither exists, uses granular format
|
|
12
|
+
*
|
|
13
|
+
* This allows seamless coexistence of both formats without migration.
|
|
14
|
+
*/
|
|
15
|
+
export class DualFormatHistoryStorage {
|
|
16
|
+
blobStorage;
|
|
17
|
+
granularStorage;
|
|
18
|
+
constructor(blobStorage, granularStorage) {
|
|
19
|
+
this.blobStorage = blobStorage;
|
|
20
|
+
this.granularStorage = granularStorage;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Delete all history for a session.
|
|
24
|
+
* Deletes from both storages to ensure complete cleanup.
|
|
25
|
+
*/
|
|
26
|
+
async deleteHistory(sessionId) {
|
|
27
|
+
const format = await this.detectFormat(sessionId);
|
|
28
|
+
if (format === 'granular') {
|
|
29
|
+
await this.granularStorage.deleteHistory(sessionId);
|
|
30
|
+
}
|
|
31
|
+
else if (format === 'blob') {
|
|
32
|
+
await this.blobStorage.deleteHistory(sessionId);
|
|
33
|
+
}
|
|
34
|
+
// For 'none', nothing to delete
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if history exists for a session in either format.
|
|
38
|
+
*/
|
|
39
|
+
async exists(sessionId) {
|
|
40
|
+
const format = await this.detectFormat(sessionId);
|
|
41
|
+
return format !== 'none';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get the underlying granular storage for advanced operations.
|
|
45
|
+
* Returns undefined if session is not in granular format.
|
|
46
|
+
*/
|
|
47
|
+
async getGranularStorage(sessionId) {
|
|
48
|
+
const format = await this.detectFormat(sessionId);
|
|
49
|
+
if (format === 'granular' || format === 'none') {
|
|
50
|
+
return this.granularStorage;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get metadata for a session from appropriate storage.
|
|
56
|
+
*/
|
|
57
|
+
async getSessionMetadata(sessionId) {
|
|
58
|
+
const format = await this.detectFormat(sessionId);
|
|
59
|
+
if (format === 'granular') {
|
|
60
|
+
return this.granularStorage.getSessionMetadata(sessionId);
|
|
61
|
+
}
|
|
62
|
+
if (format === 'blob') {
|
|
63
|
+
return this.blobStorage.getSessionMetadata(sessionId);
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a session uses granular format.
|
|
69
|
+
* Useful for consumers that want to use granular-specific features.
|
|
70
|
+
*/
|
|
71
|
+
async isGranularFormat(sessionId) {
|
|
72
|
+
const format = await this.detectFormat(sessionId);
|
|
73
|
+
return format === 'granular';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* List all session IDs from both storage formats.
|
|
77
|
+
*/
|
|
78
|
+
async listSessions() {
|
|
79
|
+
const [blobSessions, granularSessions] = await Promise.all([
|
|
80
|
+
this.blobStorage.listSessions(),
|
|
81
|
+
this.granularStorage.listSessions(),
|
|
82
|
+
]);
|
|
83
|
+
// Combine and deduplicate (shouldn't have duplicates, but be safe)
|
|
84
|
+
const allSessions = new Set([...blobSessions, ...granularSessions]);
|
|
85
|
+
return [...allSessions];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Load conversation history for a session.
|
|
89
|
+
* Routes to appropriate storage based on session format.
|
|
90
|
+
*/
|
|
91
|
+
async loadHistory(sessionId) {
|
|
92
|
+
const format = await this.detectFormat(sessionId);
|
|
93
|
+
if (format === 'granular') {
|
|
94
|
+
return this.granularStorage.loadHistory(sessionId);
|
|
95
|
+
}
|
|
96
|
+
if (format === 'blob') {
|
|
97
|
+
return this.blobStorage.loadHistory(sessionId);
|
|
98
|
+
}
|
|
99
|
+
// New session - return undefined (no history yet)
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Save conversation history for a session.
|
|
104
|
+
* Routes to appropriate storage based on session format.
|
|
105
|
+
*
|
|
106
|
+
* New sessions use granular format.
|
|
107
|
+
* Existing sessions stay in their original format.
|
|
108
|
+
*/
|
|
109
|
+
async saveHistory(sessionId, messages) {
|
|
110
|
+
const format = await this.detectFormat(sessionId);
|
|
111
|
+
if (format === 'granular') {
|
|
112
|
+
return this.granularStorage.saveHistory(sessionId, messages);
|
|
113
|
+
}
|
|
114
|
+
if (format === 'blob') {
|
|
115
|
+
// Keep existing blob sessions in blob format
|
|
116
|
+
return this.blobStorage.saveHistory(sessionId, messages);
|
|
117
|
+
}
|
|
118
|
+
// New session - use granular format
|
|
119
|
+
return this.granularStorage.saveHistory(sessionId, messages);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Detect which storage format a session uses.
|
|
123
|
+
*
|
|
124
|
+
* Priority:
|
|
125
|
+
* 1. Granular format (check first as it's the newer format)
|
|
126
|
+
* 2. Blob format (legacy)
|
|
127
|
+
* 3. None (new session)
|
|
128
|
+
*/
|
|
129
|
+
async detectFormat(sessionId) {
|
|
130
|
+
// Check granular format first (newer, preferred)
|
|
131
|
+
const isGranular = await this.granularStorage.exists(sessionId);
|
|
132
|
+
if (isGranular) {
|
|
133
|
+
return 'granular';
|
|
134
|
+
}
|
|
135
|
+
// Check blob format (legacy)
|
|
136
|
+
const isBlob = await this.blobStorage.exists(sessionId);
|
|
137
|
+
if (isBlob) {
|
|
138
|
+
return 'blob';
|
|
139
|
+
}
|
|
140
|
+
// New session
|
|
141
|
+
return 'none';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Factory function to create DualFormatHistoryStorage.
|
|
146
|
+
*/
|
|
147
|
+
export function createDualFormatHistoryStorage(blobStorage, granularStorage) {
|
|
148
|
+
return new DualFormatHistoryStorage(blobStorage, granularStorage);
|
|
149
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SessionMetadata } from '../../../core/domain/cipher/storage/history-types.js';
|
|
2
|
+
import type { IHistoryStorage } from '../../../core/interfaces/cipher/i-history-storage.js';
|
|
3
|
+
import type { InternalMessage } from '../../../core/interfaces/cipher/message-types.js';
|
|
4
|
+
import { MessageStorageService } from './message-storage-service.js';
|
|
5
|
+
/**
|
|
6
|
+
* Granular history storage implementation using MessageStorageService.
|
|
7
|
+
*
|
|
8
|
+
* This implementation stores messages individually, enabling:
|
|
9
|
+
* - Streaming message loading (newest to oldest)
|
|
10
|
+
* - Selective tool output pruning
|
|
11
|
+
* - Compaction boundary markers
|
|
12
|
+
*
|
|
13
|
+
* This is used for NEW sessions only. Existing sessions use BlobHistoryStorage.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GranularHistoryStorage implements IHistoryStorage {
|
|
16
|
+
private readonly messageStorage;
|
|
17
|
+
constructor(messageStorage: MessageStorageService);
|
|
18
|
+
/**
|
|
19
|
+
* Append a single message to the session.
|
|
20
|
+
* More efficient than saveHistory for incremental updates.
|
|
21
|
+
*/
|
|
22
|
+
appendMessage(sessionId: string, message: InternalMessage): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Delete all history for a session.
|
|
25
|
+
*/
|
|
26
|
+
deleteHistory(sessionId: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Check if history exists for a session.
|
|
29
|
+
*/
|
|
30
|
+
exists(sessionId: string): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Get metadata for a session without loading full history.
|
|
33
|
+
*/
|
|
34
|
+
getSessionMetadata(sessionId: string): Promise<SessionMetadata | undefined>;
|
|
35
|
+
/**
|
|
36
|
+
* List all session IDs with persisted history.
|
|
37
|
+
*/
|
|
38
|
+
listSessions(): Promise<string[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Load conversation history for a session.
|
|
41
|
+
* Stops at compaction boundaries for efficient loading.
|
|
42
|
+
*/
|
|
43
|
+
loadHistory(sessionId: string): Promise<InternalMessage[] | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Save conversation history for a session.
|
|
46
|
+
*
|
|
47
|
+
* This is a complete replacement - it's more efficient to use
|
|
48
|
+
* appendMessage() for incremental updates.
|
|
49
|
+
*/
|
|
50
|
+
saveHistory(sessionId: string, messages: InternalMessage[]): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Stream messages from newest to oldest.
|
|
53
|
+
* More memory efficient for large histories.
|
|
54
|
+
*
|
|
55
|
+
* @yields InternalMessage - Messages from the session history
|
|
56
|
+
*/
|
|
57
|
+
streamHistory(sessionId: string, options?: {
|
|
58
|
+
limit?: number;
|
|
59
|
+
stopAtCompaction?: boolean;
|
|
60
|
+
}): AsyncGenerator<InternalMessage>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Factory function to create GranularHistoryStorage.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createGranularHistoryStorage(messageStorage: MessageStorageService): GranularHistoryStorage;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Granular history storage implementation using MessageStorageService.
|
|
3
|
+
*
|
|
4
|
+
* This implementation stores messages individually, enabling:
|
|
5
|
+
* - Streaming message loading (newest to oldest)
|
|
6
|
+
* - Selective tool output pruning
|
|
7
|
+
* - Compaction boundary markers
|
|
8
|
+
*
|
|
9
|
+
* This is used for NEW sessions only. Existing sessions use BlobHistoryStorage.
|
|
10
|
+
*/
|
|
11
|
+
export class GranularHistoryStorage {
|
|
12
|
+
messageStorage;
|
|
13
|
+
constructor(messageStorage) {
|
|
14
|
+
this.messageStorage = messageStorage;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Append a single message to the session.
|
|
18
|
+
* More efficient than saveHistory for incremental updates.
|
|
19
|
+
*/
|
|
20
|
+
async appendMessage(sessionId, message) {
|
|
21
|
+
await this.messageStorage.saveMessage(sessionId, message);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Delete all history for a session.
|
|
25
|
+
*/
|
|
26
|
+
async deleteHistory(sessionId) {
|
|
27
|
+
await this.messageStorage.deleteSession(sessionId);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if history exists for a session.
|
|
31
|
+
*/
|
|
32
|
+
async exists(sessionId) {
|
|
33
|
+
return this.messageStorage.hasSession(sessionId);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get metadata for a session without loading full history.
|
|
37
|
+
*/
|
|
38
|
+
async getSessionMetadata(sessionId) {
|
|
39
|
+
const session = await this.messageStorage.getSession(sessionId);
|
|
40
|
+
if (!session) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
createdAt: session.createdAt,
|
|
45
|
+
lastActivity: session.updatedAt,
|
|
46
|
+
messageCount: session.messageCount,
|
|
47
|
+
sessionId: session.sessionId,
|
|
48
|
+
title: session.title,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* List all session IDs with persisted history.
|
|
53
|
+
*/
|
|
54
|
+
async listSessions() {
|
|
55
|
+
return this.messageStorage.listSessions();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load conversation history for a session.
|
|
59
|
+
* Stops at compaction boundaries for efficient loading.
|
|
60
|
+
*/
|
|
61
|
+
async loadHistory(sessionId) {
|
|
62
|
+
const hasSession = await this.messageStorage.hasSession(sessionId);
|
|
63
|
+
if (!hasSession) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
const result = await this.messageStorage.loadMessages(sessionId, { stopAtCompaction: true });
|
|
67
|
+
return this.messageStorage.toInternalMessages(result.messages);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Save conversation history for a session.
|
|
71
|
+
*
|
|
72
|
+
* This is a complete replacement - it's more efficient to use
|
|
73
|
+
* appendMessage() for incremental updates.
|
|
74
|
+
*/
|
|
75
|
+
async saveHistory(sessionId, messages) {
|
|
76
|
+
// Check if session exists
|
|
77
|
+
const existingSession = await this.messageStorage.getSession(sessionId);
|
|
78
|
+
if (existingSession) {
|
|
79
|
+
// For existing sessions, we need to detect what's new
|
|
80
|
+
// Load existing messages to find the last one
|
|
81
|
+
const existingResult = await this.messageStorage.loadMessages(sessionId, { stopAtCompaction: false });
|
|
82
|
+
const existingCount = existingResult.messages.length;
|
|
83
|
+
if (messages.length > existingCount) {
|
|
84
|
+
// Append only new messages
|
|
85
|
+
const newMessages = messages.slice(existingCount);
|
|
86
|
+
await this.messageStorage.saveMessages(sessionId, newMessages);
|
|
87
|
+
}
|
|
88
|
+
// If messages.length <= existingCount, nothing to do
|
|
89
|
+
// We don't delete messages in this implementation
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// New session - save all messages
|
|
93
|
+
await this.messageStorage.saveMessages(sessionId, messages);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Stream messages from newest to oldest.
|
|
98
|
+
* More memory efficient for large histories.
|
|
99
|
+
*
|
|
100
|
+
* @yields InternalMessage - Messages from the session history
|
|
101
|
+
*/
|
|
102
|
+
async *streamHistory(sessionId, options) {
|
|
103
|
+
const stream = this.messageStorage.streamMessages({
|
|
104
|
+
limit: options?.limit,
|
|
105
|
+
sessionId,
|
|
106
|
+
stopAtCompaction: options?.stopAtCompaction ?? true,
|
|
107
|
+
});
|
|
108
|
+
for await (const storedMessage of stream) {
|
|
109
|
+
yield this.messageStorage.toInternalMessage(storedMessage);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Factory function to create GranularHistoryStorage.
|
|
115
|
+
*/
|
|
116
|
+
export function createGranularHistoryStorage(messageStorage) {
|
|
117
|
+
return new GranularHistoryStorage(messageStorage);
|
|
118
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { CompactionResult, LoadMessagesResult, PruneToolOutputsOptions, SessionRecord, StoredMessage, StoredMessageWithParts, StreamMessagesOptions } from '../../../core/domain/cipher/storage/message-storage-types.js';
|
|
2
|
+
import type { IKeyStorage } from '../../../core/interfaces/cipher/i-key-storage.js';
|
|
3
|
+
import type { InternalMessage } from '../../../core/interfaces/cipher/message-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Service for granular message and part storage.
|
|
6
|
+
*
|
|
7
|
+
* Handles the conversion between InternalMessage format and the granular
|
|
8
|
+
* StoredMessage/StoredPart format, enabling:
|
|
9
|
+
* - Streaming message loading (newest to oldest)
|
|
10
|
+
* - Selective tool output pruning
|
|
11
|
+
* - Compaction boundary markers
|
|
12
|
+
*
|
|
13
|
+
* Key structure:
|
|
14
|
+
* - ["session", sessionId] → SessionRecord
|
|
15
|
+
* - ["message", sessionId, messageId] → StoredMessage
|
|
16
|
+
* - ["part", messageId, partId] → StoredPart
|
|
17
|
+
*/
|
|
18
|
+
export declare class MessageStorageService {
|
|
19
|
+
private readonly keyStorage;
|
|
20
|
+
constructor(keyStorage: IKeyStorage);
|
|
21
|
+
/**
|
|
22
|
+
* Delete a session and all its messages and parts.
|
|
23
|
+
*/
|
|
24
|
+
deleteSession(sessionId: string): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Get the session record, if it exists.
|
|
27
|
+
*/
|
|
28
|
+
getSession(sessionId: string): Promise<SessionRecord | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a session exists in granular format.
|
|
31
|
+
*/
|
|
32
|
+
hasSession(sessionId: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Insert a compaction boundary marker.
|
|
35
|
+
* Creates a special message that signals where to stop loading history.
|
|
36
|
+
*/
|
|
37
|
+
insertCompactionBoundary(sessionId: string, summary: string): Promise<StoredMessage>;
|
|
38
|
+
/**
|
|
39
|
+
* List all session IDs in granular format.
|
|
40
|
+
*/
|
|
41
|
+
listSessions(): Promise<string[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Load messages from a session, stopping at compaction boundary.
|
|
44
|
+
* Returns messages in chronological order (oldest first).
|
|
45
|
+
*/
|
|
46
|
+
loadMessages(sessionId: string, options?: {
|
|
47
|
+
stopAtCompaction?: boolean;
|
|
48
|
+
}): Promise<LoadMessagesResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Prune old tool outputs by marking them as compacted.
|
|
51
|
+
* Keeps the most recent tool outputs up to the specified token limit.
|
|
52
|
+
*/
|
|
53
|
+
pruneToolOutputs(options: PruneToolOutputsOptions): Promise<CompactionResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Save a single message with its parts.
|
|
56
|
+
* Updates the session record to maintain linked list pointers.
|
|
57
|
+
*/
|
|
58
|
+
saveMessage(sessionId: string, message: InternalMessage): Promise<StoredMessage>;
|
|
59
|
+
/**
|
|
60
|
+
* Save multiple messages in order.
|
|
61
|
+
* More efficient than calling saveMessage multiple times.
|
|
62
|
+
*/
|
|
63
|
+
saveMessages(sessionId: string, messages: InternalMessage[]): Promise<StoredMessage[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Create or update a session record.
|
|
66
|
+
*/
|
|
67
|
+
saveSession(session: SessionRecord): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Stream messages from newest to oldest using an async generator.
|
|
70
|
+
* More memory efficient for large histories.
|
|
71
|
+
*
|
|
72
|
+
* @yields StoredMessageWithParts - Messages from the session history
|
|
73
|
+
*/
|
|
74
|
+
streamMessages(options: StreamMessagesOptions): AsyncGenerator<StoredMessageWithParts>;
|
|
75
|
+
/**
|
|
76
|
+
* Convert a single stored message with parts back to InternalMessage format.
|
|
77
|
+
*/
|
|
78
|
+
toInternalMessage(message: StoredMessageWithParts): InternalMessage;
|
|
79
|
+
/**
|
|
80
|
+
* Convert loaded messages back to InternalMessage format.
|
|
81
|
+
*/
|
|
82
|
+
toInternalMessages(messages: StoredMessageWithParts[]): InternalMessage[];
|
|
83
|
+
/**
|
|
84
|
+
* Extract parts from an InternalMessage.
|
|
85
|
+
*/
|
|
86
|
+
private extractParts;
|
|
87
|
+
/**
|
|
88
|
+
* Load parts for a message.
|
|
89
|
+
*/
|
|
90
|
+
private loadParts;
|
|
91
|
+
private messageKey;
|
|
92
|
+
private messagePrefix;
|
|
93
|
+
private partKey;
|
|
94
|
+
private partPrefix;
|
|
95
|
+
/**
|
|
96
|
+
* Serialize file content for storage.
|
|
97
|
+
*/
|
|
98
|
+
private serializeFileContent;
|
|
99
|
+
/**
|
|
100
|
+
* Serialize image content for storage.
|
|
101
|
+
*/
|
|
102
|
+
private serializeImageContent;
|
|
103
|
+
private sessionKey;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Factory function to create MessageStorageService.
|
|
107
|
+
*/
|
|
108
|
+
export declare function createMessageStorageService(keyStorage: IKeyStorage): MessageStorageService;
|