Fix cache prune scope for non-inbox runs#6
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughGmailClient now lists messages with a query parameter, and agent.py derives a prune scope from the effective search query before pruning the seen-message cache. Tests cover query handling, pagination, and prune-scope selection. ChangesQuery-scoped Gmail listing and cache pruning
Estimated code review effort: 2 (Simple) | ~12 minutes Sequence Diagram(s)sequenceDiagram
participant run
participant _prune_query
participant _load_and_prune_cache
participant GmailClient
participant GmailAPI
run->>_prune_query: effective_query
_prune_query-->>run: prune_query
run->>_load_and_prune_cache: client, prune_query
_load_and_prune_cache->>GmailClient: list_message_ids(prune_query)
GmailClient->>GmailAPI: users().messages().list(q=prune_query)
GmailAPI-->>GmailClient: paginated ids or exception
GmailClient-->>_load_and_prune_cache: ids or error
_load_and_prune_cache-->>run: pruned cache
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
use_agent/gmail.py (1)
182-214: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConstants still named for "inbox" after generalization.
_INBOX_LIST_PAGE_CAP/_INBOX_LIST_PAGE_SIZE(used at Lines 193 and 200) are now used for arbitraryqueryvalues, not just inbox listing. Consider renaming to e.g._LIST_PAGE_CAP/_LIST_PAGE_SIZEto match the generalized method.🤖 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 `@use_agent/gmail.py` around lines 182 - 214, The pagination constants in list_message_ids are still named for inbox-only behavior even though the method now supports any query. Rename _INBOX_LIST_PAGE_CAP and _INBOX_LIST_PAGE_SIZE to query-neutral names like _LIST_PAGE_CAP and _LIST_PAGE_SIZE, and update their uses in list_message_ids so the symbols match the generalized behavior.
🤖 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 `@tests/test_prune_scope.py`:
- Line 3: The import in this test file uses a direct symbol import, which
violates the module-level import guideline. Update the top-level import to
import the use_agent module itself, then reference agent through that module
namespace wherever it is used in the test code.
In `@use_agent/agent.py`:
- Around line 407-423: The pruning scope extraction in _prune_query is
incorrectly matching negated operands like -in:spam or -label:x because
_PRUNE_OPERAND_RE allows a leading boundary match; update the regex or the
matching logic so a preceding negation is excluded before selecting the scope.
Keep the behavior in _prune_query the same for positive in:/label: operands and
the inbox fallback, but ensure only non-negated operands are returned.
---
Nitpick comments:
In `@use_agent/gmail.py`:
- Around line 182-214: The pagination constants in list_message_ids are still
named for inbox-only behavior even though the method now supports any query.
Rename _INBOX_LIST_PAGE_CAP and _INBOX_LIST_PAGE_SIZE to query-neutral names
like _LIST_PAGE_CAP and _LIST_PAGE_SIZE, and update their uses in
list_message_ids so the symbols match the generalized behavior.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ddea8ee0-cbb5-4798-858a-64705c83df53
📒 Files selected for processing (4)
tests/test_gmail_headers.pytests/test_prune_scope.pyuse_agent/agent.pyuse_agent/gmail.py
| @@ -0,0 +1,31 @@ | |||
| """Derivation of the cache-prune folder scope from a run query.""" | |||
|
|
|||
| from use_agent import agent | |||
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use module-level import instead of from ... import.
As per coding guidelines, **/*.py should "Use module-level imports only; do not use from ... import ... style imports. Import the module ... and reference members through the module namespace."
♻️ Proposed fix
-from use_agent import agent
+import use_agent.agent as agent📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| from use_agent import agent | |
| import use_agent.agent as agent |
🤖 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 `@tests/test_prune_scope.py` at line 3, The import in this test file uses a
direct symbol import, which violates the module-level import guideline. Update
the top-level import to import the use_agent module itself, then reference agent
through that module namespace wherever it is used in the test code.
Source: Coding guidelines
- _load_and_prune_cache hardcoded a list of in:inbox message-ids, then retained only those in the seen-cache. For a non-inbox run (e.g. --query in:spam) none of the processed messages are in:inbox, so every cached id was pruned each cycle. - The daemon then re-investigated the same non-actioned messages every tick, wasting API calls and tokens. Acted-on messages were unaffected (they leave the folder); only messages that stay put (e.g. NOT_COLD_SALES spam) were re-classified endlessly. - Generalize GmailClient.list_inbox_message_ids to list_message_ids (query param, default in:inbox), preserving pagination and the set[str] | None contract. - Derive the prune scope from effective_query via a local _prune_query helper: take the first in:<x>/label:<x> operand, else fall back to in:inbox. Default inbox runs are byte-for-byte unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Exclude negated folder operands (e.g. -in:spam) from _PRUNE_OPERAND_RE so a query that excludes a folder doesn't get mis-scoped to prune that folder; add regression tests - Rename _INBOX_LIST_PAGE_CAP/_INBOX_LIST_PAGE_SIZE to _LIST_PAGE_CAP/_LIST_PAGE_SIZE now that list_message_ids is used for arbitrary queries, not just the inbox Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
219256a to
8258335
Compare
Summary
Scope the daemon's seen-message cache prune to the folder each run
actually targets, instead of always listing
in:inbox.Problem
agent._load_and_prune_cachecalledclient.list_inbox_message_ids()(hardcoded
q=in:inbox) and thenseen.retain(inbox_ids)to dropcached ids no longer present. For a non-inbox run — e.g.
use-agent run --query in:spam— none of the processed messages arein:inbox, so every cached id was pruned on each cycle. The daemonthen re-investigated the same non-actioned messages every tick,
burning API calls and tokens. Acted-on messages were fine (they leave
the folder), but messages that stay put (e.g.
NOT_COLD_SALESspam)were re-classified endlessly.
Solution
GmailClient.list_inbox_message_idstolist_message_ids(query='in:inbox'), keeping its pagination andset[str] | Nonereturn contract.agent._prune_queryhelper that derives the prune scopefrom the run's
effective_query: the firstin:<x>/label:<x>operand, falling back to
in:inboxwhen the query names no folder.Default inbox runs remain byte-for-byte identical.
_load_and_prune_cachenow takes the derived prune query and listsvia the generalized method.
list_message_idsand the query→scope derivation across inbox/spam/label/lookback/no-folder cases.
ruff check,ruff format --check, andpytest -q(85 tests) all pass.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests