-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat: Add "Triangulate News" focus mode for multi-perspective news analysis #948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 15 files
Prompt for AI agents (all 3 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/components/TriangulatedNews/TriangulatedNewsSources.tsx">
<violation number="1" location="src/components/TriangulatedNews/TriangulatedNewsSources.tsx:52">
P1: The `overflow-hidden-scrollable` class added to `document.body` is not cleaned up if the component unmounts while the dialog is open. This can leave the page in a broken scrolling state. Use a `useEffect` cleanup to ensure the class is removed on unmount:
```tsx
useEffect(() => {
return () => {
document.body.classList.remove('overflow-hidden-scrollable');
};
}, []);
```</violation>
</file>
<file name="src/lib/biasLoader.ts">
<violation number="1" location="src/lib/biasLoader.ts:368">
P1: Synchronous file write (`appendFileSync`) on the request path blocks the event loop. Consider using async I/O (`fs/promises.appendFile`) with a debounced/batched write pattern, or queue unknown domains in memory and flush periodically.</violation>
<violation number="2" location="src/lib/biasLoader.ts:441">
P2: Multi-part TLD handling is incorrect. `news.bbc.co.uk` would look up `co.uk` instead of `bbc.co.uk`. Consider using a proper TLD parsing library (like `psl`) or at minimum checking for common multi-part TLDs (`.co.uk`, `.com.au`, etc.).</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
|
|
||
| const openModal = () => { | ||
| setIsDialogOpen(true); | ||
| document.body.classList.add('overflow-hidden-scrollable'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The overflow-hidden-scrollable class added to document.body is not cleaned up if the component unmounts while the dialog is open. This can leave the page in a broken scrolling state. Use a useEffect cleanup to ensure the class is removed on unmount:
useEffect(() => {
return () => {
document.body.classList.remove('overflow-hidden-scrollable');
};
}, []);Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/components/TriangulatedNews/TriangulatedNewsSources.tsx, line 52:
<comment>The `overflow-hidden-scrollable` class added to `document.body` is not cleaned up if the component unmounts while the dialog is open. This can leave the page in a broken scrolling state. Use a `useEffect` cleanup to ensure the class is removed on unmount:
```tsx
useEffect(() => {
return () => {
document.body.classList.remove('overflow-hidden-scrollable');
};
}, []);
```</comment>
<file context>
@@ -0,0 +1,190 @@
+
+ const openModal = () => {
+ setIsDialogOpen(true);
+ document.body.classList.add('overflow-hidden-scrollable');
+ };
+
</file context>
✅ Addressed in f3c6c4f
src/lib/biasLoader.ts
Outdated
| // Try without subdomains (e.g., news.bbc.com -> bbc.com) | ||
| const parts = cleanDomain.split('.'); | ||
| if (parts.length > 2) { | ||
| const rootDomain = parts.slice(-2).join('.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Multi-part TLD handling is incorrect. news.bbc.co.uk would look up co.uk instead of bbc.co.uk. Consider using a proper TLD parsing library (like psl) or at minimum checking for common multi-part TLDs (.co.uk, .com.au, etc.).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/biasLoader.ts, line 441:
<comment>Multi-part TLD handling is incorrect. `news.bbc.co.uk` would look up `co.uk` instead of `bbc.co.uk`. Consider using a proper TLD parsing library (like `psl`) or at minimum checking for common multi-part TLDs (`.co.uk`, `.com.au`, etc.).</comment>
<file context>
@@ -0,0 +1,523 @@
+ // Try without subdomains (e.g., news.bbc.com -> bbc.com)
+ const parts = cleanDomain.split('.');
+ if (parts.length > 2) {
+ const rootDomain = parts.slice(-2).join('.');
+ if (map.has(rootDomain)) {
+ return map.get(rootDomain)!;
</file context>
✅ Addressed in f3c6c4f
src/lib/biasLoader.ts
Outdated
| try { | ||
| const timestamp = new Date().toISOString().split('T')[0]; | ||
| const logLine = `${timestamp}\t${domain}\n`; | ||
| appendFileSync(UNKNOWN_DOMAINS_LOG_PATH, logLine); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Synchronous file write (appendFileSync) on the request path blocks the event loop. Consider using async I/O (fs/promises.appendFile) with a debounced/batched write pattern, or queue unknown domains in memory and flush periodically.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/biasLoader.ts, line 368:
<comment>Synchronous file write (`appendFileSync`) on the request path blocks the event loop. Consider using async I/O (`fs/promises.appendFile`) with a debounced/batched write pattern, or queue unknown domains in memory and flush periodically.</comment>
<file context>
@@ -0,0 +1,523 @@
+ try {
+ const timestamp = new Date().toISOString().split('T')[0];
+ const logLine = `${timestamp}\t${domain}\n`;
+ appendFileSync(UNKNOWN_DOMAINS_LOG_PATH, logLine);
+ } catch {
+ // Silently fail if we can't write (e.g., permissions)
</file context>
✅ Addressed in f3c6c4f
|
Hey @raydeStar, really appreciate the work you put into this. After reviewing it, we’ve decided not to merge this PR at this time We’re currently working on a larger update that will let the system reason more autonomously and pull in diverse perspectives on its own. Because of that direction, we don’t see a need for a dedicated triangulation feature in the project right now. The idea is solid, it’s just something the upcoming architecture will handle more naturally without requiring separate logic Thanks again for the effort we really do appreciate the contribution |
Hey, that's great!! If you need extra hands on a feature, reach out! I am looking to get more on my resume on AI tooling, so I'd be more than happy to help! Thanks for all you do! |
Summary
Adds a new "Triangulate News" focus mode that synthesizes news from multiple political perspectives to provide balanced, credible summaries.
Features
New Files
src/lib/search/newsTriangulate.ts- Core triangulation logicsrc/lib/biasLoader.ts- Media bias database loader with credibility scoringsrc/components/TriangulatedNews/*- UI components for displaying resultssrc/types/newsTriangulate.ts- TypeScript interfacesdata/bias/media_bias.csv- Media bias database (4,500+ sources)Modified Files
src/components/MessageInputActions/Focus.tsx- Added triangulation focus optionsrc/components/MessageBox.tsx- Render triangulated resultssrc/lib/search/index.ts- Route triangulation queriessrc/lib/hooks/useChat.tsx- Handle triangulated response formatTesting
Screenshots
Additional Notes
This is an idea that I've been turning around in my head for quite some time - a way to triangulate news, instead of reading from one source and hoping that it is correct. Gathering details from both sides, then agnosticizing the data, we will hopefully be left with facts instead of misleading information.
I've created a CSV file with information on websites and their bias listed. This was a list pulled from online, and I've done additions as well, using AI to vet and give a credibility score. This is all done to algorithmically detect how trustworthy our information is.
All tests were done locally on GPT-OSS 20B - something most LLM hobbyists should be able to run without too much trouble.
This is my first PR - I am a software developer by trade, in the field since mid-2016. Please let me know if I am missing some kind of process here.
Summary by cubic
Added a “Triangulate News” focus mode that compares articles across LEFT, CENTER, and RIGHT sources, clusters claims, and produces a neutral Reuters-style briefing with clear attribution. This improves transparency by showing shared facts, conflicts, and unique angles, backed by credibility scoring from a 4,500+ source database.
New Features
Refactors
Written for commit f3c6c4f. Summary will update automatically on new commits.