Main pr jan20#86
Conversation
…llapsed thresholds)
Pass questionsToAdd as a top-level parameter to workspaceWorker instead of nesting it in quizData, and remove unused variable.
Simplify workspace context by removing emoji icons and the internal PDF_CONTENT_URL marker.
Update logic to correctly handle adding new questions to a completed quiz and simplify memoization comparisons.
Prevent stripping valid punctuation after inline math and ensure mixed-content paragraphs (with links/mentions) are not incorrectly converted to block math.
Update regex patterns to support literal/escaped dollar signs within math delimiters.
…er mismatch; consolidate state loading logic
Greptile SummaryThis PR adds comprehensive quiz functionality to ThinkEx, enabling users to create interactive multiple-choice and true/false quizzes either from selected workspace content or general topics. The implementation includes adaptive difficulty adjustment based on user performance, LaTeX math support for STEM subjects, and session persistence for resuming quizzes. Major Changes:
Key Features:
Architecture Notes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant Assistant
participant QuizTool as createQuiz/updateQuiz Tool
participant QuizWorker
participant WorkspaceWorker
participant Database
participant UI as QuizContent Component
User->>Assistant: "Create a quiz on [topic]" or select cards + "create quiz"
Assistant->>QuizTool: Call createQuiz tool
QuizTool->>QuizTool: Extract context from selected cards
QuizTool->>QuizWorker: Generate quiz questions
QuizWorker->>QuizWorker: Build adaptive prompt with difficulty
QuizWorker->>QuizWorker: Sanitize LaTeX in JSON response
QuizWorker-->>QuizTool: Return quiz questions + title
QuizTool->>WorkspaceWorker: Create quiz item
WorkspaceWorker->>Database: Append ITEM_CREATED event
Database-->>WorkspaceWorker: Success
WorkspaceWorker-->>QuizTool: Return itemId
QuizTool-->>Assistant: Success result
Assistant->>UI: Display CreateQuizToolUI
UI->>User: Show quiz card in workspace
User->>UI: Start quiz (click on quiz card)
UI->>UI: Load QuizContent component
UI->>UI: Render first question
User->>UI: Select answer + Submit
UI->>UI: Update session state
UI->>Database: Persist session via onUpdateData
UI->>User: Show explanation + Next button
User->>Assistant: "Add more questions"
Assistant->>QuizTool: Call updateQuiz tool
QuizTool->>Database: Load workspace state
QuizTool->>QuizTool: Analyze user performance telemetry
QuizTool->>QuizWorker: Generate adaptive questions
QuizWorker-->>QuizTool: Return new questions
QuizTool->>WorkspaceWorker: Update quiz (append questions)
WorkspaceWorker->>Database: Append ITEM_UPDATED event
Database-->>WorkspaceWorker: Success
WorkspaceWorker-->>QuizTool: Success
QuizTool-->>Assistant: Success result
Assistant->>UI: Display UpdateQuizToolUI
UI->>UI: Detect new questions added
UI->>User: Toast notification + navigate to new questions
|
|
|
||
| // Sanitize LaTeX escape sequences before parsing | ||
| // We need to double-escape backslashes that aren't valid JSON escapes | ||
| jsonText = jsonText.replace(/\\(?!["\\/bfnrtu])/g, '\\\\'); |
There was a problem hiding this comment.
logic: incomplete regex pattern for LaTeX escape sequences
the negative lookahead (?!["\\/bfnrtu]) only checks for valid JSON escape sequences, but LaTeX uses many more backslash patterns (e.g. \alpha, \beta, \frac, \sqrt). this will double-escape valid LaTeX, breaking math rendering
| jsonText = jsonText.replace(/\\(?!["\\/bfnrtu])/g, '\\\\'); | |
| // Sanitize LaTeX: preserve backslashes in JSON strings | |
| jsonText = jsonText.replace(/\\(?=["\\\/bfnrtu])/g, '\\\\'); |
alternatively, handle LaTeX preservation more carefully by parsing string content separately
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/ai/workers/quiz-worker.ts
Line: 200:200
Comment:
**logic:** incomplete regex pattern for LaTeX escape sequences
the negative lookahead `(?!["\\/bfnrtu])` only checks for valid JSON escape sequences, but LaTeX uses many more backslash patterns (e.g. `\alpha`, `\beta`, `\frac`, `\sqrt`). this will double-escape valid LaTeX, breaking math rendering
```suggestion
// Sanitize LaTeX: preserve backslashes in JSON strings
jsonText = jsonText.replace(/\\(?=["\\\/bfnrtu])/g, '\\\\');
```
alternatively, handle LaTeX preservation more carefully by parsing string content separately
How can I resolve this? If you propose a fix, please make it concise.|
@greptile how did deep research change in this pr |
|
@greptile explain cleanedMessages |
There was a problem hiding this comment.
Looking at the code in the chat route, cleanedMessages refers to a processed version of the conversation messages that have been sanitized and normalized before being passed to the AI tools.
Here's what happens:
Message Cleaning Process
The cleanedMessages are created by processing the raw messages from the chat request to:
- Remove or sanitize problematic content that could interfere with AI processing
- Normalize message formats to ensure consistent structure
- Preserve essential context while removing noise
Usage in Quiz Tools
In the quiz tools (src/lib/ai/tools/quiz-tools.ts), the cleanedMessages are used to:
// Extract user's intent from their latest message
function extractUserMessage(messages: any[]): string | undefined {
// Find the last user message (most recent request)
for (let i = messages.length - 1; i >= 0; i--) {
const msg = messages[i];
if (msg.role === 'user') {
if (typeof msg.content === 'string') {
return cleanMessageForTopic(msg.content);
}
// Handle multi-part messages...
}
}
}Key Functions
- Topic Extraction: Extract what the user actually wants the quiz to be about
- Context Detection: Find selected cards context using
extractSelectedCardsContext() - Intent Understanding: Determine if user wants to create new quiz vs update existing
Message Structure
The messages typically contain:
- User messages: What the user typed
- Assistant responses: Previous AI responses
- System context: Selected cards data marked with
[[SELECTED_CARDS_MARKER]] - Tool results: Results from previous tool executions
Why "Cleaned"?
The messages are "cleaned" because they may contain:
- Raw markdown that needs normalization
- System markers that should be filtered out for topic extraction
- File URLs and metadata that aren't relevant to understanding user intent
- Special formatting that could confuse the AI models
The cleaning ensures the AI tools get the most relevant information for generating appropriate quiz content based on either the user's specified topic or selected card content.
The regex pattern was incorrectly double-escaping LaTeX sequences like \alpha, \beta, \frac, breaking math rendering. Removed the problematic sanitization as JSON parser handles properly escaped JSON correctly.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/app/globals.css`:
- Around line 1243-1263: The file contains duplicate declarations for the
`@keyframes` gradient-rotate and the .gradient-border-animated class; remove this
later duplicate block so only the original definitions remain (keep the earlier
definitions already declared around gradient-rotate and
.gradient-border-animated and delete the repeated declarations in this later
section), and verify no other styles rely on a different variant name so
references to gradient-rotate and .gradient-border-animated remain unchanged.
| /* Animated gradient border - rotates colors around the border in a circle */ | ||
| @keyframes gradient-rotate { | ||
| 0% { background-position: 0% 0%; } | ||
| 25% { background-position: 100% 0%; } | ||
| 50% { background-position: 100% 100%; } | ||
| 75% { background-position: 0% 100%; } | ||
| 100% { background-position: 0% 0%; } | ||
| } | ||
| .gradient-border-animated { | ||
| background: linear-gradient( | ||
| 90deg, | ||
| #ef444480, | ||
| #eab30880, | ||
| #22c55e80, | ||
| #3b82f680, | ||
| #a855f780, | ||
| #ef444480 | ||
| ); | ||
| background-size: 200% 200%; | ||
| animation: gradient-rotate 10s ease-in-out infinite; | ||
| } |
There was a problem hiding this comment.
Remove duplicate gradient border definitions.
The @keyframes gradient-rotate and .gradient-border-animated are already defined earlier in this file (lines 586–616). These identical declarations should be removed to avoid maintenance confusion.
🧹 Suggested fix: remove duplicate definitions
-/* Animated gradient border - rotates colors around the border in a circle */
-@keyframes gradient-rotate {
- 0% { background-position: 0% 0%; }
- 25% { background-position: 100% 0%; }
- 50% { background-position: 100% 100%; }
- 75% { background-position: 0% 100%; }
- 100% { background-position: 0% 0%; }
-}
-.gradient-border-animated {
- background: linear-gradient(
- 90deg,
- `#ef444480`,
- `#eab30880`,
- `#22c55e80`,
- `#3b82f680`,
- `#a855f780`,
- `#ef444480`
- );
- background-size: 200% 200%;
- animation: gradient-rotate 10s ease-in-out infinite;
-}📝 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.
| /* Animated gradient border - rotates colors around the border in a circle */ | |
| @keyframes gradient-rotate { | |
| 0% { background-position: 0% 0%; } | |
| 25% { background-position: 100% 0%; } | |
| 50% { background-position: 100% 100%; } | |
| 75% { background-position: 0% 100%; } | |
| 100% { background-position: 0% 0%; } | |
| } | |
| .gradient-border-animated { | |
| background: linear-gradient( | |
| 90deg, | |
| #ef444480, | |
| #eab30880, | |
| #22c55e80, | |
| #3b82f680, | |
| #a855f780, | |
| #ef444480 | |
| ); | |
| background-size: 200% 200%; | |
| animation: gradient-rotate 10s ease-in-out infinite; | |
| } |
🤖 Prompt for AI Agents
In `@src/app/globals.css` around lines 1243 - 1263, The file contains duplicate
declarations for the `@keyframes` gradient-rotate and the
.gradient-border-animated class; remove this later duplicate block so only the
original definitions remain (keep the earlier definitions already declared
around gradient-rotate and .gradient-border-animated and delete the repeated
declarations in this later section), and verify no other styles rely on a
different variant name so references to gradient-rotate and
.gradient-border-animated remain unchanged.
|
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed 4cb7b7e in 56 seconds. Click for details.
- Reviewed
20lines of code in1files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. package.json:92
- Draft comment:
Removed 'canvas-confetti' dependency. The release notes mentioned adding it; please confirm its removal is intentional and not needed in the code (e.g., for confetti animations). - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to confirm the intention behind removing a dependency. This is not allowed according to the rules, as it falls under asking the author to confirm their intention.
2. package.json:139
- Draft comment:
Removed '@types/canvas-confetti'. Ensure that this removal is aligned with the dependency removal and that no code references require these types. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the author to ensure that the removal of@types/canvas-confettiis aligned with the dependency removal and that no code references require these types. This is a request for confirmation and verification, which violates the rules.
Workflow ID: wflow_rd08gUlOuVEfr18E
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/lib/ai/workers/quiz-worker.ts`:
- Around line 199-201: The catch block that handles JSON parsing in
quiz-worker.ts currently logs the full AI response via result.text (see the
parseError catch and logger.error calls); remove or stop logging result.text
directly to avoid PII leakage and instead log only safe metadata and a
controlled/truncated sample behind an environment guard. Update the parseError
handler to log parseError and contextual metadata (e.g., requestId, modelName)
and, if process.env.NODE_ENV !== "production", include a short
sanitized/truncated snippet of result.text (e.g., first 100 chars) or a
redaction marker; reference the parseError catch block, the logger.error calls,
and result.text when making the change.
♻️ Duplicate comments (1)
src/lib/ai/workers/quiz-worker.ts (1)
205-215: Validate quiz payload before mapping.
parsed.questions.map(...)will throw ifquestionsis missing, and invalidoptions/correctIndexcan produce broken quizzes. Add array and bounds validation and fail fast with a clear error.🔧 Suggested change
- const questions: QuizQuestion[] = parsed.questions.map((q) => ({ - id: generateItemId(), // Always use unique ID - type: q.type as QuestionType, - questionText: q.questionText || q.question_text || q.text || "", - options: q.options || [], - correctIndex: q.correctIndex ?? q.correct_index ?? 0, - hint: q.hint, - explanation: q.explanation || "No explanation provided.", - })); + if (!Array.isArray(parsed.questions) || parsed.questions.length === 0) { + throw new Error("Quiz generation returned no questions"); + } + const questions: QuizQuestion[] = parsed.questions.map((q) => { + const options = Array.isArray(q.options) ? q.options : []; + const correctIndex = q.correctIndex ?? q.correct_index ?? 0; + if (options.length === 0 || correctIndex < 0 || correctIndex >= options.length) { + throw new Error("Quiz generation returned invalid options/correctIndex"); + } + return { + id: generateItemId(), // Always use unique ID + type: q.type as QuestionType, + questionText: q.questionText || q.question_text || q.text || "", + options, + correctIndex, + hint: q.hint, + explanation: q.explanation || "No explanation provided.", + }; + });
| } catch (parseError) { | ||
| logger.error("🎯 [QUIZ-WORKER] Failed to parse JSON:", parseError); | ||
| logger.error("🎯 [QUIZ-WORKER] Raw response:", result.text); |
There was a problem hiding this comment.
Avoid logging raw AI response content in errors.
result.text can include user workspace content; logging it at error level risks PII leakage. Log only metadata or a truncated sample behind a non‑prod guard.
🔧 Suggested change
- logger.error("🎯 [QUIZ-WORKER] Raw response:", result.text);
+ logger.error("🎯 [QUIZ-WORKER] Raw response length:", result.text.length);
+ if (process.env.NODE_ENV !== "production") {
+ logger.debug("🎯 [QUIZ-WORKER] Raw response (truncated):", result.text.slice(0, 1000));
+ }🤖 Prompt for AI Agents
In `@src/lib/ai/workers/quiz-worker.ts` around lines 199 - 201, The catch block
that handles JSON parsing in quiz-worker.ts currently logs the full AI response
via result.text (see the parseError catch and logger.error calls); remove or
stop logging result.text directly to avoid PII leakage and instead log only safe
metadata and a controlled/truncated sample behind an environment guard. Update
the parseError handler to log parseError and contextual metadata (e.g.,
requestId, modelName) and, if process.env.NODE_ENV !== "production", include a
short sanitized/truncated snippet of result.text (e.g., first 100 chars) or a
redaction marker; reference the parseError catch block, the logger.error calls,
and result.text when making the change.




Quizzes and deep research along with other minor fixes
Important
This PR adds full support for quizzes, including creation, updating, and playing, with new tools, workers, UI components, and style enhancements.
createQuizToolandupdateQuizToolinquiz-tools.tsfor creating and updating quizzes.quizWorkerinquiz-worker.tsfor generating quiz questions based on context or topic.workspace-worker.tsto handle quiz creation and updates.CreateQuizToolUIandUpdateQuizToolUIinassistant-uifor quiz interactions.QuizContentcomponent inworkspace-canvasfor rendering quizzes.QuizData,QuizQuestion, andQuizSessionDatatypes intypes.ts.workers.tsinto separate worker files for better organization.grid-layout-helpers.tsto includequizin default card dimensions.globals.css.This description was created by
for 4cb7b7e. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.