devchain-cli 0.23.2 → 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/data/pricing.json +12 -11
- 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 +33 -4
- package/dist/server/modules/session-reader/services/session-cache.service.js +157 -144
- package/dist/server/modules/session-reader/services/session-cache.service.js.map +1 -1
- package/dist/server/modules/session-reader/services/session-reader.service.js +0 -1
- 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 +16 -0
- package/dist/server/modules/session-reader/services/transcript-watcher.service.js +370 -69
- 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-BnzvJiFh.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 +10 -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-B6RB_uEX.js +0 -1
- package/dist/server/ui/assets/ReviewsPage-6iPnGQ1T.js +0 -6
- package/dist/server/ui/assets/index-CV8ydm7w.css +0 -32
- package/dist/server/ui/assets/index-DgajOeEy.js +0 -1197
- package/dist/server/ui/assets/useReviewSubscription-BfcypysB.js +0 -69
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
|
2
2
|
import type { SessionReaderAdapter, SessionSourceRef } from '../adapters/session-reader-adapter.interface';
|
|
3
3
|
import type { UnifiedSession } from '../dtos/unified-session.types';
|
|
4
|
+
import { type FileContentAnchors } from './bounded-anchor-proof';
|
|
4
5
|
import { MetricsService } from '../../metrics/services/metrics.service';
|
|
5
6
|
import type { CacheStats } from '../../metrics/types/metrics.types';
|
|
6
7
|
import type { UnifiedChunk } from '../dtos/unified-chunk.types';
|
|
@@ -33,7 +34,7 @@ export interface SessionCacheEntry {
|
|
|
33
34
|
lastSize: number;
|
|
34
35
|
lastMtime: number;
|
|
35
36
|
fileIdentity?: string;
|
|
36
|
-
|
|
37
|
+
fileContentAnchors?: FileContentAnchors;
|
|
37
38
|
sourceVersion: number;
|
|
38
39
|
freshnessToken: unknown;
|
|
39
40
|
lastAccessedAt: number;
|
|
@@ -42,6 +43,7 @@ export interface SessionCacheEntry {
|
|
|
42
43
|
chunks?: CachedChunks;
|
|
43
44
|
dto?: CachedTranscriptDto;
|
|
44
45
|
boundaryFold: boolean;
|
|
46
|
+
continuationState?: unknown;
|
|
45
47
|
}
|
|
46
48
|
export type SourceChangeKind = 'cache-hit' | 'same-file-append' | 'file-replacement' | 'file-truncation' | 'same-file-rewrite' | 'db-update' | 'unknown-full-parse';
|
|
47
49
|
export interface GetOrParseResult {
|
|
@@ -53,7 +55,25 @@ export interface GetOrParseResult {
|
|
|
53
55
|
lastMtime: number;
|
|
54
56
|
sourceVersion: number;
|
|
55
57
|
boundaryFold: boolean;
|
|
58
|
+
fileContentAnchors?: FileContentAnchors;
|
|
59
|
+
continuationState?: unknown;
|
|
56
60
|
}
|
|
61
|
+
export interface PreParseGeneration {
|
|
62
|
+
sourceVersion: number;
|
|
63
|
+
messageCount: number;
|
|
64
|
+
chunkCount: number;
|
|
65
|
+
}
|
|
66
|
+
export type RefreshIfPresentResult = {
|
|
67
|
+
present: false;
|
|
68
|
+
lastFullParse?: {
|
|
69
|
+
seq: number;
|
|
70
|
+
durationMs: number;
|
|
71
|
+
};
|
|
72
|
+
} | {
|
|
73
|
+
present: true;
|
|
74
|
+
preParse: PreParseGeneration;
|
|
75
|
+
result: GetOrParseResult;
|
|
76
|
+
};
|
|
57
77
|
export declare class SessionCacheService implements OnModuleDestroy, OnModuleInit {
|
|
58
78
|
private readonly metricsService;
|
|
59
79
|
private readonly logger;
|
|
@@ -68,6 +88,8 @@ export declare class SessionCacheService implements OnModuleDestroy, OnModuleIni
|
|
|
68
88
|
private dtoMisses;
|
|
69
89
|
private budgetUsedBytes;
|
|
70
90
|
private evictions;
|
|
91
|
+
private fullParseSeq;
|
|
92
|
+
private readonly fullParseCosts;
|
|
71
93
|
private idleSweepTimer?;
|
|
72
94
|
private readonly config;
|
|
73
95
|
constructor(metricsService: MetricsService, config?: TranscriptCacheConfig);
|
|
@@ -80,10 +102,17 @@ export declare class SessionCacheService implements OnModuleDestroy, OnModuleIni
|
|
|
80
102
|
getOrParse(sessionId: string, source: string | SessionSourceRef, adapter: SessionReaderAdapter): Promise<UnifiedSession>;
|
|
81
103
|
getOrParseWithMeta(sessionId: string, source: string | SessionSourceRef, adapter: SessionReaderAdapter): Promise<GetOrParseResult>;
|
|
82
104
|
private getOrParseResult;
|
|
105
|
+
refreshIfPresent(sessionId: string, source: string | SessionSourceRef, adapter: SessionReaderAdapter): Promise<RefreshIfPresentResult>;
|
|
106
|
+
private resolveIfPresentFlight;
|
|
107
|
+
private toRefreshResult;
|
|
83
108
|
private startParseFlight;
|
|
84
109
|
private sharedResult;
|
|
110
|
+
private timedFullParse;
|
|
111
|
+
private recordFullParse;
|
|
85
112
|
private parseSession;
|
|
86
113
|
getEntry(sessionId: string): SessionCacheEntry | undefined;
|
|
114
|
+
private preParseGeneration;
|
|
115
|
+
private preParseFromResult;
|
|
87
116
|
getChunks(sessionId: string, sourceVersion: number): UnifiedChunk[] | undefined;
|
|
88
117
|
setChunks(sessionId: string, sourceVersion: number, chunks: UnifiedChunk[]): void;
|
|
89
118
|
getDto(sessionId: string, maxToolResultLength: number, enrichmentFingerprint: string): CachedTranscriptDto | undefined;
|
|
@@ -104,12 +133,12 @@ export declare class SessionCacheService implements OnModuleDestroy, OnModuleIni
|
|
|
104
133
|
private estimateSourceWeight;
|
|
105
134
|
private withoutDerivedChunks;
|
|
106
135
|
private foldLeadingContinuationIntoCachedTail;
|
|
107
|
-
private mergeMetrics;
|
|
108
136
|
private mergeWarnings;
|
|
109
137
|
private statFile;
|
|
110
138
|
private classifyUnsafeFileChange;
|
|
111
|
-
private
|
|
112
|
-
private
|
|
139
|
+
private tryHashFileAnchors;
|
|
140
|
+
private resolveStoredAnchors;
|
|
141
|
+
private snapshotEndsOnLineBoundary;
|
|
113
142
|
private toSourceRef;
|
|
114
143
|
private sourceIdentity;
|
|
115
144
|
private computeFreshness;
|
|
@@ -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}`)
|
|
@@ -88,6 +90,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
88
90
|
dtoMisses = 0;
|
|
89
91
|
budgetUsedBytes = 0;
|
|
90
92
|
evictions = 0;
|
|
93
|
+
fullParseSeq = 0;
|
|
94
|
+
fullParseCosts = new Map();
|
|
91
95
|
idleSweepTimer;
|
|
92
96
|
config;
|
|
93
97
|
constructor(metricsService, config) {
|
|
@@ -106,6 +110,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
106
110
|
this.idleSweepTimer = undefined;
|
|
107
111
|
}
|
|
108
112
|
this.clear();
|
|
113
|
+
this.fullParseCosts.clear();
|
|
109
114
|
}
|
|
110
115
|
getCacheStats() {
|
|
111
116
|
const total = this.hits + this.misses;
|
|
@@ -190,26 +195,77 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
190
195
|
if (sameSource)
|
|
191
196
|
throw error;
|
|
192
197
|
}
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
const shareable = snapshot && !snapshot.absent ? snapshot : undefined;
|
|
199
|
+
if (sameSource && shareable && flight.generation > arrivalGeneration) {
|
|
200
|
+
return this.sharedResult(shareable.result);
|
|
195
201
|
}
|
|
196
202
|
const next = flight.next ?? this.parseFlights.get(sessionId);
|
|
197
203
|
if (next) {
|
|
198
204
|
flight = next;
|
|
199
205
|
continue;
|
|
200
206
|
}
|
|
201
|
-
const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ?
|
|
207
|
+
const refresh = this.startParseFlight(sessionId, source, adapter, sameSource ? shareable : undefined);
|
|
202
208
|
flight.next = refresh;
|
|
203
209
|
return (await refresh.promise).result;
|
|
204
210
|
}
|
|
205
211
|
}
|
|
206
|
-
|
|
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') {
|
|
207
263
|
const sourceIdentity = this.sourceIdentity(this.toSourceRef(source, adapter));
|
|
208
264
|
const flight = {
|
|
209
265
|
sourceIdentity,
|
|
210
266
|
generation: ++this.flightGeneration,
|
|
211
267
|
promise: Promise.resolve()
|
|
212
|
-
.then(() => this.parseSession(sessionId, source, adapter, sourceIdentity, previous))
|
|
268
|
+
.then(() => this.parseSession(sessionId, source, adapter, sourceIdentity, previous, mode))
|
|
213
269
|
.finally(() => {
|
|
214
270
|
if (this.parseFlights.get(sessionId) === flight) {
|
|
215
271
|
this.parseFlights.delete(sessionId);
|
|
@@ -223,30 +279,57 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
223
279
|
this.hits += 1;
|
|
224
280
|
return { ...result, cacheHit: true, sourceChangeKind: 'cache-hit', boundaryFold: false };
|
|
225
281
|
}
|
|
226
|
-
async
|
|
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') {
|
|
227
300
|
const now = Date.now();
|
|
228
301
|
const ref = this.toSourceRef(source, adapter);
|
|
229
302
|
const threadRef = typeof source !== 'string' ? ref : undefined;
|
|
230
303
|
let freshness = await this.computeFreshness(ref, adapter);
|
|
231
304
|
const retained = this.cache.get(sessionId);
|
|
232
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;
|
|
233
310
|
if (previous && JSON.stringify(previous.freshnessToken) === JSON.stringify(freshness.token)) {
|
|
234
|
-
if (cached
|
|
311
|
+
if (cached && cached.session === previous.result?.session)
|
|
235
312
|
this.touchLru(sessionId, cached, now);
|
|
236
|
-
return {
|
|
313
|
+
return {
|
|
314
|
+
result: this.sharedResult(previous.result),
|
|
315
|
+
freshnessToken: freshness.token,
|
|
316
|
+
preParse,
|
|
317
|
+
};
|
|
237
318
|
}
|
|
238
319
|
const freshSession = this.takeFreshCachedSession(sessionId, cached, freshness.token, now);
|
|
239
320
|
if (freshSession && cached) {
|
|
240
321
|
return {
|
|
241
322
|
result: this.toGetOrParseResult(freshSession, cached, true, 'cache-hit'),
|
|
242
323
|
freshnessToken: freshness.token,
|
|
324
|
+
preParse,
|
|
243
325
|
};
|
|
244
326
|
}
|
|
245
327
|
this.misses += 1;
|
|
246
328
|
let session;
|
|
247
329
|
let lastOffset;
|
|
248
330
|
let boundaryFold = false;
|
|
249
|
-
let
|
|
331
|
+
let acceptedFileAnchors;
|
|
332
|
+
let continuationState;
|
|
250
333
|
const sameFileIdentity = ref.kind !== 'file' ||
|
|
251
334
|
(cached?.fileIdentity !== undefined && cached.fileIdentity === freshness.fileIdentity);
|
|
252
335
|
const fileReplaced = cached !== undefined && ref.kind === 'file' && !sameFileIdentity;
|
|
@@ -254,12 +337,12 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
254
337
|
ref.kind === 'file' &&
|
|
255
338
|
sameFileIdentity &&
|
|
256
339
|
freshness.size > cached.lastSize;
|
|
257
|
-
const
|
|
258
|
-
? await this.
|
|
340
|
+
const growthAnchors = sameIdentityGrowth && cached.fileContentAnchors !== undefined
|
|
341
|
+
? await this.tryHashFileAnchors(ref.filePath, freshness, cached.lastOffset)
|
|
259
342
|
: undefined;
|
|
260
343
|
const provenSameFileAppend = sameIdentityGrowth &&
|
|
261
|
-
cached.
|
|
262
|
-
|
|
344
|
+
cached.fileContentAnchors !== undefined &&
|
|
345
|
+
(0, bounded_anchor_proof_1.anchorsEqual)(growthAnchors, cached.fileContentAnchors);
|
|
263
346
|
let sourceChangeKind = !cached
|
|
264
347
|
? 'unknown-full-parse'
|
|
265
348
|
: ref.kind === 'db'
|
|
@@ -273,26 +356,36 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
273
356
|
: freshness.size < cached.lastSize
|
|
274
357
|
? 'file-truncation'
|
|
275
358
|
: 'same-file-rewrite';
|
|
276
|
-
if (cached && provenSameFileAppend &&
|
|
359
|
+
if (cached && provenSameFileAppend && cached.fileContentAnchors) {
|
|
277
360
|
this.logger.debug({ sessionId, lastOffset: cached.lastOffset, currentSize: freshness.size }, 'Incremental parse (source grew)');
|
|
278
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
|
+
}
|
|
279
368
|
let tentativeResult = threadRef
|
|
280
369
|
? await adapter.parseIncremental(ref.filePath, incOptions, threadRef)
|
|
281
370
|
: await adapter.parseIncremental(ref.filePath, incOptions);
|
|
282
|
-
const
|
|
283
|
-
|
|
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) {
|
|
284
378
|
this.logger.debug({ sessionId }, 'Discarding incremental parse because its proven file revision drifted');
|
|
285
379
|
tentativeResult = undefined;
|
|
286
380
|
freshness = await this.computeFreshness(ref, adapter);
|
|
287
381
|
sourceChangeKind = this.classifyUnsafeFileChange(cached, freshness);
|
|
288
|
-
session = threadRef
|
|
289
|
-
? await adapter.parseFullSession(ref.filePath, threadRef)
|
|
290
|
-
: await adapter.parseFullSession(ref.filePath);
|
|
382
|
+
session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
|
|
291
383
|
lastOffset = freshness.size;
|
|
292
384
|
}
|
|
293
385
|
else {
|
|
294
386
|
const acceptedResult = tentativeResult;
|
|
295
|
-
|
|
387
|
+
acceptedFileAnchors = proofAnchors;
|
|
388
|
+
continuationState = acceptedResult.continuationState;
|
|
296
389
|
const newMessages = acceptedResult.entries;
|
|
297
390
|
if (adapter.incrementalMode === 'snapshot') {
|
|
298
391
|
const snapshotMetrics = acceptedResult.metrics ?? cached.session.metrics;
|
|
@@ -309,7 +402,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
309
402
|
boundaryFold = folded.tailMutatedWithoutNewMessage;
|
|
310
403
|
const mergedMessages = folded.merged;
|
|
311
404
|
const mergedMetrics = acceptedResult.metrics
|
|
312
|
-
?
|
|
405
|
+
? (0, metrics_merge_1.mergeMetrics)(cached.session.metrics, acceptedResult.metrics, (0, metrics_merge_1.deriveMergeInputsFromMessages)(cached.session.metrics, mergedMessages))
|
|
313
406
|
: cached.session.metrics;
|
|
314
407
|
session = {
|
|
315
408
|
...cached.session,
|
|
@@ -329,9 +422,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
329
422
|
else if (cached && freshness.size < cached.lastSize) {
|
|
330
423
|
this.logger.debug({ sessionId }, 'Full reparse (source truncated)');
|
|
331
424
|
}
|
|
332
|
-
session = threadRef
|
|
333
|
-
? await adapter.parseFullSession(ref.filePath, threadRef)
|
|
334
|
-
: await adapter.parseFullSession(ref.filePath);
|
|
425
|
+
session = await this.timedFullParse(sessionId, adapter, ref.filePath, threadRef);
|
|
335
426
|
lastOffset = freshness.size;
|
|
336
427
|
}
|
|
337
428
|
const coalesced = (0, coalesce_turns_1.coalesceAssistantTurns)(session);
|
|
@@ -339,11 +430,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
339
430
|
session = { ...session, messages: coalesced.messages, metrics: coalesced.metrics };
|
|
340
431
|
}
|
|
341
432
|
session = this.withoutDerivedChunks(session);
|
|
342
|
-
const
|
|
343
|
-
? lastOffset === freshness.size && acceptedFileDigests !== undefined
|
|
344
|
-
? acceptedFileDigests.fullDigest
|
|
345
|
-
: (await this.tryHashFileContent(ref.filePath, freshness, lastOffset))?.prefixDigest
|
|
346
|
-
: undefined;
|
|
433
|
+
const fileContentAnchors = await this.resolveStoredAnchors(ref, freshness, lastOffset, acceptedFileAnchors);
|
|
347
434
|
this.deleteEntry(sessionId);
|
|
348
435
|
const sourceWeightBytes = this.estimateSourceWeight(ref, session, freshness.size);
|
|
349
436
|
const entry = {
|
|
@@ -353,13 +440,14 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
353
440
|
lastSize: freshness.size,
|
|
354
441
|
lastMtime: freshness.mtimeMs,
|
|
355
442
|
fileIdentity: freshness.fileIdentity,
|
|
356
|
-
|
|
443
|
+
fileContentAnchors,
|
|
357
444
|
sourceVersion: freshness.sourceVersion,
|
|
358
445
|
freshnessToken: freshness.token,
|
|
359
446
|
lastAccessedAt: now,
|
|
360
447
|
sourceWeightBytes,
|
|
361
448
|
weights: { parsed: sourceWeightBytes * 2, chunks: 0, dto: 0 },
|
|
362
449
|
boundaryFold,
|
|
450
|
+
continuationState,
|
|
363
451
|
};
|
|
364
452
|
this.cache.set(sessionId, entry);
|
|
365
453
|
this.budgetUsedBytes += entry.weights.parsed;
|
|
@@ -367,11 +455,26 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
367
455
|
return {
|
|
368
456
|
result: this.toGetOrParseResult(session, entry, false, sourceChangeKind),
|
|
369
457
|
freshnessToken: freshness.token,
|
|
458
|
+
preParse,
|
|
370
459
|
};
|
|
371
460
|
}
|
|
372
461
|
getEntry(sessionId) {
|
|
373
462
|
return this.cache.get(sessionId);
|
|
374
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
|
+
}
|
|
375
478
|
getChunks(sessionId, sourceVersion) {
|
|
376
479
|
const entry = this.cache.get(sessionId);
|
|
377
480
|
if (!entry?.chunks || entry.chunks.sourceVersion !== sourceVersion) {
|
|
@@ -473,6 +576,8 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
473
576
|
lastMtime: entry.lastMtime,
|
|
474
577
|
sourceVersion: entry.sourceVersion,
|
|
475
578
|
boundaryFold: cacheHit ? false : entry.boundaryFold,
|
|
579
|
+
fileContentAnchors: entry.fileContentAnchors,
|
|
580
|
+
continuationState: entry.continuationState,
|
|
476
581
|
};
|
|
477
582
|
}
|
|
478
583
|
touchLru(sessionId, entry, now) {
|
|
@@ -516,27 +621,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
516
621
|
}
|
|
517
622
|
foldLeadingContinuationIntoCachedTail(cachedMessages, newMessages) {
|
|
518
623
|
const tail = cachedMessages[cachedMessages.length - 1];
|
|
519
|
-
|
|
520
|
-
return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
|
|
521
|
-
}
|
|
522
|
-
let foldCount = 0;
|
|
523
|
-
let tailStopReason = tail.stopReason ?? null;
|
|
524
|
-
while (foldCount < newMessages.length) {
|
|
525
|
-
const m = newMessages[foldCount];
|
|
526
|
-
if (m.isSidechain !== tail.isSidechain)
|
|
527
|
-
break;
|
|
528
|
-
if (m.isCompactSummary)
|
|
529
|
-
break;
|
|
530
|
-
const isToolResult = (0, tool_result_fold_1.isToolResultOnlyMessage)(m);
|
|
531
|
-
const isContinuationAssistant = m.role === 'assistant';
|
|
532
|
-
if (!isToolResult && !isContinuationAssistant)
|
|
533
|
-
break;
|
|
534
|
-
if (isContinuationAssistant && tailStopReason === 'end_turn')
|
|
535
|
-
break;
|
|
536
|
-
if (isContinuationAssistant)
|
|
537
|
-
tailStopReason = m.stopReason ?? null;
|
|
538
|
-
foldCount += 1;
|
|
539
|
-
}
|
|
624
|
+
const { foldCount, tailMutatedWithoutNewMessage } = (0, metrics_merge_1.computeLeadingContinuationFold)((0, metrics_merge_1.describeTail)(tail), newMessages);
|
|
540
625
|
if (foldCount === 0) {
|
|
541
626
|
return { merged: [...cachedMessages, ...newMessages], tailMutatedWithoutNewMessage: false };
|
|
542
627
|
}
|
|
@@ -552,51 +637,7 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
552
637
|
const remaining = newMessages.slice(foldCount);
|
|
553
638
|
return {
|
|
554
639
|
merged: [...cachedMessages.slice(0, -1), foldedTail, ...remaining],
|
|
555
|
-
tailMutatedWithoutNewMessage
|
|
556
|
-
};
|
|
557
|
-
}
|
|
558
|
-
mergeMetrics(existing, incremental, allMessages) {
|
|
559
|
-
const inputTokens = existing.inputTokens + incremental.inputTokens;
|
|
560
|
-
const outputTokens = existing.outputTokens + incremental.outputTokens;
|
|
561
|
-
const cacheReadTokens = existing.cacheReadTokens + incremental.cacheReadTokens;
|
|
562
|
-
const cacheCreationTokens = existing.cacheCreationTokens + incremental.cacheCreationTokens;
|
|
563
|
-
const totalTokens = inputTokens + outputTokens + cacheReadTokens + cacheCreationTokens;
|
|
564
|
-
let durationMs = existing.durationMs;
|
|
565
|
-
if (allMessages.length >= 2) {
|
|
566
|
-
durationMs =
|
|
567
|
-
allMessages[allMessages.length - 1].timestamp.getTime() -
|
|
568
|
-
allMessages[0].timestamp.getTime();
|
|
569
|
-
}
|
|
570
|
-
const modelsSet = new Set();
|
|
571
|
-
if (existing.primaryModel)
|
|
572
|
-
modelsSet.add(existing.primaryModel);
|
|
573
|
-
if (incremental.primaryModel)
|
|
574
|
-
modelsSet.add(incremental.primaryModel);
|
|
575
|
-
if (existing.modelsUsed)
|
|
576
|
-
existing.modelsUsed.forEach((m) => modelsSet.add(m));
|
|
577
|
-
if (incremental.modelsUsed)
|
|
578
|
-
incremental.modelsUsed.forEach((m) => modelsSet.add(m));
|
|
579
|
-
const modelsUsed = modelsSet.size > 1 ? Array.from(modelsSet) : undefined;
|
|
580
|
-
return {
|
|
581
|
-
inputTokens,
|
|
582
|
-
outputTokens,
|
|
583
|
-
cacheReadTokens,
|
|
584
|
-
cacheCreationTokens,
|
|
585
|
-
totalTokens,
|
|
586
|
-
costUsd: existing.costUsd + incremental.costUsd,
|
|
587
|
-
primaryModel: incremental.primaryModel ?? existing.primaryModel,
|
|
588
|
-
modelsUsed,
|
|
589
|
-
isOngoing: incremental.isOngoing,
|
|
590
|
-
visibleContextTokens: (0, estimate_content_tokens_1.estimateVisibleFromMessages)(allMessages),
|
|
591
|
-
totalContextTokens: incremental.totalContextTokens > 0
|
|
592
|
-
? incremental.totalContextTokens
|
|
593
|
-
: existing.totalContextTokens,
|
|
594
|
-
contextWindowTokens: incremental.contextWindowTokens ?? existing.contextWindowTokens,
|
|
595
|
-
messageCount: allMessages.length,
|
|
596
|
-
durationMs,
|
|
597
|
-
totalContextConsumption: existing.totalContextConsumption,
|
|
598
|
-
compactionCount: existing.compactionCount,
|
|
599
|
-
phaseBreakdowns: existing.phaseBreakdowns,
|
|
640
|
+
tailMutatedWithoutNewMessage,
|
|
600
641
|
};
|
|
601
642
|
}
|
|
602
643
|
mergeWarnings(existing, incremental) {
|
|
@@ -628,59 +669,31 @@ let SessionCacheService = SessionCacheService_1 = class SessionCacheService {
|
|
|
628
669
|
}
|
|
629
670
|
return 'same-file-rewrite';
|
|
630
671
|
}
|
|
631
|
-
async
|
|
672
|
+
async tryHashFileAnchors(filePath, expected, offset, allowGrowth = false) {
|
|
632
673
|
try {
|
|
633
|
-
return await
|
|
674
|
+
return await (0, bounded_anchor_proof_1.hashFileAnchors)(filePath, expected, offset, allowGrowth);
|
|
634
675
|
}
|
|
635
676
|
catch (error) {
|
|
636
|
-
this.logger.debug({ error, filePath }, 'File
|
|
677
|
+
this.logger.debug({ error, filePath }, 'File anchor proof unavailable — append is unsafe');
|
|
637
678
|
return undefined;
|
|
638
679
|
}
|
|
639
680
|
}
|
|
640
|
-
async
|
|
641
|
-
if (
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
if (current.size !== expected.size ||
|
|
651
|
-
current.mtime.getTime() !== expected.mtimeMs ||
|
|
652
|
-
`${current.dev}:${current.ino}` !== expected.fileIdentity) {
|
|
653
|
-
throw new Error('File changed while computing append proof');
|
|
654
|
-
}
|
|
655
|
-
};
|
|
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) {
|
|
656
691
|
try {
|
|
657
|
-
await
|
|
658
|
-
const prefixHash = (0, node_crypto_1.createHash)('sha256');
|
|
659
|
-
const fullHash = (0, node_crypto_1.createHash)('sha256');
|
|
660
|
-
const buffer = Buffer.allocUnsafe(Math.min(FILE_HASH_CHUNK_BYTES, Math.max(1, expected.size)));
|
|
661
|
-
let position = 0;
|
|
662
|
-
while (position < expected.size) {
|
|
663
|
-
const requested = Math.min(buffer.byteLength, expected.size - position);
|
|
664
|
-
const { bytesRead } = await handle.read(buffer, 0, requested, position);
|
|
665
|
-
if (bytesRead === 0) {
|
|
666
|
-
throw new Error('File ended while computing append proof');
|
|
667
|
-
}
|
|
668
|
-
const chunk = buffer.subarray(0, bytesRead);
|
|
669
|
-
fullHash.update(chunk);
|
|
670
|
-
const prefixBytes = Math.min(bytesRead, Math.max(0, prefixLength - position));
|
|
671
|
-
if (prefixBytes > 0) {
|
|
672
|
-
prefixHash.update(chunk.subarray(0, prefixBytes));
|
|
673
|
-
}
|
|
674
|
-
position += bytesRead;
|
|
675
|
-
}
|
|
676
|
-
await assertStableSnapshot();
|
|
677
|
-
return {
|
|
678
|
-
prefixDigest: prefixHash.digest('hex'),
|
|
679
|
-
fullDigest: fullHash.digest('hex'),
|
|
680
|
-
};
|
|
692
|
+
return (await (0, bounded_line_read_1.lastCompleteLineEnd)(filePath, 0, offset)) === offset;
|
|
681
693
|
}
|
|
682
|
-
|
|
683
|
-
|
|
694
|
+
catch (error) {
|
|
695
|
+
this.logger.debug({ error, filePath }, 'Line-boundary probe failed — withholding append proof');
|
|
696
|
+
return false;
|
|
684
697
|
}
|
|
685
698
|
}
|
|
686
699
|
toSourceRef(source, adapter) {
|