Skip to content

feat(memory): scale Agent Memory with bounded workloads#1939

Merged
yyhhyyyyyy merged 13 commits into
devfrom
feat/agent-memory-performance-scale
Jul 11, 2026
Merged

feat(memory): scale Agent Memory with bounded workloads#1939
yyhhyyyyyy merged 13 commits into
devfrom
feat/agent-memory-performance-scale

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Scale Agent Memory for large memory corpora, long Tape histories, and multi-agent workloads while preserving existing correctness, privacy, and compatibility guarantees.

Changes

  • Add bounded FTS v4 recall with deterministic keyword selection and safe LIKE fallback.
  • Add vector readiness certificates, mutation serialization, and lease-safe store LRU.
  • Add a rebuildable Tape ingestion projection for bounded extraction-range reads.
  • Batch candidate decisions and embedding persistence with fixed provider and statement limits.
  • Add working-memory debounce and bounded maintenance budgets, queries, and concurrency.
  • Add memory.page keyset pagination while retaining deprecated memory.list compatibility.
  • Add paginated Memory Settings browsing, load-more, server search, coalesced refresh, and dirty-draft protection.
  • Enforce Unicode-aware content limits for manual and automatic memories.
  • Add bounded operational audit retention with an exact allowlist.
  • Add production performance counters, scale benchmarks, native CI gates, and standalone architecture documentation.

Summary by CodeRabbit

  • New Features
    • Added bounded, cursor-based “Load more” pagination for memory management (replacing full-list fetching).
  • Bug Fixes
    • Enforced Unicode-aware content size limits for manual and auto memory submissions; oversized inputs are now rejected with content-too-large.
    • Improved memory recall/search reliability with safer fallback behavior, and tightened working-memory refresh and maintenance behavior under update load.
    • Updated operational audit retention behavior for more consistent pruning.
  • Documentation
    • Added Agent Memory performance/scalability architecture plans/specs/tasks and native SQLite performance validation guidance.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7eea839e-bce7-45fd-a668-cfcccf4db169

📥 Commits

Reviewing files that changed from the base of the PR and between ffb49a5 and e1f8400.

📒 Files selected for processing (21)
  • docs/architecture/agent-memory-performance-and-scale/plan.md
  • docs/architecture/agent-memory-performance-and-scale/spec.md
  • docs/architecture/agent-memory-performance-and-scale/tasks.md
  • docs/architecture/agent-memory-system/spec.md
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/memoryPresenter/runtimeConstants.ts
  • src/main/presenter/memoryPresenter/services/maintenanceService.ts
  • src/main/presenter/memoryPresenter/services/reflectionService.ts
  • src/main/presenter/memoryPresenter/services/writeCoordinator.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts
  • src/main/routes/index.ts
  • src/renderer/settings/components/MemoryListView.vue
  • test/main/lib/asyncSemaphore.test.ts
  • test/main/presenter/agentMemoryAuditRetention.test.ts
  • test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
  • test/main/presenter/agentRuntimePresenter/tapeFacts.test.ts
  • test/main/presenter/memoryMaintenanceBudget.test.ts
  • test/main/presenter/memoryPresenter.test.ts
  • test/main/presenter/sqlitePresenter/deepchatMemoryIngestionProjection.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/renderer/components/MemoryListView.test.ts
💤 Files with no reviewable changes (1)
  • test/main/presenter/memoryMaintenanceBudget.test.ts
✅ Files skipped from review due to trivial changes (3)
  • docs/architecture/agent-memory-performance-and-scale/tasks.md
  • docs/architecture/agent-memory-performance-and-scale/spec.md
  • docs/architecture/agent-memory-performance-and-scale/plan.md
🚧 Files skipped from review as they are similar to previous changes (13)
  • test/main/routes/dispatcher.test.ts
  • src/main/routes/index.ts
  • test/main/presenter/agentMemoryAuditRetention.test.ts
  • src/main/presenter/memoryPresenter/services/reflectionService.ts
  • test/main/presenter/sqlitePresenter/deepchatMemoryIngestionProjection.test.ts
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts
  • src/renderer/settings/components/MemoryListView.vue
  • test/renderer/components/MemoryListView.test.ts
  • docs/architecture/agent-memory-system/spec.md
  • src/main/presenter/memoryPresenter/services/maintenanceService.ts
  • src/main/presenter/memoryPresenter/services/writeCoordinator.ts
  • test/main/presenter/memoryPresenter.test.ts

📝 Walkthrough

Walkthrough

Adds bounded agent-memory recall, ingestion projection, embedding and maintenance orchestration, keyset pagination, Unicode/content validation, performance instrumentation, native SQLite performance CI, and regression and scale tests.

Changes

Agent memory performance and scale

Layer / File(s) Summary
Architecture, contracts, and validation
docs/architecture/..., src/shared/..., scripts/architecture-guard.mjs, .github/workflows/prcheck.yml, package.json, vitest.config.memory-perf.ts
Documents bounded memory behavior, adds content and pagination contracts, shared Unicode utilities, architecture enforcement, and native SQLite performance validation.
Ingestion projection and tape semantics
src/main/presenter/sqlitePresenter/tables/deepchatMemoryIngestionProjection.ts, src/main/presenter/agentRuntimePresenter/*, src/main/presenter/sqlitePresenter/tables/deepchatTape*
Materializes effective message ranges, maintains projection currency, supports rebuild and fallback behavior, and updates extraction cursor commits.
Recall, batching, persistence, and maintenance
src/main/presenter/memoryPresenter/core/*, src/main/presenter/memoryPresenter/services/*, src/main/presenter/memoryPresenter/types.ts
Adds deterministic keyword selection, batched decision parsing, token budgets, bounded retrieval, revision-aware writes, maintenance concurrency, and Unicode content limits.
SQLite FTS and vector infrastructure
src/main/presenter/sqlitePresenter/tables/agentMemory*, src/main/presenter/memoryPresenter/infra/*
Adds policy-versioned FTS mirrors, strategy-based search, readiness certificates, lease and mutation barriers, batched vector persistence, coverage checks, and resource convergence.
Management pagination and renderer behavior
src/shared/contracts/routes/memory.routes.ts, src/main/routes/index.ts, src/renderer/api/MemoryClient.ts, src/renderer/settings/components/*, src/renderer/src/i18n/*
Adds bounded cursor pagination through IPC and renderer memory management, with stale-request handling, load-more behavior, refresh debouncing, and localized labels.
Regression and scale coverage
test/main/**, test/renderer/**
Adds native SQLite, FTS, projection, pagination, embedding, maintenance, workload-bound, Unicode, architecture-guard, and renderer race-condition tests.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.49% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: scaling Agent Memory with bounded workloads and performance-related constraints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agent-memory-performance-scale

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (9)
docs/architecture/agent-memory-performance-and-scale/tasks.md (1)

116-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: rephrase "with success" for conciseness.

The LanguageTool static analysis flags "with success" as potentially wordy. Consider rephrasing to "successful" or similar for brevity, though the current phrasing is grammatically correct and clear in context.

As per coding guidelines, static analysis hints should be selectively incorporated. This is a minor style suggestion that can be deferred.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/architecture/agent-memory-performance-and-scale/tasks.md` at line 116,
Rephrase the checklist item near “Key embedding connection warmup” to replace
“with success” with the more concise “successful” while preserving the existing
meaning.

Source: Linters/SAST tools

src/main/presenter/memoryPresenter/services/writeCoordinator.ts (1)

644-650: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider using DECISION_BATCH_MAX_BATCHES instead of hardcoded 2.

The maxBatches argument 2 matches DECISION_BATCH_MAX_BATCHES from batchDecision.ts, but if that constant changes, partitions beyond 2 would be silently skipped and their candidates sent to fallback. Importing and using the constant makes this relationship explicit and prevents a subtle regression.

♻️ Proposed refactor
 import {
+  DECISION_BATCH_MAX_BATCHES,
   parseBatchDecisionResults,
   partitionBatchDecisions,
   type BatchDecisionInput
 } from '../core/batchDecision'
     const initialBatch = await this.requestBatchDecisions(
       agentId,
       model,
       initialDecisionInputs,
-      2,
+      DECISION_BATCH_MAX_BATCHES,
       operationFence
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/memoryPresenter/services/writeCoordinator.ts` around lines
644 - 650, Replace the hardcoded maxBatches value 2 in writeCoordinator’s
initial requestBatchDecisions call with the DECISION_BATCH_MAX_BATCHES constant
imported from batchDecision.ts, preserving the existing behavior while keeping
it synchronized with the configured limit.
test/main/presenter/memoryMaintenanceBudget.test.ts (1)

1-8: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Test file combines two unrelated source modules, deviating from mirrored layout.

This file tests both AsyncSemaphore (src/main/lib/asyncSemaphore.ts) and MaintenanceBudget/selectMaintenanceRowsWithinTokenBudget (src/main/presenter/memoryPresenter/core/maintenanceBudget.ts) in one file under test/main/presenter/. A strict mirror would place the AsyncSemaphore suite under test/main/lib/asyncSemaphore.test.ts.

As per coding guidelines, "Place main-process Vitest suites under test/main/ and mirror the source layout there."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/main/presenter/memoryMaintenanceBudget.test.ts` around lines 1 - 8, The
test file mixes AsyncSemaphore tests with maintenance budget tests, violating
the mirrored test layout. Move the AsyncSemaphore suite and its import to
test/main/lib/asyncSemaphore.test.ts, leaving MaintenanceBudget and
selectMaintenanceRowsWithinTokenBudget tests in the presenter test file.

Source: Coding guidelines

src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts (1)

120-131: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Unrecognized/missing tool status silently treated as "final".

tapeToolRank treats any non-'pending' value (including null when meta_json.status is absent or non-string) as terminal (rank 2). If a tool_call row's status hasn't been recorded yet for reasons other than being explicitly 'pending', it would be treated as a completed/final tool call by callers using includePending=false, e.g. applyAppendedEntry in deepchatMemoryIngestionProjection.ts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts`
around lines 120 - 131, Update tapeToolRank to distinguish explicit terminal
statuses from missing or unrecognized statuses: preserve the existing pending
handling, but return a non-terminal rank for null or unsupported status values
so callers such as applyAppendedEntry do not treat them as completed. Use
readTapeToolStatus as the status source and define the accepted terminal status
values explicitly.
test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts (1)

1213-1296: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Good regression coverage for rebuild-then-cache and fallback paths; incremental applyAppendedEntry path remains untested here.

Both new tests validate that buildMemoryExtractionWindow rebuilds the projection once and then relies on bounded range reads, and that a readCurrentRange failure safely falls back to the authoritative Tape view while invalidating the projection. The mock's append unconditionally sets memoryIngestionProjectionCurrent = false (Line 360), so these tests never exercise the production applyAppendedEntry incremental-update code path (deepchatMemoryIngestionProjection.ts), which can keep the projection current without a full invalidate/rebuild when entries are appended sequentially. Consider adding a follow-up test elsewhere that exercises applyAppendedEntry directly against the real DeepChatMemoryIngestionProjectionTable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts`
around lines 1213 - 1296, Add regression coverage for the incremental
applyAppendedEntry path using the real DeepChatMemoryIngestionProjectionTable,
rather than the mock that always marks the projection stale. Append sequential
entries, call applyAppendedEntry directly, then verify readCurrentRange returns
the updated bounded rows without invalidation or full rebuild.
src/main/presenter/sqlitePresenter/tables/deepchatMemoryIngestionProjection.ts (1)

150-165: 🧹 Nitpick | 🔵 Trivial

Retraction and non-sequential apply always force a full invalidate/rebuild.

Any retraction event or non-sequential append forces invalidateSession (full rebuild on next read) rather than a targeted correction. This trades some rebuild cost for correctness/simplicity, which is a reasonable choice for a cache invalidation design, but worth confirming this doesn't become a hot path under bursty retraction/edit workloads at scale (per this PR's stated scale goals).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/presenter/sqlitePresenter/tables/deepchatMemoryIngestionProjection.ts`
around lines 150 - 165, The retraction and non-sequential append paths in the
projection handler always trigger full session invalidation, which may be costly
during bursts. Review the callers and implementation of invalidateSession and
the surrounding ingestion logic, then confirm this rebuild strategy is
acceptable at the expected scale; if not, replace it with targeted correction or
deduplicated/deferred invalidation while preserving correctness.
src/main/presenter/memoryPresenter/services/maintenanceService.ts (1)

509-515: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid wasted neighbor queries once the token budget is exhausted.

The budget precheck at Line 511 runs continue after the expensive queryNeighborsByMemoryId call (Line 475). When budget.snapshot().inputTokens approaches/exceeds MAINTENANCE_MAX_INPUT_TOKENS, every remaining scan row still triggers a vector neighbor query before hitting the continue, potentially wasting up to CONSOLIDATION_MAX_NEIGHBOR_SCANS queries. Since the budget only grows within a pass, add an early break at the top of the loop when no remaining capacity exists.

♻️ Suggested guard at loop start (Line 466)
       for (const row of scanRows) {
         lastScanned = row
+        if (MAINTENANCE_MAX_INPUT_TOKENS - budget.snapshot().inputTokens <= 0) break
         if (merged.has(row.id)) continue
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/memoryPresenter/services/maintenanceService.ts` around
lines 509 - 515, Add an early budget-capacity guard at the start of the scan
loop in the maintenance service, before any query such as
queryNeighborsByMemoryId runs. Break when budget.snapshot().inputTokens has
reached MAINTENANCE_MAX_INPUT_TOKENS; retain the existing per-candidate precheck
for prompt-size validation.
src/main/presenter/memoryPresenter/services/reflectionService.ts (1)

73-76: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider naming the 256 token overhead buffer.

The 256 subtracted from availableTokens is a prompt-template overhead allowance. If this value is too small and the template grows, budget.reserve at line 85 will silently fail and skip reflection. Extracting it as a named constant (e.g., REFLECTION_PROMPT_OVERHEAD_TOKENS) alongside the other constants in runtimeConstants.ts would make the intent explicit and simplify future tuning.

♻️ Optional refactor
 const availableTokens = Math.max(
   0,
-  MAINTENANCE_MAX_INPUT_TOKENS - budget.snapshot().inputTokens - 256
+  MAINTENANCE_MAX_INPUT_TOKENS - budget.snapshot().inputTokens - REFLECTION_PROMPT_OVERHEAD_TOKENS
 )

And in runtimeConstants.ts:

+export const REFLECTION_PROMPT_OVERHEAD_TOKENS = 256
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/memoryPresenter/services/reflectionService.ts` around
lines 73 - 76, Replace the magic 256 token subtraction in the reflection token
calculation with a named REFLECTION_PROMPT_OVERHEAD_TOKENS constant defined
alongside the other runtime constants, then use that constant in the
availableTokens calculation and update any related references.
test/main/routes/dispatcher.test.ts (1)

2262-2314: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a guard-branch case for memory.page.

Every other memory.* dispatch test here (getByIds, archive, reindex, getHealth, getLifecycle) verifies both the non-deepchat-agent guard and the success path. The new memory.page test only exercises the success path — worth adding a companion case asserting pageMemories is not called and an empty page is returned for a non-managed agent, matching the sibling tests' pattern.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/main/routes/dispatcher.test.ts` around lines 2262 - 2314, Add a
companion `memory.page` dispatch test for a non-managed agent, following the
guard-branch pattern used by the other `memory.*` tests. Assert `pageMemories`
is not called and the result contains an empty items array (with no next
cursor), then retain the existing deepchat success-path test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/architecture/agent-memory-system/spec.md`:
- Around line 126-133: Update the module table entry for asyncSemaphore to
reference src/main/lib/asyncSemaphore.ts instead of
memoryPresenter/infra/asyncSemaphore.ts, preserving its existing description.

In `@src/main/presenter/agentRuntimePresenter/index.ts`:
- Around line 2798-2932: Persistent failures in rebuildMemoryIngestionRange
leave extraction permanently unable to commit its cursor, causing the same tape
tail to rebuild on every run. Add a bounded retry or circuit-breaker around
projectionTable.replaceSession, tracking failures per session and suppressing
repeated rebuild attempts for a cooldown or threshold; alternatively propagate
an explicit degraded state that buildMemoryExtractionWindow can handle without
repeatedly clearing cursorCommitOrderSeq. Update listMemoryIngestionRange and
rebuildMemoryIngestionRange consistently so recovery after a successful
replacement resets the failure state.

In `@src/renderer/settings/components/MemoryListView.vue`:
- Around line 151-161: Hide the load-more footer while a search is active by
adding a !searchActive condition to the existing v-if around the
memory-load-more Button. Locate the template block using
data-testid="memory-load-more"; retain the existing initialLoading and
nextCursor guards alongside the new searchActive guard.

In `@test/main/presenter/agentMemoryAuditRetention.test.ts`:
- Around line 39-41: Update the query-plan assertion in
agentMemoryAuditRetention tests to require the exact replacement index name,
changing the expected value to idx_agent_memory_audit_operational_retention_v2
rather than the shared prefix.

In `@test/main/presenter/agentMemoryTable.test.ts`:
- Around line 1630-1651: Guard the test “drops a partial FTS build and fails
open to one bounded LIKE query” against the required-native environment by
temporarily clearing DEEPCHAT_REQUIRE_NATIVE_SQLITE for its duration and
restoring the original value afterward. Keep the existing simulated FTS failure
and LIKE fallback assertions unchanged.

In `@test/main/presenter/memoryPresenter.test.ts`:
- Around line 5916-5931: Fix the copy-paste error in the target ID setup by
changing the repo.updateStatus call inside the targetIds map callback to use the
loop’s id for both the row identifier and embeddingId, ensuring each target-N
record receives the intended embedding metadata.

---

Nitpick comments:
In `@docs/architecture/agent-memory-performance-and-scale/tasks.md`:
- Line 116: Rephrase the checklist item near “Key embedding connection warmup”
to replace “with success” with the more concise “successful” while preserving
the existing meaning.

In `@src/main/presenter/memoryPresenter/services/maintenanceService.ts`:
- Around line 509-515: Add an early budget-capacity guard at the start of the
scan loop in the maintenance service, before any query such as
queryNeighborsByMemoryId runs. Break when budget.snapshot().inputTokens has
reached MAINTENANCE_MAX_INPUT_TOKENS; retain the existing per-candidate precheck
for prompt-size validation.

In `@src/main/presenter/memoryPresenter/services/reflectionService.ts`:
- Around line 73-76: Replace the magic 256 token subtraction in the reflection
token calculation with a named REFLECTION_PROMPT_OVERHEAD_TOKENS constant
defined alongside the other runtime constants, then use that constant in the
availableTokens calculation and update any related references.

In `@src/main/presenter/memoryPresenter/services/writeCoordinator.ts`:
- Around line 644-650: Replace the hardcoded maxBatches value 2 in
writeCoordinator’s initial requestBatchDecisions call with the
DECISION_BATCH_MAX_BATCHES constant imported from batchDecision.ts, preserving
the existing behavior while keeping it synchronized with the configured limit.

In
`@src/main/presenter/sqlitePresenter/tables/deepchatMemoryIngestionProjection.ts`:
- Around line 150-165: The retraction and non-sequential append paths in the
projection handler always trigger full session invalidation, which may be costly
during bursts. Review the callers and implementation of invalidateSession and
the surrounding ingestion logic, then confirm this rebuild strategy is
acceptable at the expected scale; if not, replace it with targeted correction or
deduplicated/deferred invalidation while preserving correctness.

In `@src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts`:
- Around line 120-131: Update tapeToolRank to distinguish explicit terminal
statuses from missing or unrecognized statuses: preserve the existing pending
handling, but return a non-terminal rank for null or unsupported status values
so callers such as applyAppendedEntry do not treat them as completed. Use
readTapeToolStatus as the status source and define the accepted terminal status
values explicitly.

In `@test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts`:
- Around line 1213-1296: Add regression coverage for the incremental
applyAppendedEntry path using the real DeepChatMemoryIngestionProjectionTable,
rather than the mock that always marks the projection stale. Append sequential
entries, call applyAppendedEntry directly, then verify readCurrentRange returns
the updated bounded rows without invalidation or full rebuild.

In `@test/main/presenter/memoryMaintenanceBudget.test.ts`:
- Around line 1-8: The test file mixes AsyncSemaphore tests with maintenance
budget tests, violating the mirrored test layout. Move the AsyncSemaphore suite
and its import to test/main/lib/asyncSemaphore.test.ts, leaving
MaintenanceBudget and selectMaintenanceRowsWithinTokenBudget tests in the
presenter test file.

In `@test/main/routes/dispatcher.test.ts`:
- Around line 2262-2314: Add a companion `memory.page` dispatch test for a
non-managed agent, following the guard-branch pattern used by the other
`memory.*` tests. Assert `pageMemories` is not called and the result contains an
empty items array (with no next cursor), then retain the existing deepchat
success-path test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd89b399-80a8-4db7-bdff-248a6732d6c7

📥 Commits

Reviewing files that changed from the base of the PR and between 1882065 and 30896d0.

📒 Files selected for processing (120)
  • .github/workflows/prcheck.yml
  • docs/architecture/agent-memory-performance-and-scale/plan.md
  • docs/architecture/agent-memory-performance-and-scale/spec.md
  • docs/architecture/agent-memory-performance-and-scale/tasks.md
  • docs/architecture/agent-memory-system/spec.md
  • package.json
  • scripts/architecture-guard.mjs
  • src/main/lib/asyncSemaphore.ts
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/agentRuntimePresenter/memoryExtractionChunks.ts
  • src/main/presenter/agentRuntimePresenter/tapeEffectiveView.ts
  • src/main/presenter/agentRuntimePresenter/tapeFacts.ts
  • src/main/presenter/configPresenter/index.ts
  • src/main/presenter/index.ts
  • src/main/presenter/memoryPresenter/context.ts
  • src/main/presenter/memoryPresenter/core/batchDecision.ts
  • src/main/presenter/memoryPresenter/core/decision.ts
  • src/main/presenter/memoryPresenter/core/extraction.ts
  • src/main/presenter/memoryPresenter/core/jsonExtraction.ts
  • src/main/presenter/memoryPresenter/core/lifecycle.ts
  • src/main/presenter/memoryPresenter/core/maintenanceBudget.ts
  • src/main/presenter/memoryPresenter/core/recallKeyword.ts
  • src/main/presenter/memoryPresenter/index.ts
  • src/main/presenter/memoryPresenter/infra/embeddingPipeline.ts
  • src/main/presenter/memoryPresenter/infra/memoryVectorStore.ts
  • src/main/presenter/memoryPresenter/infra/providerGateway.ts
  • src/main/presenter/memoryPresenter/infra/vectorStoreManager.ts
  • src/main/presenter/memoryPresenter/ports.ts
  • src/main/presenter/memoryPresenter/runtimeConstants.ts
  • src/main/presenter/memoryPresenter/services/conflictService.ts
  • src/main/presenter/memoryPresenter/services/maintenanceService.ts
  • src/main/presenter/memoryPresenter/services/managementService.ts
  • src/main/presenter/memoryPresenter/services/personaService.ts
  • src/main/presenter/memoryPresenter/services/reflectionService.ts
  • src/main/presenter/memoryPresenter/services/retrievalService.ts
  • src/main/presenter/memoryPresenter/services/workingMemoryService.ts
  • src/main/presenter/memoryPresenter/services/writeCoordinator.ts
  • src/main/presenter/memoryPresenter/types.ts
  • src/main/presenter/sqlitePresenter/importData.ts
  • src/main/presenter/sqlitePresenter/index.ts
  • src/main/presenter/sqlitePresenter/schemaCatalog.ts
  • src/main/presenter/sqlitePresenter/sqliteCopyExclusions.ts
  • src/main/presenter/sqlitePresenter/tables/agentMemory.ts
  • src/main/presenter/sqlitePresenter/tables/agentMemoryAudit.ts
  • src/main/presenter/sqlitePresenter/tables/agentMemoryFtsPolicy.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatMemoryIngestionProjection.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatTapeEffectiveSemantics.ts
  • src/main/presenter/sqlitePresenter/tables/deepchatTapeEntries.ts
  • src/main/presenter/toolPresenter/agentTools/agentMemoryTools.ts
  • src/main/presenter/workspacePresenter/concurrencyLimiter.ts
  • src/main/presenter/workspacePresenter/fileSearcher.ts
  • src/main/routes/index.ts
  • src/renderer/api/MemoryClient.ts
  • src/renderer/settings/components/MemoryLifecyclePanel.vue
  • src/renderer/settings/components/MemoryListView.vue
  • src/renderer/settings/components/MemorySettings.vue
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shared/contracts/routes.ts
  • src/shared/contracts/routes/memory.routes.ts
  • src/shared/lib/unicodeText.ts
  • src/shared/types/agent-memory.ts
  • test/main/nativeSqliteHarness.ts
  • test/main/performance/memory/fixtures.ts
  • test/main/performance/memory/maintenanceScale.perf.ts
  • test/main/performance/memory/memoryBaseline.perf.ts
  • test/main/performance/memory/performanceObserver.ts
  • test/main/performance/memory/recallScale.perf.ts
  • test/main/performance/memory/tapeScale.perf.ts
  • test/main/performance/memory/timing.ts
  • test/main/performance/memory/workloadBounds.perf.ts
  • test/main/presenter/agentMemoryAuditRetention.test.ts
  • test/main/presenter/agentMemoryPaginationNative.test.ts
  • test/main/presenter/agentMemoryTable.test.ts
  • test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
  • test/main/presenter/agentRuntimePresenter/memoryExtractionChunks.test.ts
  • test/main/presenter/configPresenter/deprecatedProviderCleanup.test.ts
  • test/main/presenter/fakes/memoryFakes.ts
  • test/main/presenter/memoryAdd.test.ts
  • test/main/presenter/memoryAuditRetention.test.ts
  • test/main/presenter/memoryBatchDecision.test.ts
  • test/main/presenter/memoryEmbeddingScale.test.ts
  • test/main/presenter/memoryExtraction.test.ts
  • test/main/presenter/memoryLifecycle.test.ts
  • test/main/presenter/memoryMaintenanceBudget.test.ts
  • test/main/presenter/memoryNativeMigration.test.ts
  • test/main/presenter/memoryPagination.test.ts
  • test/main/presenter/memoryPresenter.test.ts
  • test/main/presenter/memoryRetrieval.eval.test.ts
  • test/main/presenter/memoryUpdate.test.ts
  • test/main/presenter/memoryVectorStore.test.ts
  • test/main/presenter/recallKeyword.test.ts
  • test/main/presenter/sqlitePresenter/deepchatMemoryIngestionProjection.test.ts
  • test/main/presenter/toolPresenter/agentTools/agentMemoryTools.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/main/routes/memoryDto.test.ts
  • test/main/scripts/architectureGuard.test.ts
  • test/main/shared/unicodeText.test.ts
  • test/renderer/api/clients.test.ts
  • test/renderer/components/MemoryListView.test.ts
  • test/renderer/components/MemorySettings.test.ts
  • vitest.config.memory-perf.ts
💤 Files with no reviewable changes (1)
  • src/main/presenter/workspacePresenter/concurrencyLimiter.ts

Comment thread docs/architecture/agent-memory-system/spec.md
Comment thread src/main/presenter/agentRuntimePresenter/index.ts
Comment thread src/renderer/settings/components/MemoryListView.vue Outdated
Comment thread test/main/presenter/agentMemoryAuditRetention.test.ts
Comment thread test/main/presenter/agentMemoryTable.test.ts
Comment thread test/main/presenter/memoryPresenter.test.ts
@yyhhyyyyyy yyhhyyyyyy merged commit d76bd37 into dev Jul 11, 2026
4 checks passed
@yyhhyyyyyy yyhhyyyyyy deleted the feat/agent-memory-performance-scale branch July 11, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant