devchain-cli 0.23.1 → 0.23.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/drizzle/0083_retire_documents.sql +2 -0
- package/dist/drizzle/0084_retire_codebase_overview.sql +1 -0
- package/dist/drizzle/0085_clumsy_zodiak.sql +166 -0
- package/dist/drizzle/meta/0083_snapshot.json +7422 -0
- package/dist/drizzle/meta/0084_snapshot.json +7422 -0
- package/dist/drizzle/meta/0085_snapshot.json +7446 -0
- package/dist/drizzle/meta/_journal.json +21 -0
- package/dist/server/app.main.module.js +0 -4
- package/dist/server/app.main.module.js.map +1 -1
- package/dist/server/app.normal.module.js +0 -4
- package/dist/server/app.normal.module.js.map +1 -1
- package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.d.ts +1 -0
- package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.js +48 -0
- package/dist/server/modules/epic-time/controllers/external-estimate-log.controller.js.map +1 -1
- package/dist/server/modules/epic-time/models/epic-time.models.d.ts +10 -0
- package/dist/server/modules/epic-time/services/epic-estimate-logging.service.d.ts +4 -1
- package/dist/server/modules/epic-time/services/epic-estimate-logging.service.js +43 -1
- package/dist/server/modules/epic-time/services/epic-estimate-logging.service.js.map +1 -1
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.d.ts +1 -0
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js +31 -1
- package/dist/server/modules/epics/subscribers/epic-assignment-notifier.subscriber.js.map +1 -1
- package/dist/server/modules/external-integrations/connections/stable-integration-connection.d.ts +14 -0
- package/dist/server/modules/external-integrations/connections/stable-integration-connection.js +56 -0
- package/dist/server/modules/external-integrations/connections/stable-integration-connection.js.map +1 -0
- package/dist/server/modules/external-integrations/my-work/external-edit-session.service.d.ts +2 -1
- package/dist/server/modules/external-integrations/my-work/external-edit-session.service.js +51 -33
- package/dist/server/modules/external-integrations/my-work/external-edit-session.service.js.map +1 -1
- package/dist/server/modules/external-integrations/my-work/external-my-work.controller.js +2 -2
- package/dist/server/modules/external-integrations/my-work/external-my-work.controller.js.map +1 -1
- package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.d.ts +1 -0
- package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.js +33 -1
- package/dist/server/modules/external-integrations/my-work/external-my-work.openapi.js.map +1 -1
- package/dist/server/modules/external-integrations/my-work/external-my-work.service.d.ts +1 -1
- package/dist/server/modules/external-integrations/my-work/external-my-work.service.js +41 -48
- package/dist/server/modules/external-integrations/my-work/external-my-work.service.js.map +1 -1
- package/dist/server/modules/external-integrations/my-work/external-time-mutation.service.js +24 -11
- package/dist/server/modules/external-integrations/my-work/external-time-mutation.service.js.map +1 -1
- package/dist/server/modules/external-integrations/sessions/external-edit-session.store.js +3 -1
- package/dist/server/modules/external-integrations/sessions/external-edit-session.store.js.map +1 -1
- package/dist/server/modules/mcp/constants.d.ts +0 -2
- package/dist/server/modules/mcp/constants.js +1 -11
- package/dist/server/modules/mcp/constants.js.map +1 -1
- package/dist/server/modules/mcp/dtos/mcp.dto.d.ts +0 -165
- package/dist/server/modules/mcp/dtos/mcp.dto.js +1 -47
- package/dist/server/modules/mcp/dtos/mcp.dto.js.map +1 -1
- package/dist/server/modules/mcp/services/instructions-resolver.d.ts +4 -13
- package/dist/server/modules/mcp/services/instructions-resolver.js +26 -166
- package/dist/server/modules/mcp/services/instructions-resolver.js.map +1 -1
- package/dist/server/modules/mcp/services/mappers/dto-mappers.d.ts +2 -4
- package/dist/server/modules/mcp/services/mappers/dto-mappers.js +0 -22
- package/dist/server/modules/mcp/services/mappers/dto-mappers.js.map +1 -1
- package/dist/server/modules/mcp/services/mcp-tool-binding.registry.js +1 -2
- package/dist/server/modules/mcp/services/mcp-tool-binding.registry.js.map +1 -1
- package/dist/server/modules/mcp/services/utils/resource-resolver.d.ts +2 -4
- package/dist/server/modules/mcp/services/utils/resource-resolver.js +0 -59
- package/dist/server/modules/mcp/services/utils/resource-resolver.js.map +1 -1
- package/dist/server/modules/mcp/tool-descriptors/index.js +0 -2
- package/dist/server/modules/mcp/tool-descriptors/index.js.map +1 -1
- package/dist/server/modules/mcp/tool-descriptors/runtime-bindings.js +0 -2
- package/dist/server/modules/mcp/tool-descriptors/runtime-bindings.js.map +1 -1
- package/dist/server/modules/projects/helpers/project-import.d.ts +0 -33
- package/dist/server/modules/projects/helpers/project-import.js +0 -224
- package/dist/server/modules/projects/helpers/project-import.js.map +1 -1
- package/dist/server/modules/projects/services/project-registry-import.service.d.ts +3 -6
- package/dist/server/modules/projects/services/project-registry-import.service.js +7 -28
- package/dist/server/modules/projects/services/project-registry-import.service.js.map +1 -1
- package/dist/server/modules/projects/template-codec/codecs/teams.codec.js.map +1 -1
- package/dist/server/modules/registry/controllers/registry.controller.js +3 -10
- package/dist/server/modules/registry/controllers/registry.controller.js.map +1 -1
- package/dist/server/modules/registry/services/registry-orchestration.service.d.ts +11 -3
- package/dist/server/modules/registry/services/registry-orchestration.service.js +6 -1
- package/dist/server/modules/registry/services/registry-orchestration.service.js.map +1 -1
- package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.d.ts +8 -0
- package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js +9 -0
- package/dist/server/modules/session-reader/adapters/claude-session-reader.adapter.js.map +1 -1
- package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.d.ts +10 -0
- package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js +13 -0
- package/dist/server/modules/session-reader/adapters/codex-session-reader.adapter.js.map +1 -1
- package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.d.ts +20 -1
- package/dist/server/modules/session-reader/adapters/session-reader-adapter.interface.js.map +1 -1
- package/dist/server/modules/session-reader/controllers/session-reader.controller.d.ts +21 -1
- package/dist/server/modules/session-reader/controllers/session-reader.controller.js +49 -3
- package/dist/server/modules/session-reader/controllers/session-reader.controller.js.map +1 -1
- package/dist/server/modules/session-reader/data/pricing.json +2052 -178
- package/dist/server/modules/session-reader/parsers/bounded-line-read.d.ts +2 -0
- package/dist/server/modules/session-reader/parsers/bounded-line-read.js +66 -0
- package/dist/server/modules/session-reader/parsers/bounded-line-read.js.map +1 -0
- package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.d.ts +6 -0
- package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js +44 -13
- package/dist/server/modules/session-reader/parsers/claude-jsonl.parser.js.map +1 -1
- package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.d.ts +22 -0
- package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js +61 -16
- package/dist/server/modules/session-reader/parsers/codex-jsonl.parser.js.map +1 -1
- package/dist/server/modules/session-reader/services/bounded-anchor-proof.d.ts +12 -0
- package/dist/server/modules/session-reader/services/bounded-anchor-proof.js +103 -0
- package/dist/server/modules/session-reader/services/bounded-anchor-proof.js.map +1 -0
- package/dist/server/modules/session-reader/services/metrics-merge.d.ts +17 -0
- package/dist/server/modules/session-reader/services/metrics-merge.js +114 -0
- package/dist/server/modules/session-reader/services/metrics-merge.js.map +1 -0
- package/dist/server/modules/session-reader/services/session-cache.service.d.ts +40 -4
- package/dist/server/modules/session-reader/services/session-cache.service.js +232 -148
- package/dist/server/modules/session-reader/services/session-cache.service.js.map +1 -1
- package/dist/server/modules/session-reader/services/session-reader.service.d.ts +15 -1
- package/dist/server/modules/session-reader/services/session-reader.service.js +70 -2
- package/dist/server/modules/session-reader/services/session-reader.service.js.map +1 -1
- package/dist/server/modules/session-reader/services/transcript-watcher.service.d.ts +20 -3
- package/dist/server/modules/session-reader/services/transcript-watcher.service.js +538 -197
- package/dist/server/modules/session-reader/services/transcript-watcher.service.js.map +1 -1
- package/dist/server/modules/sessions/controllers/sessions.controller.d.ts +4 -1
- package/dist/server/modules/sessions/controllers/sessions.controller.js +32 -0
- package/dist/server/modules/sessions/controllers/sessions.controller.js.map +1 -1
- package/dist/server/modules/sessions/services/message-pool.types.d.ts +23 -0
- package/dist/server/modules/sessions/services/sessions-message-pool.service.d.ts +5 -2
- package/dist/server/modules/sessions/services/sessions-message-pool.service.js +82 -4
- package/dist/server/modules/sessions/services/sessions-message-pool.service.js.map +1 -1
- package/dist/server/modules/storage/db/schema.d.ts +57 -219
- package/dist/server/modules/storage/db/schema.js +15 -27
- package/dist/server/modules/storage/db/schema.js.map +1 -1
- package/dist/server/modules/storage/interfaces/storage.interface.d.ts +6 -23
- package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
- package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.d.ts +6 -1
- package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.js +163 -32
- package/dist/server/modules/storage/local/delegates/external-estimate-log.delegate.js.map +1 -1
- package/dist/server/modules/storage/local/delegates/external-managed-subtask.delegate.js +11 -1
- package/dist/server/modules/storage/local/delegates/external-managed-subtask.delegate.js.map +1 -1
- package/dist/server/modules/storage/local/delegates/integration.delegate.d.ts +1 -1
- package/dist/server/modules/storage/local/delegates/integration.delegate.js +17 -13
- package/dist/server/modules/storage/local/delegates/integration.delegate.js.map +1 -1
- package/dist/server/modules/storage/local/delegates/project.delegate.js +1 -10
- package/dist/server/modules/storage/local/delegates/project.delegate.js.map +1 -1
- package/dist/server/modules/storage/local/local-storage.service.d.ts +6 -9
- package/dist/server/modules/storage/local/local-storage.service.js +8 -22
- package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
- package/dist/server/modules/storage/models/domain.models.d.ts +14 -20
- package/dist/server/modules/storage/models/domain.models.js +2 -1
- package/dist/server/modules/storage/models/domain.models.js.map +1 -1
- package/dist/server/modules/terminal/services/human-prompt-state.service.d.ts +7 -0
- package/dist/server/modules/terminal/services/human-prompt-state.service.js +26 -0
- package/dist/server/modules/terminal/services/human-prompt-state.service.js.map +1 -1
- package/dist/server/modules/terminal/services/terminal-session/terminal-session.js +3 -2
- package/dist/server/modules/terminal/services/terminal-session/terminal-session.js.map +1 -1
- package/dist/server/modules/terminal/utils/terminal-activity.js +8 -1
- package/dist/server/modules/terminal/utils/terminal-activity.js.map +1 -1
- package/dist/server/templates/teams-dev.json +2 -2
- package/dist/server/tsconfig.tsbuildinfo +1 -1
- package/dist/server/ui/assets/{ExternalRichEditor-FwCAalXO.js → ExternalRichEditor-akgwTdms.js} +24 -24
- package/dist/server/ui/assets/ReviewDetailPage-10JU-Gdr.js +1 -0
- package/dist/server/ui/assets/ReviewsPage-BIVn-pS5.js +6 -0
- package/dist/server/ui/assets/index-Bg8fZbSZ.css +32 -0
- package/dist/server/ui/assets/index-DHmiffN1.js +1000 -0
- package/dist/server/ui/assets/useReviewSubscription-Xua63feT.js +69 -0
- package/dist/server/ui/index.html +2 -2
- package/dist/templates/teams-dev.json +2 -2
- package/package.json +13 -1
- package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.js +0 -52
- package/dist/server/modules/codebase-overview-analyzer/codebase-overview-analyzer.module.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.d.ts +0 -30
- package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.js +0 -230
- package/dist/server/modules/codebase-overview-analyzer/controllers/codebase-overview.controller.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.d.ts +0 -24
- package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.js +0 -191
- package/dist/server/modules/codebase-overview-analyzer/repositories/overview-scope.repository.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.d.ts +0 -73
- package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.js +0 -1133
- package/dist/server/modules/codebase-overview-analyzer/services/codebase-overview-analyzer.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.d.ts +0 -14
- package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.js +0 -114
- package/dist/server/modules/codebase-overview-analyzer/services/dependency-aggregation.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.d.ts +0 -8
- package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.js +0 -200
- package/dist/server/modules/codebase-overview-analyzer/services/district-splitting.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.d.ts +0 -11
- package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.js +0 -164
- package/dist/server/modules/codebase-overview-analyzer/services/evidence-query.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.js +0 -166
- package/dist/server/modules/codebase-overview-analyzer/services/go-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.d.ts +0 -21
- package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.js +0 -253
- package/dist/server/modules/codebase-overview-analyzer/services/hotspot-scoring.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.d.ts +0 -24
- package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.js +0 -98
- package/dist/server/modules/codebase-overview-analyzer/services/identity-resolver.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.js +0 -155
- package/dist/server/modules/codebase-overview-analyzer/services/java-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.d.ts +0 -19
- package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.js +0 -88
- package/dist/server/modules/codebase-overview-analyzer/services/language-adapter-registry.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.js +0 -173
- package/dist/server/modules/codebase-overview-analyzer/services/php-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.js +0 -171
- package/dist/server/modules/codebase-overview-analyzer/services/python-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.js +0 -158
- package/dist/server/modules/codebase-overview-analyzer/services/ruby-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.js +0 -222
- package/dist/server/modules/codebase-overview-analyzer/services/rust-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.d.ts +0 -4
- package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.js +0 -72
- package/dist/server/modules/codebase-overview-analyzer/services/scope-auto-detector.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.d.ts +0 -6
- package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.js +0 -37
- package/dist/server/modules/codebase-overview-analyzer/services/scope-resolver.service.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.js +0 -108
- package/dist/server/modules/codebase-overview-analyzer/services/typescript-adapter.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/types/index.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/types/index.js +0 -6
- package/dist/server/modules/codebase-overview-analyzer/types/index.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/types/overview.types.d.ts +0 -231
- package/dist/server/modules/codebase-overview-analyzer/types/overview.types.js +0 -3
- package/dist/server/modules/codebase-overview-analyzer/types/overview.types.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.js +0 -13
- package/dist/server/modules/codebase-overview-analyzer/types/scope-defaults.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.d.ts +0 -54
- package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.js +0 -27
- package/dist/server/modules/codebase-overview-analyzer/types/scope.schema.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/types/scope.types.d.ts +0 -12
- package/dist/server/modules/codebase-overview-analyzer/types/scope.types.js +0 -3
- package/dist/server/modules/codebase-overview-analyzer/types/scope.types.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/utils/constants.d.ts +0 -1
- package/dist/server/modules/codebase-overview-analyzer/utils/constants.js +0 -5
- package/dist/server/modules/codebase-overview-analyzer/utils/constants.js.map +0 -1
- package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.d.ts +0 -2
- package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.js +0 -17
- package/dist/server/modules/codebase-overview-analyzer/utils/path-matcher.js.map +0 -1
- package/dist/server/modules/documents/controllers/documents.controller.d.ts +0 -12
- package/dist/server/modules/documents/controllers/documents.controller.js +0 -174
- package/dist/server/modules/documents/controllers/documents.controller.js.map +0 -1
- package/dist/server/modules/documents/documents.module.d.ts +0 -2
- package/dist/server/modules/documents/documents.module.js +0 -22
- package/dist/server/modules/documents/documents.module.js.map +0 -1
- package/dist/server/modules/mcp/services/handlers/document-context.d.ts +0 -8
- package/dist/server/modules/mcp/services/handlers/document-context.js +0 -3
- package/dist/server/modules/mcp/services/handlers/document-context.js.map +0 -1
- package/dist/server/modules/mcp/services/handlers/document-tools.d.ts +0 -6
- package/dist/server/modules/mcp/services/handlers/document-tools.js +0 -109
- package/dist/server/modules/mcp/services/handlers/document-tools.js.map +0 -1
- package/dist/server/modules/mcp/services/utils/document-link-resolver.d.ts +0 -10
- package/dist/server/modules/mcp/services/utils/document-link-resolver.js +0 -124
- package/dist/server/modules/mcp/services/utils/document-link-resolver.js.map +0 -1
- package/dist/server/modules/mcp/tool-descriptors/document.bindings.d.ts +0 -1
- package/dist/server/modules/mcp/tool-descriptors/document.bindings.js +0 -19
- package/dist/server/modules/mcp/tool-descriptors/document.bindings.js.map +0 -1
- package/dist/server/modules/mcp/tool-descriptors/document.metadata.d.ts +0 -2
- package/dist/server/modules/mcp/tool-descriptors/document.metadata.js +0 -96
- package/dist/server/modules/mcp/tool-descriptors/document.metadata.js.map +0 -1
- package/dist/server/modules/storage/local/delegates/document.delegate.d.ts +0 -18
- package/dist/server/modules/storage/local/delegates/document.delegate.js +0 -275
- package/dist/server/modules/storage/local/delegates/document.delegate.js.map +0 -1
- package/dist/server/ui/assets/ReviewDetailPage-D8DVpsJm.js +0 -1
- package/dist/server/ui/assets/ReviewsPage-DcWpRFbm.js +0 -6
- package/dist/server/ui/assets/index-CV8ydm7w.css +0 -32
- package/dist/server/ui/assets/index-Cwe7LxcW.js +0 -1197
- package/dist/server/ui/assets/useReviewSubscription-CYoSg-88.js +0 -69
|
@@ -51,15 +51,17 @@ exports.getTranscriptCacheConfig = getTranscriptCacheConfig;
|
|
|
51
51
|
const common_1 = require("@nestjs/common");
|
|
52
52
|
const node_crypto_1 = require("node:crypto");
|
|
53
53
|
const fs = __importStar(require("node:fs/promises"));
|
|
54
|
-
const estimate_content_tokens_1 = require("../adapters/utils/estimate-content-tokens");
|
|
55
|
-
const tool_result_fold_1 = require("../adapters/utils/tool-result-fold");
|
|
56
54
|
const coalesce_turns_1 = require("../adapters/utils/coalesce-turns");
|
|
55
|
+
const metrics_merge_1 = require("./metrics-merge");
|
|
56
|
+
const bounded_anchor_proof_1 = require("./bounded-anchor-proof");
|
|
57
|
+
const bounded_line_read_1 = require("../parsers/bounded-line-read");
|
|
57
58
|
const metrics_service_1 = require("../../metrics/services/metrics.service");
|
|
59
|
+
const chunk_builder_1 = require("../builders/chunk-builder");
|
|
58
60
|
const DEFAULT_CACHE_IDLE_TTL_MS = 10 * 60 * 1_000;
|
|
59
61
|
const DEFAULT_CACHE_SWEEP_INTERVAL_MS = 60_000;
|
|
60
62
|
const DEFAULT_CACHE_BUDGET_BYTES = 64 * 1024 * 1024;
|
|
61
63
|
const SAFE_INTEGER_LOW_BITS = 0x20_0000;
|
|
62
|
-
const
|
|
64
|
+
const FULL_PARSE_COST_CAP = 256;
|
|
63
65
|
function fileSourceVersion(stat) {
|
|
64
66
|
const digest = (0, node_crypto_1.createHash)('sha256')
|
|
65
67
|
.update(`${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`)
|
|
@@ -78,6 +80,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
78
80
|
metricsService;
|
|
79
81
|
logger = new common_1.Logger(SessionCacheService_1.name);
|
|
80
82
|
cache = new Map();
|
|
83
|
+
parseFlights = new Map();
|
|
84
|
+
flightGeneration = 0;
|
|
81
85
|
hits = 0;
|
|
82
86
|
misses = 0;
|
|
83
87
|
chunksHits = 0;
|
|
@@ -86,6 +90,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
86
90
|
dtoMisses = 0;
|
|
87
91
|
budgetUsedBytes = 0;
|
|
88
92
|
evictions = 0;
|
|
93
|
+
fullParseSeq = 0;
|
|
94
|
+
fullParseCosts = new Map();
|
|
89
95
|
idleSweepTimer;
|
|
90
96
|
config;
|
|
91
97
|
constructor(metricsService, config) {
|
|
@@ -104,6 +110,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
104
110
|
this.idleSweepTimer = undefined;
|
|
105
111
|
}
|
|
106
112
|
this.clear();
|
|
113
|
+
this.fullParseCosts.clear();
|
|
107
114
|
}
|
|
108
115
|
getCacheStats() {
|
|
109
116
|
const total = this.hits + this.misses;
|
|
@@ -159,6 +166,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
159
166
|
if (!cached)
|
|
160
167
|
return undefined;
|
|
161
168
|
const ref = this.toSourceRef(source, adapter);
|
|
169
|
+
if (cached.sourceIdentity !== this.sourceIdentity(ref))
|
|
170
|
+
return undefined;
|
|
162
171
|
const freshness = await this.computeFreshness(ref, adapter);
|
|
163
172
|
return this.takeFreshCachedSession(sessionId, cached, freshness.token, Date.now());
|
|
164
173
|
}
|
|
@@ -169,20 +178,158 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
169
178
|
return this.getOrParseResult(sessionId, source, adapter);
|
|
170
179
|
}
|
|
171
180
|
async getOrParseResult(sessionId, source, adapter) {
|
|
181
|
+
const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
|
|
182
|
+
const arrivalGeneration = this.flightGeneration;
|
|
183
|
+
const existing = this.parseFlights.get(sessionId);
|
|
184
|
+
if (!existing) {
|
|
185
|
+
return (await this.startParseFlight(sessionId, source, adapter).promise).result;
|
|
186
|
+
}
|
|
187
|
+
let flight = existing;
|
|
188
|
+
for (;;) {
|
|
189
|
+
const sameSource = flight.sourceIdentity === sourceIdentity;
|
|
190
|
+
let snapshot;
|
|
191
|
+
try {
|
|
192
|
+
snapshot = await flight.promise;
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (sameSource)
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
const shareable = snapshot && !snapshot.absent ? snapshot : undefined;
|
|
199
|
+
if (sameSource && shareable && flight.generation > arrivalGeneration) {
|
|
200
|
+
return this.sharedResult(shareable.result);
|
|
201
|
+
}
|
|
202
|
+
const next = flight.next ?? this.parseFlights.get(sessionId);
|
|
203
|
+
if (next) {
|
|
204
|
+
flight = next;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ? shareable : undefined);
|
|
208
|
+
flight.next = refresh;
|
|
209
|
+
return (await refresh.promise).result;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async refreshIfPresent(sessionId, source, adapter) {
|
|
213
|
+
const snapshot = await this.resolveIfPresentFlight(sessionId, source, adapter);
|
|
214
|
+
return this.toRefreshResult(sessionId, snapshot);
|
|
215
|
+
}
|
|
216
|
+
async resolveIfPresentFlight(sessionId, source, adapter) {
|
|
217
|
+
const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
|
|
218
|
+
const arrivalGeneration = this.flightGeneration;
|
|
219
|
+
const existing = this.parseFlights.get(sessionId);
|
|
220
|
+
if (!existing) {
|
|
221
|
+
return this.startParseFlight(sessionId, source, adapter, undefined, 'ifPresent').promise;
|
|
222
|
+
}
|
|
223
|
+
let flight = existing;
|
|
224
|
+
for (;;) {
|
|
225
|
+
const sameSource = flight.sourceIdentity === sourceIdentity;
|
|
226
|
+
let snapshot;
|
|
227
|
+
try {
|
|
228
|
+
snapshot = await flight.promise;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
}
|
|
232
|
+
const shareable = snapshot && !snapshot.absent ? snapshot : undefined;
|
|
233
|
+
if (sameSource && shareable && flight.generation > arrivalGeneration) {
|
|
234
|
+
return shareable;
|
|
235
|
+
}
|
|
236
|
+
const next = flight.next ?? this.parseFlights.get(sessionId);
|
|
237
|
+
if (next) {
|
|
238
|
+
flight = next;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ? shareable : undefined, 'ifPresent');
|
|
242
|
+
flight.next = refresh;
|
|
243
|
+
return refresh.promise;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
toRefreshResult(sessionId, snapshot) {
|
|
247
|
+
if (snapshot.absent || !snapshot.result) {
|
|
248
|
+
const record = this.fullParseCosts.get(sessionId);
|
|
249
|
+
return record
|
|
250
|
+
? { present: false, lastFullParse: { seq: record.seq, durationMs: record.durationMs } }
|
|
251
|
+
: { present: false };
|
|
252
|
+
}
|
|
253
|
+
if (snapshot.preParse) {
|
|
254
|
+
return { present: true, preParse: snapshot.preParse, result: snapshot.result };
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
present: true,
|
|
258
|
+
preParse: this.preParseFromResult(snapshot.result),
|
|
259
|
+
result: this.sharedResult(snapshot.result),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
startParseFlight(sessionId, source, adapter, previous, mode = 'always') {
|
|
263
|
+
const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
|
|
264
|
+
const flight = {
|
|
265
|
+
sourceIdentity,
|
|
266
|
+
generation: ++this.flightGeneration,
|
|
267
|
+
promise: Promise.resolve()
|
|
268
|
+
.then(() => this.parseSession(sessionId, source, adapter, sourceIdentity, previous, mode))
|
|
269
|
+
.finally(() => {
|
|
270
|
+
if (this.parseFlights.get(sessionId) === flight) {
|
|
271
|
+
this.parseFlights.delete(sessionId);
|
|
272
|
+
}
|
|
273
|
+
}),
|
|
274
|
+
};
|
|
275
|
+
this.parseFlights.set(sessionId, flight);
|
|
276
|
+
return flight;
|
|
277
|
+
}
|
|
278
|
+
sharedResult(result) {
|
|
279
|
+
this.hits += 1;
|
|
280
|
+
return { ...result, cacheHit: true, sourceChangeKind: 'cache-hit', boundaryFold: false };
|
|
281
|
+
}
|
|
282
|
+
async timedFullParse(sessionId, adapter, filePath, threadRef) {
|
|
283
|
+
const startedAt = performance.now();
|
|
284
|
+
const session = threadRef
|
|
285
|
+
? await adapter.parseFullSession(filePath, threadRef)
|
|
286
|
+
: await adapter.parseFullSession(filePath);
|
|
287
|
+
this.recordFullParse(sessionId, performance.now() - startedAt);
|
|
288
|
+
return session;
|
|
289
|
+
}
|
|
290
|
+
recordFullParse(sessionId, durationMs) {
|
|
291
|
+
this.fullParseSeq += 1;
|
|
292
|
+
if (!this.fullParseCosts.has(sessionId) && this.fullParseCosts.size >= FULL_PARSE_COST_CAP) {
|
|
293
|
+
const oldest = this.fullParseCosts.keys().next().value;
|
|
294
|
+
if (oldest !== undefined)
|
|
295
|
+
this.fullParseCosts.delete(oldest);
|
|
296
|
+
}
|
|
297
|
+
this.fullParseCosts.set(sessionId, { seq: this.fullParseSeq, durationMs });
|
|
298
|
+
}
|
|
299
|
+
async parseSession(sessionId, source, adapter, sourceIdentity, previous, mode = 'always') {
|
|
172
300
|
const now = Date.now();
|
|
173
301
|
const ref = this.toSourceRef(source, adapter);
|
|
174
302
|
const threadRef = typeof source !== 'string' ? ref : undefined;
|
|
175
303
|
let freshness = await this.computeFreshness(ref, adapter);
|
|
176
|
-
const
|
|
304
|
+
const retained = this.cache.get(sessionId);
|
|
305
|
+
const cached = retained?.sourceIdentity === sourceIdentity ? retained : undefined;
|
|
306
|
+
if (mode === 'ifPresent' && !cached) {
|
|
307
|
+
return { absent: true, freshnessToken: freshness.token };
|
|
308
|
+
}
|
|
309
|
+
const preParse = mode === 'ifPresent' && cached ? this.preParseGeneration(cached) : undefined;
|
|
310
|
+
if (previous && JSON.stringify(previous.freshnessToken) === JSON.stringify(freshness.token)) {
|
|
311
|
+
if (cached && cached.session === previous.result?.session)
|
|
312
|
+
this.touchLru(sessionId, cached, now);
|
|
313
|
+
return {
|
|
314
|
+
result: this.sharedResult(previous.result),
|
|
315
|
+
freshnessToken: freshness.token,
|
|
316
|
+
preParse,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
177
319
|
const freshSession = this.takeFreshCachedSession(sessionId, cached, freshness.token, now);
|
|
178
320
|
if (freshSession && cached) {
|
|
179
|
-
return
|
|
321
|
+
return {
|
|
322
|
+
result: this.toGetOrParseResult(freshSession, cached, true, 'cache-hit'),
|
|
323
|
+
freshnessToken: freshness.token,
|
|
324
|
+
preParse,
|
|
325
|
+
};
|
|
180
326
|
}
|
|
181
327
|
this.misses += 1;
|
|
182
328
|
let session;
|
|
183
329
|
let lastOffset;
|
|
184
330
|
let boundaryFold = false;
|
|
185
|
-
let
|
|
331
|
+
let acceptedFileAnchors;
|
|
332
|
+
let continuationState;
|
|
186
333
|
const sameFileIdentity = ref.kind !== 'file' ||
|
|
187
334
|
(cached?.fileIdentity !== undefined && cached.fileIdentity === freshness.fileIdentity);
|
|
188
335
|
const fileReplaced = cached !== undefined && ref.kind === 'file' && !sameFileIdentity;
|
|
@@ -190,12 +337,12 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
190
337
|
ref.kind === 'file' &&
|
|
191
338
|
sameFileIdentity &&
|
|
192
339
|
freshness.size > cached.lastSize;
|
|
193
|
-
const
|
|
194
|
-
? await this.
|
|
340
|
+
const growthAnchors = sameIdentityGrowth && cached.fileContentAnchors !== undefined
|
|
341
|
+
? await this.tryHashFileAnchors(ref.filePath, freshness, cached.lastOffset)
|
|
195
342
|
: undefined;
|
|
196
343
|
const provenSameFileAppend = sameIdentityGrowth &&
|
|
197
|
-
cached.
|
|
198
|
-
|
|
344
|
+
cached.fileContentAnchors !== undefined &&
|
|
345
|
+
(0, bounded_anchor_proof_1.anchorsEqual)(growthAnchors, cached.fileContentAnchors);
|
|
199
346
|
let sourceChangeKind = !cached
|
|
200
347
|
? 'unknown-full-parse'
|
|
201
348
|
: ref.kind === 'db'
|
|
@@ -209,26 +356,36 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
209
356
|
: freshness.size < cached.lastSize
|
|
210
357
|
? 'file-truncation'
|
|
211
358
|
: 'same-file-rewrite';
|
|
212
|
-
if (cached && provenSameFileAppend &&
|
|
359
|
+
if (cached && provenSameFileAppend && cached.fileContentAnchors) {
|
|
213
360
|
this.logger.debug({ sessionId, lastOffset: cached.lastOffset, currentSize: freshness.size }, 'Incremental parse (source grew)');
|
|
214
361
|
const incOptions = { byteOffset: cached.lastOffset, includeToolCalls: true };
|
|
362
|
+
if (adapter.incrementalMode === 'delta') {
|
|
363
|
+
incOptions.endByteOffset = freshness.size;
|
|
364
|
+
}
|
|
365
|
+
if (cached.continuationState !== undefined) {
|
|
366
|
+
incOptions.continuationState = cached.continuationState;
|
|
367
|
+
}
|
|
215
368
|
let tentativeResult = threadRef
|
|
216
369
|
? await adapter.parseIncremental(ref.filePath, incOptions, threadRef)
|
|
217
370
|
: await adapter.parseIncremental(ref.filePath, incOptions);
|
|
218
|
-
const
|
|
219
|
-
|
|
371
|
+
const newOffset = tentativeResult.nextByteOffset;
|
|
372
|
+
const prefixHeld = newOffset >= cached.lastOffset &&
|
|
373
|
+
(0, bounded_anchor_proof_1.anchorsEqual)(await this.tryHashFileAnchors(ref.filePath, freshness, cached.lastOffset, true), cached.fileContentAnchors);
|
|
374
|
+
const proofAnchors = prefixHeld
|
|
375
|
+
? await this.tryHashFileAnchors(ref.filePath, freshness, newOffset, true)
|
|
376
|
+
: undefined;
|
|
377
|
+
if (proofAnchors === undefined) {
|
|
220
378
|
this.logger.debug({ sessionId }, 'Discarding incremental parse because its proven file revision drifted');
|
|
221
379
|
tentativeResult = undefined;
|
|
222
380
|
freshness = await this.computeFreshness(ref, adapter);
|
|
223
381
|
sourceChangeKind = this.classifyUnsafeFileChange(cached, freshness);
|
|
224
|
-
session = threadRef
|
|
225
|
-
? await adapter.parseFullSession(ref.filePath, threadRef)
|
|
226
|
-
: await adapter.parseFullSession(ref.filePath);
|
|
382
|
+
session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
|
|
227
383
|
lastOffset = freshness.size;
|
|
228
384
|
}
|
|
229
385
|
else {
|
|
230
386
|
const acceptedResult = tentativeResult;
|
|
231
|
-
|
|
387
|
+
acceptedFileAnchors = proofAnchors;
|
|
388
|
+
continuationState = acceptedResult.continuationState;
|
|
232
389
|
const newMessages = acceptedResult.entries;
|
|
233
390
|
if (adapter.incrementalMode === 'snapshot') {
|
|
234
391
|
const snapshotMetrics = acceptedResult.metrics ?? cached.session.metrics;
|
|
@@ -245,7 +402,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
245
402
|
boundaryFold = folded.tailMutatedWithoutNewMessage;
|
|
246
403
|
const mergedMessages = folded.merged;
|
|
247
404
|
const mergedMetrics = acceptedResult.metrics
|
|
248
|
-
?
|
|
405
|
+
? (0, metrics_merge_1.mergeMetrics)(cached.session.metrics, acceptedResult.metrics, (0, metrics_merge_1.deriveMergeInputsFromMessages)(cached.session.metrics, mergedMessages))
|
|
249
406
|
: cached.session.metrics;
|
|
250
407
|
session = {
|
|
251
408
|
...cached.session,
|
|
@@ -265,9 +422,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
265
422
|
else if (cached && freshness.size < cached.lastSize) {
|
|
266
423
|
this.logger.debug({ sessionId }, 'Full reparse (source truncated)');
|
|
267
424
|
}
|
|
268
|
-
session = threadRef
|
|
269
|
-
? await adapter.parseFullSession(ref.filePath, threadRef)
|
|
270
|
-
: await adapter.parseFullSession(ref.filePath);
|
|
425
|
+
session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
|
|
271
426
|
lastOffset = freshness.size;
|
|
272
427
|
}
|
|
273
428
|
const coalesced = (0, coalesce_turns_1.coalesceAssistantTurns)(session);
|
|
@@ -275,44 +430,51 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
275
430
|
session = { ...session, messages: coalesced.messages, metrics: coalesced.metrics };
|
|
276
431
|
}
|
|
277
432
|
session = this.withoutDerivedChunks(session);
|
|
278
|
-
const
|
|
279
|
-
? lastOffset === freshness.size && acceptedFileDigests !== undefined
|
|
280
|
-
? acceptedFileDigests.fullDigest
|
|
281
|
-
: (await this.tryHashFileContent(ref.filePath, freshness, lastOffset))?.prefixDigest
|
|
282
|
-
: undefined;
|
|
433
|
+
const fileContentAnchors = await this.resolveStoredAnchors(ref, freshness, lastOffset, acceptedFileAnchors);
|
|
283
434
|
this.deleteEntry(sessionId);
|
|
284
435
|
const sourceWeightBytes = this.estimateSourceWeight(ref, session, freshness.size);
|
|
285
436
|
const entry = {
|
|
437
|
+
sourceIdentity,
|
|
286
438
|
session,
|
|
287
439
|
lastOffset,
|
|
288
440
|
lastSize: freshness.size,
|
|
289
441
|
lastMtime: freshness.mtimeMs,
|
|
290
442
|
fileIdentity: freshness.fileIdentity,
|
|
291
|
-
|
|
443
|
+
fileContentAnchors,
|
|
292
444
|
sourceVersion: freshness.sourceVersion,
|
|
293
445
|
freshnessToken: freshness.token,
|
|
294
446
|
lastAccessedAt: now,
|
|
295
447
|
sourceWeightBytes,
|
|
296
448
|
weights: { parsed: sourceWeightBytes * 2, chunks: 0, dto: 0 },
|
|
297
449
|
boundaryFold,
|
|
450
|
+
continuationState,
|
|
298
451
|
};
|
|
299
452
|
this.cache.set(sessionId, entry);
|
|
300
453
|
this.budgetUsedBytes += entry.weights.parsed;
|
|
301
454
|
this.enforceBudget();
|
|
302
455
|
return {
|
|
303
|
-
session,
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
lastOffset,
|
|
307
|
-
lastSize: freshness.size,
|
|
308
|
-
lastMtime: freshness.mtimeMs,
|
|
309
|
-
sourceVersion: freshness.sourceVersion,
|
|
310
|
-
boundaryFold,
|
|
456
|
+
result: this.toGetOrParseResult(session, entry, false, sourceChangeKind),
|
|
457
|
+
freshnessToken: freshness.token,
|
|
458
|
+
preParse,
|
|
311
459
|
};
|
|
312
460
|
}
|
|
313
461
|
getEntry(sessionId) {
|
|
314
462
|
return this.cache.get(sessionId);
|
|
315
463
|
}
|
|
464
|
+
preParseGeneration(entry) {
|
|
465
|
+
return {
|
|
466
|
+
sourceVersion: entry.sourceVersion,
|
|
467
|
+
messageCount: entry.session.messages.length,
|
|
468
|
+
chunkCount: entry.chunks?.chunks.length ?? (0, chunk_builder_1.buildChunks)(entry.session.messages).length,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
preParseFromResult(result) {
|
|
472
|
+
return {
|
|
473
|
+
sourceVersion: result.sourceVersion,
|
|
474
|
+
messageCount: result.session.messages.length,
|
|
475
|
+
chunkCount: result.session.chunks?.length ?? (0, chunk_builder_1.buildChunks)(result.session.messages).length,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
316
478
|
getChunks(sessionId, sourceVersion) {
|
|
317
479
|
const entry = this.cache.get(sessionId);
|
|
318
480
|
if (!entry?.chunks || entry.chunks.sourceVersion !== sourceVersion) {
|
|
@@ -394,7 +556,9 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
394
556
|
return this.cache.size;
|
|
395
557
|
}
|
|
396
558
|
takeFreshCachedSession(sessionId, cached, freshnessToken, now) {
|
|
397
|
-
if (!cached ||
|
|
559
|
+
if (!cached ||
|
|
560
|
+
this.cache.get(sessionId) !== cached ||
|
|
561
|
+
JSON.stringify(cached.freshnessToken) !== JSON.stringify(freshnessToken)) {
|
|
398
562
|
return undefined;
|
|
399
563
|
}
|
|
400
564
|
this.logger.debug({ sessionId }, 'Session cache hit');
|
|
@@ -411,10 +575,14 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
411
575
|
lastSize: entry.lastSize,
|
|
412
576
|
lastMtime: entry.lastMtime,
|
|
413
577
|
sourceVersion: entry.sourceVersion,
|
|
414
|
-
boundaryFold: entry.boundaryFold,
|
|
578
|
+
boundaryFold: cacheHit ? false : entry.boundaryFold,
|
|
579
|
+
fileContentAnchors: entry.fileContentAnchors,
|
|
580
|
+
continuationState: entry.continuationState,
|
|
415
581
|
};
|
|
416
582
|
}
|
|
417
583
|
touchLru(sessionId, entry, now) {
|
|
584
|
+
if (this.cache.get(sessionId) !== entry)
|
|
585
|
+
return;
|
|
418
586
|
entry.lastAccessedAt = now;
|
|
419
587
|
this.cache.delete(sessionId);
|
|
420
588
|
this.cache.set(sessionId, entry);
|
|
@@ -453,27 +621,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
453
621
|
}
|
|
454
622
|
foldLeadingContinuationIntoCachedTail(cachedMessages, newMessages) {
|
|
455
623
|
const tail = cachedMessages[cachedMessages.length - 1];
|
|
456
|
-
|
|
457
|
-
return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
|
|
458
|
-
}
|
|
459
|
-
let foldCount = 0;
|
|
460
|
-
let tailStopReason = tail.stopReason ?? null;
|
|
461
|
-
while (foldCount < newMessages.length) {
|
|
462
|
-
const m = newMessages[foldCount];
|
|
463
|
-
if (m.isSidechain !== tail.isSidechain)
|
|
464
|
-
break;
|
|
465
|
-
if (m.isCompactSummary)
|
|
466
|
-
break;
|
|
467
|
-
const isToolResult = (0, tool_result_fold_1.isToolResultOnlyMessage)(m);
|
|
468
|
-
const isContinuationAssistant = m.role === 'assistant';
|
|
469
|
-
if (!isToolResult && !isContinuationAssistant)
|
|
470
|
-
break;
|
|
471
|
-
if (isContinuationAssistant && tailStopReason === 'end_turn')
|
|
472
|
-
break;
|
|
473
|
-
if (isContinuationAssistant)
|
|
474
|
-
tailStopReason = m.stopReason ?? null;
|
|
475
|
-
foldCount += 1;
|
|
476
|
-
}
|
|
624
|
+
const { foldCount, tailMutatedWithoutNewMessage } = (0, metrics_merge_1.computeLeadingContinuationFold)((0, metrics_merge_1.describeTail)(tail), newMessages);
|
|
477
625
|
if (foldCount === 0) {
|
|
478
626
|
return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
|
|
479
627
|
}
|
|
@@ -489,51 +637,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
489
637
|
const remaining = newMessages.slice(foldCount);
|
|
490
638
|
return {
|
|
491
639
|
merged: [...cachedMessages.slice(0, -1), foldedTail, ...remaining],
|
|
492
|
-
tailMutatedWithoutNewMessage
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
mergeMetrics(existing, incremental, allMessages) {
|
|
496
|
-
const inputTokens = existing.inputTokens + incremental.inputTokens;
|
|
497
|
-
const outputTokens = existing.outputTokens + incremental.outputTokens;
|
|
498
|
-
const cacheReadTokens = existing.cacheReadTokens + incremental.cacheReadTokens;
|
|
499
|
-
const cacheCreationTokens = existing.cacheCreationTokens + incremental.cacheCreationTokens;
|
|
500
|
-
const totalTokens = inputTokens + outputTokens + cacheReadTokens + cacheCreationTokens;
|
|
501
|
-
let durationMs = existing.durationMs;
|
|
502
|
-
if (allMessages.length >= 2) {
|
|
503
|
-
durationMs =
|
|
504
|
-
allMessages[allMessages.length - 1].timestamp.getTime() -
|
|
505
|
-
allMessages[0].timestamp.getTime();
|
|
506
|
-
}
|
|
507
|
-
const modelsSet = new Set();
|
|
508
|
-
if (existing.primaryModel)
|
|
509
|
-
modelsSet.add(existing.primaryModel);
|
|
510
|
-
if (incremental.primaryModel)
|
|
511
|
-
modelsSet.add(incremental.primaryModel);
|
|
512
|
-
if (existing.modelsUsed)
|
|
513
|
-
existing.modelsUsed.forEach((m) => modelsSet.add(m));
|
|
514
|
-
if (incremental.modelsUsed)
|
|
515
|
-
incremental.modelsUsed.forEach((m) => modelsSet.add(m));
|
|
516
|
-
const modelsUsed = modelsSet.size > 1 ? Array.from(modelsSet) : undefined;
|
|
517
|
-
return {
|
|
518
|
-
inputTokens,
|
|
519
|
-
outputTokens,
|
|
520
|
-
cacheReadTokens,
|
|
521
|
-
cacheCreationTokens,
|
|
522
|
-
totalTokens,
|
|
523
|
-
costUsd: existing.costUsd + incremental.costUsd,
|
|
524
|
-
primaryModel: incremental.primaryModel ?? existing.primaryModel,
|
|
525
|
-
modelsUsed,
|
|
526
|
-
isOngoing: incremental.isOngoing,
|
|
527
|
-
visibleContextTokens: (0, estimate_content_tokens_1.estimateVisibleFromMessages)(allMessages),
|
|
528
|
-
totalContextTokens: incremental.totalContextTokens > 0
|
|
529
|
-
? incremental.totalContextTokens
|
|
530
|
-
: existing.totalContextTokens,
|
|
531
|
-
contextWindowTokens: incremental.contextWindowTokens ?? existing.contextWindowTokens,
|
|
532
|
-
messageCount: allMessages.length,
|
|
533
|
-
durationMs,
|
|
534
|
-
totalContextConsumption: existing.totalContextConsumption,
|
|
535
|
-
compactionCount: existing.compactionCount,
|
|
536
|
-
phaseBreakdowns: existing.phaseBreakdowns,
|
|
640
|
+
tailMutatedWithoutNewMessage,
|
|
537
641
|
};
|
|
538
642
|
}
|
|
539
643
|
mergeWarnings(existing, incremental) {
|
|
@@ -565,59 +669,31 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
565
669
|
}
|
|
566
670
|
return 'same-file-rewrite';
|
|
567
671
|
}
|
|
568
|
-
async
|
|
672
|
+
async tryHashFileAnchors(filePath, expected, offset, allowGrowth = false) {
|
|
569
673
|
try {
|
|
570
|
-
return await
|
|
674
|
+
return await (0, bounded_anchor_proof_1.hashFileAnchors)(filePath, expected, offset, allowGrowth);
|
|
571
675
|
}
|
|
572
676
|
catch (error) {
|
|
573
|
-
this.logger.debug({ error, filePath }, 'File
|
|
677
|
+
this.logger.debug({ error, filePath }, 'File anchor proof unavailable — append is unsafe');
|
|
574
678
|
return undefined;
|
|
575
679
|
}
|
|
576
680
|
}
|
|
577
|
-
async
|
|
578
|
-
if (
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
if (current.size !== expected.size ||
|
|
588
|
-
current.mtime.getTime() !== expected.mtimeMs ||
|
|
589
|
-
`${current.dev}:${current.ino}` !== expected.fileIdentity) {
|
|
590
|
-
throw new Error('File changed while computing append proof');
|
|
591
|
-
}
|
|
592
|
-
};
|
|
681
|
+
async resolveStoredAnchors(ref, freshness, lastOffset, acceptedFileAnchors) {
|
|
682
|
+
if (ref.kind !== 'file')
|
|
683
|
+
return undefined;
|
|
684
|
+
if (acceptedFileAnchors)
|
|
685
|
+
return acceptedFileAnchors;
|
|
686
|
+
if (!(await this.snapshotEndsOnLineBoundary(ref.filePath, lastOffset)))
|
|
687
|
+
return undefined;
|
|
688
|
+
return this.tryHashFileAnchors(ref.filePath, freshness, lastOffset);
|
|
689
|
+
}
|
|
690
|
+
async snapshotEndsOnLineBoundary(filePath, offset) {
|
|
593
691
|
try {
|
|
594
|
-
await
|
|
595
|
-
const prefixHash = (0, node_crypto_1.createHash)('sha256');
|
|
596
|
-
const fullHash = (0, node_crypto_1.createHash)('sha256');
|
|
597
|
-
const buffer = Buffer.allocUnsafe(Math.min(FILE_HASH_CHUNK_BYTES, Math.max(1, expected.size)));
|
|
598
|
-
let position = 0;
|
|
599
|
-
while (position < expected.size) {
|
|
600
|
-
const requested = Math.min(buffer.byteLength, expected.size - position);
|
|
601
|
-
const { bytesRead } = await handle.read(buffer, 0, requested, position);
|
|
602
|
-
if (bytesRead === 0) {
|
|
603
|
-
throw new Error('File ended while computing append proof');
|
|
604
|
-
}
|
|
605
|
-
const chunk = buffer.subarray(0, bytesRead);
|
|
606
|
-
fullHash.update(chunk);
|
|
607
|
-
const prefixBytes = Math.min(bytesRead, Math.max(0, prefixLength - position));
|
|
608
|
-
if (prefixBytes > 0) {
|
|
609
|
-
prefixHash.update(chunk.subarray(0, prefixBytes));
|
|
610
|
-
}
|
|
611
|
-
position += bytesRead;
|
|
612
|
-
}
|
|
613
|
-
await assertStableSnapshot();
|
|
614
|
-
return {
|
|
615
|
-
prefixDigest: prefixHash.digest('hex'),
|
|
616
|
-
fullDigest: fullHash.digest('hex'),
|
|
617
|
-
};
|
|
692
|
+
return (await (0, bounded_line_read_1.lastCompleteLineEnd)(filePath, 0, offset)) === offset;
|
|
618
693
|
}
|
|
619
|
-
|
|
620
|
-
|
|
694
|
+
catch (error) {
|
|
695
|
+
this.logger.debug({ error, filePath }, 'Line-boundary probe failed — withholding append proof');
|
|
696
|
+
return false;
|
|
621
697
|
}
|
|
622
698
|
}
|
|
623
699
|
toSourceRef(source, adapter) {
|
|
@@ -630,6 +706,14 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
630
706
|
}
|
|
631
707
|
return source;
|
|
632
708
|
}
|
|
709
|
+
sourceIdentity(ref) {
|
|
710
|
+
return JSON.stringify([
|
|
711
|
+
ref.providerName.trim().toLowerCase(),
|
|
712
|
+
ref.kind,
|
|
713
|
+
ref.filePath,
|
|
714
|
+
ref.kind === 'db' ? ref.providerSessionId : undefined,
|
|
715
|
+
]);
|
|
716
|
+
}
|
|
633
717
|
async computeFreshness(ref, adapter) {
|
|
634
718
|
const { size, mtimeMs, dev, ino, fileIdentity } = await this.statFile(ref.filePath);
|
|
635
719
|
const adapterToken = adapter.getFreshnessToken
|