Skip to content

fix: preserve original casing in identify_main_topic#2885

Open
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-2882-20260710-1002
Open

fix: preserve original casing in identify_main_topic#2885
praisonai-triage-agent[bot] wants to merge 2 commits into
mainfrom
claude/issue-2882-20260710-1002

Conversation

@praisonai-triage-agent

@praisonai-triage-agent praisonai-triage-agent Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #2882

Summary

HybridConversationAnalyzer.identify_main_topic() lowercased all message text before running a regex designed to match capitalized phrases ([A-Z][a-z]+), so that pattern could never match. The function returned "rest api" and the case-sensitive test test_identify_main_topic failed on all platforms.

Changes

  • Run the capitalized-phrase regex on original-case text so acronyms/proper nouns (e.g. REST API) are preserved.
  • Run action/focus patterns (implement, working on, ...) on the lowercase copy.
  • Prefer capitalized candidates over lowercase action-object fragments (e.g. REST API over a rest api); fall back to action/focus candidates only when no capitalized phrase repeats.
  • Documented the return-value casing contract in the docstring.

Now identify_main_topic() returns 'REST API' for the standard fixture.

Test plan

  • test_identify_main_topic passes
  • All 13 tests in test_conversation_compaction.py pass (no regression in test_llm_analysis_fallback, etc.)

Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved conversation topic detection to better preserve capitalization, acronyms, and proper names.
    • Topic identification now prioritizes recurring named topics and selects more meaningful phrases when multiple candidates are equally common.
    • Improved fallback behavior for conversations focused on actions or tasks.

Run the capitalized-phrase regex on original-case text instead of a
lowercased copy so acronyms/proper nouns like "REST API" are preserved.
Action/focus patterns still run on lowercase text. Capitalized candidates
are preferred over lowercase action-object fragments.

Co-authored-by: praisonai-triage-agent[bot] <praisonai-triage-agent[bot]@users.noreply.github.com>
@MervinPraison

Copy link
Copy Markdown
Owner

@coderabbitai review

@MervinPraison

Copy link
Copy Markdown
Owner

/review

1 similar comment
@MervinPraison

Copy link
Copy Markdown
Owner

/review

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:manual-review Blocked: requires manual review pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet pipeline/final-claude-pending Reviews done; waiting for FINAL @claude labels Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bfce8b17-e3d8-40b1-a827-e120a648df69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

identify_main_topic now retains original message casing for capitalized and proper-noun candidates, extracts action/focus phrases from lowercase text, and prioritizes repeated capitalized candidates with phrase-length tie-breaking.

Changes

Topic extraction

Layer / File(s) Summary
Topic candidate selection
src/praisonai-agents/praisonaiagents/context/conversation.py
Message preprocessing preserves original content, capitalized candidates and lowercase action/focus candidates are extracted separately, and selection prioritizes repeated capitalized candidates before action/focus fallbacks.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: preserving original casing in identify_main_topic.
Linked Issues check ✅ Passed The changes address #2882 by using original-case text for capitalized topics and lowercase for action/focus matching, returning REST API.
Out of Scope Changes check ✅ Passed The diff appears limited to the identify_main_topic fix and related selection logic, with no unrelated scope added.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-2882-20260710-1002

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.

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR updates conversation topic detection to preserve readable casing. The main changes are:

  • Extract capitalized phrases from original-case text.
  • Match action and focus phrases against lowercase text.
  • Rank repeated topic candidates with casing as a tie-breaker.
  • Document the returned topic casing behavior.

Confidence Score: 4/5

This is close, but the topic ranking should be fixed before merging.

  • Repeated greetings can still beat equally repeated action topics.
  • The compacted summary can show a greeting instead of the real conversation topic.

src/praisonai-agents/praisonaiagents/context/conversation.py

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/context/conversation.py Updates topic extraction and ranking while preserving original casing for capitalized candidates.

Reviews (2): Last reviewed commit: "fix: rank conversation topics by frequen..." | Re-trigger Greptile

Comment thread src/praisonai-agents/praisonaiagents/context/conversation.py Outdated
@MervinPraison

Copy link
Copy Markdown
Owner

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions
  4. SDK value: review in depth whether the change genuinely adds value to the SDK — never add features for the sake of adding them. It must strengthen the SDK (simpler, more user-friendly, robust, world-class, secure). If it does not clearly add value, request changes or recommend rejecting/closing rather than merging scope creep
  5. Do not bloat the Agent class with additional params — only if absolutely required; we already support many params.
  6. Repo routing: agent-callable tools → PraisonAI-Tools; lifecycle plugins → PraisonAI-Plugins; optional sandbox backends → PraisonAI-Plugins (praisonai.sandbox entry point) — request changes if wrongly added to praisonaiagents/

Phase 2: FIX Valid Issues
7. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
8. Push all code fixes directly to THIS branch (do NOT create a new PR)
9. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
10. If all issues are resolved, approve the PR / close the Issue
11. If blocking issues remain, request changes / leave clear action items

@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed pipeline/final-claude-pending Reviews done; waiting for FINAL @claude pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet labels Jul 10, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task —— View job


Final Architecture Review — PR #2885

  • Read AGENTS.md + changed file
  • Verify Greptile P1 — CONFIRMED valid
  • Phase 1 architecture review
  • Fix the greeting-override bug
  • Run tests (13/13 pass)
  • Final verdict

Phase 1 — Architecture (per AGENTS.md)

Check Result
Protocol-driven ✅ Implementation in context/conversation.py, protocols stay in protocols.py. Correctly routed to praisonaiagents/.
Backward compatible ✅ Pure internal refactor of identify_main_topic; signature/return type unchanged.
Performance ✅ Not a hot path (compaction-time only); complexity unchanged.
SDK value ✅ Fixes a real correctness bug (case-sensitive test failing on all platforms). Adds no params, no deps, no Agent bloat.
Repo routing ✅ No tools/plugins/sandbox misplacement.

Phase 2 — Fix implemented

Greptile P1 (valid): repeated greetings override real topics. Confirmed by repro — Hello (×2) beat rest api (×3) because capitalized candidates were ranked entirely before lowercase candidates and short-circuited.

Fix in src/praisonai-agents/praisonaiagents/context/conversation.py:

  1. Frequency-first ranking — all repeated candidates now scored together by frequency; capitalization is only a tie-breaker (so REST API still beats a rest api at equal frequency, but a genuinely more-frequent lowercase topic wins over a rarely-repeated greeting).
  2. Bounded action/focus capture — the greedy [a-z\s]+ object pattern previously swallowed whole multi-sentence spans (>50 chars → discarded), which is why stray greetings won. Object capture is now limited to a short noun phrase (≤4 words), strips leading articles and trailing stop-words, so real topics survive as clean, countable candidates.
  3. Updated docstring to document the frequency-first + capitalization-tiebreaker contract.

Verification

  • Hello greeting scenario → now returns the recurring topic (rest api / database schema), no longer Hello.
  • Standard fixture → still 'REST API'.
  • test_conversation_compaction.py: 13/13 pass (no regression in test_identify_main_topic, test_llm_analysis_fallback).

Skipped: Other tests/unit/context/ failures (test_context_overflow.py, test_context_param.py) are pre-existing environment issues (ModuleNotFoundError: pydantic, unrelated mock NoneType) — unrelated to this change.

Phase 3 — Verdict

Approve. The original case-preservation fix is sound and correctly scoped; the one valid reviewer-flagged bug (greeting override) is now resolved and pushed to this branch. No blocking issues remain.

Note: I can't submit a formal GitHub approval (bot restriction), but from an architecture standpoint this is ready to merge.

Pushed commit 5e678c3 to claude/issue-2882-20260710-1002.

Job runBranch

@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.

🧹 Nitpick comments (1)
src/praisonai-agents/praisonaiagents/context/conversation.py (1)

88-153: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Core logic correctly fixes the casing bug; one design concern with sentence-initial words.

The two-set strategy and frequency/length-based selection are sound and produce the expected "REST API" result for the test fixture. The docstring clearly documents the casing contract. Approving the implementation.

One concern: cap_pattern matches any word starting with an uppercase letter, including common sentence-initial words like "The", "Help", "What". Since frequency is counted via combined_lower.count(candidate.lower()) — a substring search without word boundaries — a sentence-initial word like "Help" can accumulate a high frequency from its lowercase occurrences elsewhere in the conversation, potentially outranking meaningful proper nouns. In the current test fixture this works because "REST API" ties on frequency and wins on length, but conversations heavy with sentence-initial "The"/"This"/"That" could produce unexpected topics.

Consider adding a small stopword filter for common sentence-initial words, or using word-boundary-aware counting (e.g., len(re.findall(r'\b' + re.escape(candidate.lower()) + r'\b', combined_lower))). This is deferable since the current change is a net improvement over the previous fully-lowercased approach.

🤖 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/praisonai-agents/praisonaiagents/context/conversation.py` around lines 88
- 153, Prevent common sentence-initial words from being selected as topics in
identify_main_topic: add a small stopword filter for words such as “The”,
“This”, and “That”, and replace combined_lower.count(candidate.lower()) with
word-boundary-aware matching using re.escape so only complete candidate
occurrences contribute to frequency.
🤖 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.

Nitpick comments:
In `@src/praisonai-agents/praisonaiagents/context/conversation.py`:
- Around line 88-153: Prevent common sentence-initial words from being selected
as topics in identify_main_topic: add a small stopword filter for words such as
“The”, “This”, and “That”, and replace combined_lower.count(candidate.lower())
with word-boundary-aware matching using re.escape so only complete candidate
occurrences contribute to frequency.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d3fea16-771c-41fe-92a5-bdec7384d3b4

📥 Commits

Reviewing files that changed from the base of the PR and between eb4747f and 04de510.

📒 Files selected for processing (1)
  • src/praisonai-agents/praisonaiagents/context/conversation.py

…e real topics

Greptile P1: capitalized candidates were ranked entirely before lowercase
action candidates, so a repeated greeting (e.g. 'Hello') could win over a
more-frequently-discussed lowercase topic. Now all repeated candidates are
scored by frequency, with capitalization used only as a tie-breaker. Also
bound the action/focus object capture to a short noun phrase so real topics
survive the length filter instead of being swallowed by a greedy match.

Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
@MervinPraison MervinPraison added pipeline/blocked:stale-final Blocked: FINAL stale after new commits and removed pipeline/blocked:stale-final Blocked: FINAL stale after new commits labels Jul 10, 2026
# Prefer higher frequency, then capitalized phrases, then longer.
return max(
scored.values(),
key=lambda item: (item[1], item[2], len(item[0])),

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.

P1 Greetings Still Win

When a repeated greeting ties the actual topic, this tie-breaker still returns the greeting. For example, two messages like Hello, please implement a REST API and Hello, I am working on a REST API give Hello and rest api the same frequency, so is_cap makes Hello win. The compacted summary can then show the greeting as the conversation topic instead of the repeated action topic.

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!

@praisonai-triage-agent praisonai-triage-agent Bot removed pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown labels Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:manual-review Blocked: requires manual review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: identify_main_topic lowercases text before capitalized regex — test_identify_main_topic fails

1 participant