feat(categorize): add AI-powered auto-categorization watcher with mul… - #1410
Conversation
…ti-level taxonomy Introduces aw-watcher-categorize package supporting multi-provider AI models (OpenAI, Ollama, Gemini, Claude), deep 3-4 tier category taxonomy, real-time heartbeat emission, batch rule learning, and built-in offline heuristics.
Greptile SummaryIntroduces an AI-powered categorization watcher with offline heuristics, multiple model providers, real-time category heartbeats, and batch rule learning.
Confidence Score: 3/5The PR is not ready to merge because learned rules are persisted in an unusable form and the new watcher is omitted from standard build and release bundles. The settings update double-encodes the classes list, preventing generated rules from surviving or loading correctly, while the repository's explicit build and packaging paths never include the new executable. Files Needing Attention: aw-watcher-categorize/aw_watcher_categorize/learner.py, aw-watcher-categorize/pyproject.toml, Makefile, and aw.spec Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
W[Window/Web events] --> C[Multi-tier classifier]
R[Server rules] --> C
H[Built-in heuristics] --> C
C -->|fallback| AI[Configured AI provider]
C --> E[Categorization heartbeat]
AI --> L[Suggested regex]
L -->|learn/apply or auto-update| S[Server classes setting]
Reviews (1): Last reviewed commit: "feat(categorize): add AI-powered auto-ca..." | Re-trigger Greptile |
| existing_map[cat_tuple] = new_item | ||
|
|
||
| try: | ||
| client.set_setting("classes", json.dumps(raw_classes)) |
There was a problem hiding this comment.
Classes setting is double-encoded
When generated rules are applied, json.dumps(raw_classes) passes a string to set_setting, which serializes its value again. The server consequently stores classes as a JSON string instead of an array, preventing the learned rules from loading and causing later updates to fall back to the defaults.
| client.set_setting("classes", json.dumps(raw_classes)) | |
| client.set_setting("classes", raw_classes) |
| [tool.poetry] | ||
| name = "aw-watcher-categorize" | ||
| version = "0.1.0" | ||
| description = "Automated AI-powered categorization watcher and rule learner for ActivityWatch" | ||
| authors = ["ActivityWatch Contributors <erik@bjareho.lt>"] | ||
| license = "MPL-2.0" | ||
| readme = "README.md" | ||
|
|
||
| [tool.poetry.scripts] | ||
| aw-watcher-categorize = "aw_watcher_categorize.main:main" |
There was a problem hiding this comment.
Watcher is omitted from packaging
The new executable is not registered in the root Makefile module lists or the PyInstaller specification. Standard repository builds therefore neither build nor test this watcher, and released ActivityWatch bundles do not contain the advertised aw-watcher-categorize command.
Knowledge Base Used: Packaging assets
|
|
||
| class LRUCache: | ||
| def __init__(self, capacity: int = 2000): | ||
| self.capacity = capacity | ||
| self.cache: OrderedDict[str, ClassificationResult] = OrderedDict() | ||
|
|
||
| def get(self, key: str) -> Optional[ClassificationResult]: | ||
| if key not in self.cache: | ||
| return None | ||
| self.cache.move_to_end(key) | ||
| return self.cache[key] | ||
|
|
||
| def put(self, key: str, value: ClassificationResult) -> None: | ||
| if key in self.cache: | ||
| self.cache.move_to_end(key) | ||
| self.cache[key] = value | ||
| if len(self.cache) > self.capacity: | ||
| self.cache.popitem(last=False) |
There was a problem hiding this comment.
Cache lacks required profiling
This introduces a custom 2,000-entry LRU cache without profiling that identifies classification caching as a bottleneck. That adds memory use and maintenance complexity without a measured performance justification.
Rule Used: Before implementing performance optimizations, mea... (source)
Learned From
gptme/gptme#707
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…ti-level taxonomy
Introduces aw-watcher-categorize package supporting multi-provider AI models (OpenAI, Ollama, Gemini, Claude), deep 3-4 tier category taxonomy, real-time heartbeat emission, batch rule learning, and built-in offline heuristics.