feat: improve Memory v5 task/chat classification with LLM classifier#5493
Conversation
Add TaskClassifier interface with two implementations: - llmClassifier: uses provider with 2s timeout, fallback to heuristic - heuristicClassifier: improved keyword matching + file reference detection Add classificationCache with LRU eviction (100 entries max) and 5min TTL. Includes comprehensive unit tests for both classifiers and cache behavior.
Update Agent to use TaskClassifier: - Add classifier field and UseMemoryCompilerLLMClassification option - Initialize classifier in New() (LLM or heuristic based on flag) - Completely skip Memory v5 for chat inputs (not just injection) - Clear cache on session boundary Add REASONIX_MEMORY_COMPILER_LLM_CLASSIFICATION env var (default: false). When disabled (default), uses heuristic classifier. When enabled, uses LLM classifier with heuristic fallback on error/timeout.
Update TestRunDoesNotInjectMemoryCompilerContractForGreeting to expect zero stats events (chat inputs now completely skip Memory v5). Add two new E2E tests: - TestClassifierSkipsMemoryV5ForChat: verifies chat skips Memory v5 - TestClassifierUsesMemoryV5ForTask: verifies tasks use Memory v5
SivanCola
left a comment
There was a problem hiding this comment.
Approved. This is now a well-scoped fix for the Memory v5 chat/task noise reported in #5486 and the related user-visible compiler citation noise.
The selected mechanism is the right one: Memory v5 startup is gated by task/chat classification, the heuristic classifier remains the default path, the optional LLM classifier is explicitly opt-in, simple greetings and acknowledgements skip execution-contract injection, real task/failure descriptions still use Memory v5, and Memory v5 compiler citations are kept out of the visible transcript.
Why this fits the architecture:
- The default path stays local and cache-friendly; it does not add provider calls unless the opt-in environment flag is enabled.
- The classifier controls the Memory v5 startup/injection boundary instead of only decorating it, so non-imperative task reports like "the auth isn't working" still get the compiler path.
- It remains compatible with #5487: #5487 filters backend evidence citations, while this PR handles chat/task gating and transcript visibility.
The main thing I wanted tightened was the classifier-to-injection contract and the boundary coverage. The follow-up commits now cover the Memory v5 gating path, classifier caching, heuristic chat exclusions, Chinese task phrases, failure semantics, English boundary cases, and frontend citation visibility. Related older work in #5376 is superseded by this PR's newer implementation path.
Verified:
- latest GitHub checks are green: CI, race, desktop, lint, coverage, govulncheck, CodeQL, and cache-impact
- clean local merge against current
main-v2succeeded go test ./internal/agent/... ./internal/memorycompiler/...passed after that mergegit diff --checkpassed
Closes #5486
Summary
Improve Memory v5 task/chat detection logic, addressing false positives and false negatives in the keyword-matching approach.
Implemented in two phases:
Phase 1: Keyword-based Gating (first 3 commits)
59dc039 - Throttle memory compiler prompt injection
memorycompiler/runtime.goshouldInjectPrompt()to decide whether to inject the contractbc9b7f2 - Hide memory compiler citations in transcript
Message.tsxmemoryCitationVisibility.tsutility function76852fe - Gate memory compiler prompt injection for chat
shouldInjectMemoryCompilerContractForInput()inagent.gohello,hi,你好,fix,修复, etc.memory_compiler_gate_test.goProblem: The keyword approach suffers from false positives ("thanks for fixing" → task) and false negatives ("auth isn't working" → chat).
Phase 2: LLM-based Classifier (last 3 commits)
d916d0c - Add task/chat classifier infrastructure
task_classifier.go:TaskClassifierinterfacellmClassifier: classifies via Haiku model (2s timeout)heuristicClassifier: improved keyword fallbackclassificationCache: session-scoped cache (LRU + 5min TTL)bbc2d87 - Integrate classifier to gate Memory v5
agent.go:boot.go:REASONIX_MEMORY_COMPILER_LLM_CLASSIFICATIONfalse(gradual rollout)SetSession()097a49d - Update and add E2E tests for classifier behavior
TestRunDoesNotInjectMemoryCompilerContractForGreeting:TestClassifierSkipsMemoryV5ForChatTestClassifierUsesMemoryV5ForTaskCache-impact: low - New session-scoped cache (max 100 entries, ~10KB) only active when feature flag enabled (default: false). Cleared on session boundary.
Cache-guard: Comprehensive unit tests in internal/agent/task_classifier_cache_test.go covering Get/Set, TTL expiration, LRU eviction, normalization, and Clear behavior. Run: go test ./internal/agent/... -run TestClassificationCache -v
System-prompt-review: No system prompt content changes. Modified boot.go only adds feature flag configuration
(REASONIX_MEMORY_COMPILER_LLM_CLASSIFICATION) without altering prompt templates or agent instructions.
Verification
All tests pass:
go test ./internal/agent/... -vTest coverage
Cache details
New cache: classificationCache (only when feature flag is enabled)
Cache strategy: