feat: LLM Implementation#160
Open
ahmedalkawaz wants to merge 87 commits into
Open
Conversation
Used optional chaining operator instead of longer boolean expression
Reduced onTopicsLoaded function complexity Project 1 individual change
…yload /topic endpoint now supports storing boolean field for anonymous for both posts and topics (stored as "true" or "false" string in redis)
Does not accept a null anonymous attribute
topics/{tid} endpoint now returns the stored anonymous field
Context
This PR introduces support for marking topics as “answered.”
Description
There is now a new answered field to the topic object and implements socket-based getter and setter endpoints to manage the field.
Changes
- Added answered field to topic creation logic in src/topics
- Default value set to 0
- Implemented: topics.getAnswered, topics.setAnswered
- Added privilege checks for read access
Testing
- Tested via browser console using:
- socket.emit('topics.setAnswered', { tid: 2, answered: true }, console.log);
- socket.emit('topics.getAnswered', 2, console.log);
…ibute feat: add an anonymous field to topic and post objects Overall this makes sense to me. Seemed to work well in the video as well.
Remove schema validation test for GET /api/admin/extend/plugins
Accidental require passport (not needed)
Remove schema validation test for GET /api/admin/extend/plugins
Context This merge commit adds a “Post anonymously” toggle to the NodeBB composer UI for new topics and replies. Description When a user opens the composer to create a new topic or reply, a “Post anonymously” switch is displayed alongside existing composer controls. This change is frontend-only. Changes - Added a composer anonymity toggle that renders whenever the composer is opened/loaded/enhanced - Injected the toggle into the composer near the toolbar area when available - Prevented duplicate insertion if composer rerenders - Stored the toggle state on the composer element for future backend integration Testing - Opened composer via Reply and New Topic and confirmed toggle appears consistently - Checked console/logging to confirm the handler runs on composer open events and the toggle state updates on change
From 1B: Reduce complexity of isGroupTitleValid function
This code implements the "marked as answered" feature. The code checks if a post is a question. If it is a question, the user can mark it as answered by clicking a button in the tools dropdown.
Added a compact category-scoped search next to the Add thread button.
Changes:
topic-list-bar.tpl — inserted a small search form (sends term + hidden categories={cid} to /search).
search.js — new client AMD module that intercepts the form and navigates via ajaxify.
topicList.js — wired the new module to initialize with the topic list.
No backend changes.
Answered tests
Revert "Answered tests"
Should correctly attach anonymous field to topic object upon creation
Exposes anonymous field only when uid requested
Context This PR updates answered/unanswered toggle feature across both the frontend and backend. This PR refines the feature behavior and adds comprehensive automated test coverage. Description Topics can be marked as questions and toggled between answered and unanswered states. When a user clicks “Mark as Answered,” a green “answered” tag appears next to the question title. When they click “Mark as Unanswered,” a red “unanswered” tag is shown instead. The frontend now uses color-coded tags to clearly reflect the topic’s state. On the backend, the original tracking system for “marked as answer” and “marked as question” has been removed and replaced with a cleaner tag-based approach that manages “answered,” “unanswered,” and “question” states more directly. This PR also introduces automated tests to verify the correctness of the state transitions, permission logic, and frontend rendering behavior. Changes Replaced the original answered/question tracking system with tag-based state handling Implemented color-coded frontend tags for answered and unanswered states Added tests for: markAnswered markUnanswered markAsQuestion unmarkAsQuestion Added permission tests to ensure non-owners and non-admins cannot mark topics as answered Added test/topics/answered-template.js to verify benchpress template rendering of answered/unanswered badges Testing Ran full test suite with npm run test Ran backend tests with npm test -- test/topics.js Ran frontend template tests with npm test test/topics/answered-template.js
Context This PR introduces support for marking topics and posts as “anonymous.” Description When the "Post anonymously" toggle is checked when drafting a post, it gets marked as anonymous and the username of the poster is hidden Changes Added plugin to scrub user data from posts and inject the toggle into the composer Changed topic and post schemas to show the anonymous fields of topic and post objects getFields methods for posts and topics now exposes anonymous field Tests for verifying the toggle injection rendering and user scrubbing functions of the plugin Testing Unit tests (npm test) npm install, ./nodebb activate nodebb-plugin-anon-toggle, then build and run to see the toggle and make test posts
Context This PR introduces a search bar on category pages that filters topics on the client-side as the user types. Description When a user navigates to a category page, a new search input is available in the topic list header. Typing into this input automatically hides topics whose titles don't match the query string. The search query string also securely persists across category navigation using the browser's sessionStorage. Changes Added an input search element to the topic list header in vendor/nodebb-theme-harmony-2.1.35/templates/partials/topic-list-bar.tpl Added client-side filtering and memory logic hooked to action:ajaxify.end in vendor/nodebb-theme-harmony-2.1.35/public/harmony.js Added rudimentary assert-based search filtering tests in test/category-search.js Testing Added lightweight client-side equivalent tests to test/category-search.js and checked whether they correctly simulated the filtering behavior of hiding un-matched topic array titles, passing without breaking the npm run test chain. Manually tested in the browser by typing strings into the newly created search bar to filter category topics, and clicking into other categories to visibly verify that the query term remained in the input and continued filtering successfully.
Context This PR adds a user guide for the new features (anonymous toggle, answered label, topics search bar for each category) Description/Changes User guide for the new features with descriptions of each feature, how to install/use them, and how to test them Testing None required (just adding a .md file that is not referenced or run in the actual functionality of NodeBB
Linux VM (Recitation 7)
Recitation 7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
This PR integrates an LLM-based translation service into NodeBB, enabling automatic detection and translation of non-English posts at creation time.
Description
When a user creates a post, NodeBB calls a separate Python Flask translator service powered by Ollama. The service classifies the language of the post and translates it to English if needed. Non-English posts display a "Click here to view the translated message" button that reveals the translation inline.
Changes
Created translator/ directory containing a standalone Flask translation microservice (src/translator.py, app.py, requirements.txt)
LLM integration uses Ollama with llama3.1:8b model for language classification and translation via structured prompts
Robust error handling: validates LLM output against a known languages list, falls back to assuming English on gibberish responses, empty translations, or service errors
Updated src/translate/index.js to call the Flask service asynchronously with graceful fallback if the service is unreachable
Unit tests in translator/test/unit/test_translator.py covering normal responses, English detection, gibberish handling, timeouts, empty translations, and empty input
Testing
Unit tests: cd translator && uv run pytest (7 tests passing)
Integration: requires three processes running simultaneously:
ollama serve (LLM backend)
cd translator && uv run flask run (translator service on port 5000)
NodeBB (./nodebb build && ./nodebb start)
Create a non-English post (e.g. "Dies ist eine deutsche Nachricht.") and verify the translate button appears with the English translation