Skip to content

Fix/quizzes#208

Merged
urjitc merged 16 commits intomainfrom
fix/quizzes
Mar 2, 2026
Merged

Fix/quizzes#208
urjitc merged 16 commits intomainfrom
fix/quizzes

Conversation

@urjitc
Copy link
Copy Markdown
Member

@urjitc urjitc commented Mar 1, 2026

Important

This pull request introduces a unified editItem tool for editing notes, flashcards, and quizzes, replacing individual update tools and enhancing workspace item management.

  • Behavior:
    • Introduces editItem tool for unified editing of note, flashcard, and quiz items, replacing individual update tools.
    • Removes quizTopic from DistillationResult in route.ts.
    • Updates NOTE_FLASHCARD_QUIZ_SYSTEM to include quiz generation.
  • Tools:
    • Adds edit-item-tool.ts for handling edits across item types.
    • Removes updateNote, updateFlashcards, updateQuiz, and selectCards tools.
    • Updates createChatTools to use editItem.
  • Workers:
    • Updates workspace-worker.ts to support edit action for notes, flashcards, and quizzes.
  • Schemas:
    • Adds EditItemResultSchema to tool-result-schemas.ts.
  • Components:
    • Renames UpdateNoteToolUI.tsx to EditItemToolUI.tsx and updates its logic.
    • Removes SelectCardsToolUI.tsx, UpdateFlashcardToolUI.tsx, and UpdateQuizToolUI.tsx.

This description was created by Ellipsis for c4a7360. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • New Features

    • Unified "Edit Item" tool to edit notes, flashcards, and quizzes (targeted edits and renames).
    • Quiz creation accepts explicit question lists and returns quizzes with question counts.
  • Improvements

    • Notes, flashcards, and quizzes can be generated together in one streamlined flow.
    • Simplified UI: legacy standalone update/select screens removed in favor of the unified edit experience.
    • Assistant response continuation improved to better respect sentence endings and shorter buffers.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thinkex Canceled Canceled Mar 2, 2026 6:37am

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 1, 2026

Warning

Rate limit exceeded

@urjitc has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between db28530 and e22fc49.

📒 Files selected for processing (1)
  • src/components/assistant-ui/thread.tsx
📝 Walkthrough

Walkthrough

Consolidates generation flows and tools: merges note/flashcard/quiz generation into a combined autogen path, removes topic-based quiz worker, introduces explicit-question quiz creation, adds an editItem tool and workspace "edit" action, and removes several UI update components.

Changes

Cohort / File(s) Summary
Autogen route & combined generation
src/app/api/workspaces/autogen/route.ts
Merged note/flashcard/quiz generation into a single path using NOTE_FLASHCARD_QUIZ_SCHEMA/system; removed quizTopic; added streaming/progress events and included quiz data in outputs.
Workspace item creation & layouts
src/app/api/workspaces/autogen/..., src/lib/workspace-state/*
Item creation/bulkCreate shapes updated to include quizTitle, QuizQuestion[] (with generated ids), and layout metadata; mapping adjusted to new combined generation result.
New unified edit tool & exports
src/lib/ai/tools/edit-item-tool.ts, src/lib/ai/tools/index.ts, src/lib/ai/tools/workspace-tools.ts
Added createEditItemTool and exported editItem; removed updateNote/selectCards/updateFlashcards/updateQuiz exports; extended WorkspaceToolContext with activeFolderId and threadId.
Workspace worker edit support
src/lib/ai/workers/workspace-worker.ts
Added "edit" action supporting targeted edits and renames across notes, flashcards, quizzes; supports newName, diff/filediff, JSON validation, block serialization, and version/conflict handling.
Quiz tooling & worker removal
src/lib/ai/tools/quiz-tools.ts, src/lib/ai/workers/index.ts, src/lib/ai/workers/quiz-worker.ts
Removed quiz-worker and its exports; createQuizTool now accepts explicit questions, maps them to internal QuizQuestion (ids via generateItemId), and creates quizzes directly via workspaceWorker.
Flashcard update removal
src/lib/ai/tools/flashcard-tools.ts
Removed createUpdateFlashcardsTool; edit capabilities consolidated into edit-item-tool.
Schemas & types
src/lib/ai/tool-result-schemas.ts, src/lib/workspace-state/types.ts
Added EditItemResultSchema/EditItemResult; removed quiz metadata fields (difficulty, sourceCardIds, sourceCardNames); adjusted QuizResultSchema (removed difficulty/isContextBased).
Formatting & context output
src/lib/utils/format-workspace-context.ts, src/lib/ai/tools/read-workspace.ts
Switched flashcard/quiz context formatting to concise JSON payloads; updated guidance text to reference editItem/createFlashcards and OCR/image placeholder improvements.
UI removals & refactors
src/components/assistant-ui/SelectCardsToolUI.tsx, src/components/assistant-ui/UpdateFlashcardToolUI.tsx, src/components/assistant-ui/UpdateQuizToolUI.tsx, src/components/assistant-ui/EditItemToolUI.tsx, src/components/assistant-ui/CreateQuizToolUI.tsx, src/components/assistant-ui/thread.tsx
Deleted SelectCards/UpdateFlashcard/UpdateQuiz UIs; introduced/renamed EditItemToolUI, adjusted CreateQuizToolUI input to CreateQuizInput, and updated thread.tsx to use EditItemToolUI (removed floating retrigger zone and changed continue heuristics).
Worker exports & cleanup
src/lib/ai/workers/index.ts
Removed re-export of quiz-worker.
Client minor cleanup
src/app/api/cards/from-message/route.ts
Removed unused userId session extraction.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as Autogen Route
  participant AI as AI Service
  participant Worker as WorkspaceWorker
  participant DB as Storage/Events

  Client->>API: Request generate note+flashcards+quiz
  API->>AI: Prompt (NOTE_FLASHCARD_QUIZ_SYSTEM) and stream progress
  AI-->>API: Streamed JSON (note, flashcards, quiz)
  API->>Worker: create / bulkCreate items (include quiz questions with generated ids)
  Worker->>DB: append events / persist items
  DB-->>Worker: ack
  Worker-->>API: creation result
  API-->>Client: final result with items and quiz data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 I stitched the tools into one neat hop,

editItem nibbling where old fragments stop.
Quizzes arrive with questions, tidy and bright,
IDs in their pockets, ready for flight.
— a rabbit claps, carrots shining in moonlight

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix/quizzes' is too vague and generic; it does not clearly communicate the main changes in the pull request, which involve consolidating multiple update tools into a unified editItem tool and restructuring quiz generation. Use a more descriptive title such as 'Consolidate update tools into unified editItem tool' or 'Refactor: Replace individual update tools with unified editItem tool'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 84.21% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/quizzes

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 and usage tips.

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link
Copy Markdown
Contributor

@ellipsis-dev ellipsis-dev Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to c4a7360 in 18 seconds. Click for details.
  • Reviewed 3019 lines of code in 19 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft 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.

Workflow ID: wflow_dm71UpYy3GqXE8QX

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Comment thread src/lib/ai/tools/edit-item-tool.ts Fixed
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 19 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/app/api/workspaces/autogen/route.ts">

<violation number="1" location="src/app/api/workspaces/autogen/route.ts:507">
P2: Quiz questions are accepted without validating option count or correctIndex bounds, so LLM output with missing options can render quizzes with no selectable answers or invalid correct indices. Add schema validation to enforce 4 options for multiple-choice and 2 for true/false (and clamp correctIndex) before building the quiz data.</violation>
</file>

<file name="src/lib/ai/workers/workspace-worker.ts">

<violation number="1" location="src/lib/ai/workers/workspace-worker.ts:879">
P1: Runtime crash: `questionsToAdd.length` in the logger will throw `TypeError: Cannot read properties of undefined` when `updateQuiz` is called with only a title change (no questions). The return value on line 879 was correctly fixed with optional chaining, but this logger statement was missed.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/lib/ai/workers/workspace-worker.ts
Comment thread src/app/api/workspaces/autogen/route.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/assistant-ui/CreateQuizToolUI.tsx (1)

37-50: ⚠️ Potential issue | 🟡 Minor

Avoid stale item lookup causing false “Item no longer exists”.

Line 37 now relies on workspaceState.items to resolve currentItem. Right after completion, that list can lag briefly, so Move can fail even for a valid new quiz. Add a fallback item source (or gate Move visibility until item resolution succeeds).

🩹 Suggested fix
 const currentItem = useMemo(() => {
   const targetId = result.itemId || result.quizId;
-  if (!targetId || !workspaceState?.items) return undefined;
-  return workspaceState.items.find((item: any) => item.id === targetId);
-}, [result.itemId, result.quizId, workspaceState?.items]);
+  const items = workspaceState?.items ?? allItems;
+  if (!targetId || !items?.length) return undefined;
+  return items.find((item: any) => item.id === targetId);
+}, [result.itemId, result.quizId, workspaceState?.items, allItems]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/assistant-ui/CreateQuizToolUI.tsx` around lines 37 - 50,
CreateQuizReceipt's currentItem lookup using workspaceState.items can be stale
immediately after creation causing false "Item no longer exists" errors; update
the lookup to fallback to other sources (for example use
result.itemId/result.quizId to find the item in the passed-in allItems prop or
in result.payload) before declaring the item missing, and/or prevent showing the
Move dialog (showMoveDialog) until a resolved currentItem exists; specifically
modify the useMemo that computes currentItem to first try workspaceState.items,
then fall back to allItems.find(...) or result-contained data, and ensure
moveItemToFolder and the UI that toggles setShowMoveDialog only enable when
currentItem is non-undefined.
🧹 Nitpick comments (3)
src/components/assistant-ui/CreateQuizToolUI.tsx (1)

25-25: Keep createQuiz args strongly typed.

Line 25 switches to Record<string, unknown>, which drops compile-time checks between the tool contract and this UI. Prefer reusing the canonical createQuiz input type exported from your shared tool/schema module so arg-shape drift fails at compile time.

♻️ Suggested direction
-type CreateQuizArgs = Record<string, unknown>;
+// Reuse the shared createQuiz input type from your tool/schema source of truth
+type CreateQuizArgs = CreateQuizInput;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/assistant-ui/CreateQuizToolUI.tsx` at line 25, Replace the
ad-hoc CreateQuizArgs = Record<string, unknown> with the canonical input type
used by the createQuiz tool: import the exported createQuiz input/interface type
from the shared tool/schema module and use that type for CreateQuizArgs (or
replace usages directly with the imported type) so the CreateQuizToolUI's
createQuiz argument shape is strongly typed and keeps contract drift caught at
compile time.
src/components/assistant-ui/EditItemToolUI.tsx (1)

49-52: Minor: Type annotation could use the actual Item type.

The type annotation { id: string } works but loses type information. Since workspaceState.items is typed as Item[], you could rely on TypeScript inference:

-    return workspaceState.items.find((item: { id: string }) => item.id === result.itemId);
+    return workspaceState.items.find((item) => item.id === result.itemId);

This preserves the full Item type for card, allowing proper type checking when accessing card?.name.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/assistant-ui/EditItemToolUI.tsx` around lines 49 - 52, The
inline type annotation in the useMemo callback for `card` currently uses `{ id:
string }`, which loses the full `Item` type; update the predicate to use the
actual `Item` type (e.g., use `item: Item` or rely on inference from
`workspaceState.items.find`) so `card` is inferred as `Item | undefined` and
downstream accesses like `card?.name` are properly typed; modify the `useMemo`
callback in `EditItemToolUI` accordingly (referencing `card`, `result.itemId`,
and `workspaceState.items`) to restore full `Item` type information.
src/lib/ai/workers/workspace-worker.ts (1)

1019-1026: Redundant duplicate name check.

The duplicate name check at lines 1023-1026 appears redundant since the rename case is already validated at lines 996-1001. The second check uses itemName which equals changes.name ?? existingItem.name, but if changes.name is set, it was already validated. If changes.name is not set, itemName equals existingItem.name, which shouldn't conflict with itself (same params.itemId).

This is harmless defensive coding, but consider removing it to simplify the logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/ai/workers/workspace-worker.ts` around lines 1019 - 1026, The
duplicate-name validation block is redundant because rename validation already
runs earlier; remove the second check that computes itemName = (changes.name ??
existingItem.name) and the subsequent call to
hasDuplicateName(currentState.items, itemName, existingItem.type,
existingItem.folderId ?? null, params.itemId). Instead, rely on the earlier
rename validation (the code that checks changes.name against hasDuplicateName)
and keep the early return for no-op updates; ensure no other logic depends on
itemName or that second branch before deletion so behavior remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/ai/tools/edit-item-tool.ts`:
- Around line 141-145: The function returns matchedItem.name in the success
branch which yields the pre-edit name; instead, when workerResult.success is
true, return the final name by preferring newName (if set) over
matchedItem.name—i.e. update the returned object built from workerResult to set
itemName: newName ?? matchedItem.name so tool receipts reflect the renamed item;
reference variables: workerResult, matchedItem.name, newName.
- Around line 101-113: The current logic uses resolveItem(state.items, itemName)
and proceeds without guarding against multiple editable items that share the
same name; update the flow to detect duplicate-name collisions before applying
edits: after resolving matchedItem (or instead of a single fuzzy match) collect
all candidates from state.items where name === itemName (and type !== "folder"),
and if more than one candidate exists return success: false with a message that
lists distinguishing info (e.g., id, type, path/parent, or index) and instructs
the user to disambiguate (or call a disambiguation helper). Ensure this check
references resolveItem, state.items, matchedItem and itemName so the
duplicate-name guard prevents edits hitting the wrong item.

In `@src/lib/ai/tools/quiz-tools.ts`:
- Around line 32-33: Change the Zod schema for the quiz title from
z.string().nullable() to z.string().nullish() so the input can omit the title
key entirely (or provide null) and still pass validation; update the schema
where the property is named title alongside QuizQuestionSchema, ensuring it
matches the TypeScript signature (title?: string | null) and allows the existing
fallback logic that applies a default 'Quiz' when title is missing or null.
- Around line 15-22: QuizQuestionSchema currently allows any options length and
an unbounded correctIndex; update QuizQuestionSchema to validate by
discriminating on type: for "multiple_choice" require options.length === 4
(z.tuple or refine) and for "true_false" require options equal ["True","False"]
(literal array check), and constrain correctIndex to be an integer within
0..options.length-1 (use z.number().int().refine or z.preprocess with a
dependent refinement). Also update the related quiz array schema (the array
definition around the quiz questions) to use the revised QuizQuestionSchema and
adjust the mapping function that processes questions (the mapping function
referenced around lines 55-63) to assume validated shapes (or defensively check
bounds before indexing), and mirror the same schema changes in the duplicate
definition in src/app/api/workspaces/autogen/route.ts so both places enforce
exact option counts and correctIndex bounds.

---

Outside diff comments:
In `@src/components/assistant-ui/CreateQuizToolUI.tsx`:
- Around line 37-50: CreateQuizReceipt's currentItem lookup using
workspaceState.items can be stale immediately after creation causing false "Item
no longer exists" errors; update the lookup to fallback to other sources (for
example use result.itemId/result.quizId to find the item in the passed-in
allItems prop or in result.payload) before declaring the item missing, and/or
prevent showing the Move dialog (showMoveDialog) until a resolved currentItem
exists; specifically modify the useMemo that computes currentItem to first try
workspaceState.items, then fall back to allItems.find(...) or result-contained
data, and ensure moveItemToFolder and the UI that toggles setShowMoveDialog only
enable when currentItem is non-undefined.

---

Nitpick comments:
In `@src/components/assistant-ui/CreateQuizToolUI.tsx`:
- Line 25: Replace the ad-hoc CreateQuizArgs = Record<string, unknown> with the
canonical input type used by the createQuiz tool: import the exported createQuiz
input/interface type from the shared tool/schema module and use that type for
CreateQuizArgs (or replace usages directly with the imported type) so the
CreateQuizToolUI's createQuiz argument shape is strongly typed and keeps
contract drift caught at compile time.

In `@src/components/assistant-ui/EditItemToolUI.tsx`:
- Around line 49-52: The inline type annotation in the useMemo callback for
`card` currently uses `{ id: string }`, which loses the full `Item` type; update
the predicate to use the actual `Item` type (e.g., use `item: Item` or rely on
inference from `workspaceState.items.find`) so `card` is inferred as `Item |
undefined` and downstream accesses like `card?.name` are properly typed; modify
the `useMemo` callback in `EditItemToolUI` accordingly (referencing `card`,
`result.itemId`, and `workspaceState.items`) to restore full `Item` type
information.

In `@src/lib/ai/workers/workspace-worker.ts`:
- Around line 1019-1026: The duplicate-name validation block is redundant
because rename validation already runs earlier; remove the second check that
computes itemName = (changes.name ?? existingItem.name) and the subsequent call
to hasDuplicateName(currentState.items, itemName, existingItem.type,
existingItem.folderId ?? null, params.itemId). Instead, rely on the earlier
rename validation (the code that checks changes.name against hasDuplicateName)
and keep the early return for no-op updates; ensure no other logic depends on
itemName or that second branch before deletion so behavior remains unchanged.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe21a21 and 4be02e9.

📒 Files selected for processing (19)
  • src/app/api/workspaces/autogen/route.ts
  • src/components/assistant-ui/CreateQuizToolUI.tsx
  • src/components/assistant-ui/EditItemToolUI.tsx
  • src/components/assistant-ui/SelectCardsToolUI.tsx
  • src/components/assistant-ui/UpdateFlashcardToolUI.tsx
  • src/components/assistant-ui/UpdateQuizToolUI.tsx
  • src/components/assistant-ui/thread.tsx
  • src/lib/ai/tool-result-schemas.ts
  • src/lib/ai/tools/edit-item-tool.ts
  • src/lib/ai/tools/flashcard-tools.ts
  • src/lib/ai/tools/index.ts
  • src/lib/ai/tools/quiz-tools.ts
  • src/lib/ai/tools/read-workspace.ts
  • src/lib/ai/tools/workspace-tools.ts
  • src/lib/ai/workers/index.ts
  • src/lib/ai/workers/quiz-worker.ts
  • src/lib/ai/workers/workspace-worker.ts
  • src/lib/utils/format-workspace-context.ts
  • src/lib/workspace-state/types.ts
💤 Files with no reviewable changes (6)
  • src/lib/workspace-state/types.ts
  • src/lib/ai/workers/quiz-worker.ts
  • src/lib/ai/workers/index.ts
  • src/components/assistant-ui/UpdateFlashcardToolUI.tsx
  • src/components/assistant-ui/UpdateQuizToolUI.tsx
  • src/components/assistant-ui/SelectCardsToolUI.tsx

Comment thread src/lib/ai/tools/edit-item-tool.ts
Comment thread src/lib/ai/tools/edit-item-tool.ts
Comment thread src/lib/ai/tools/quiz-tools.ts Outdated
Comment thread src/lib/ai/tools/quiz-tools.ts Outdated
urjitc added 5 commits March 1, 2026 17:35
…lidation; CreateQuiz/EditItem UI fixes; remove redundant duplicate check

Made-with: Cursor
…e lacks sentence-ending punctuation; lower char threshold to 150

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Unused variable userId causes TypeScript compilation error that blocks the Vercel build.

Fix on Vercel

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/api/workspaces/autogen/route.ts (1)

507-525: Consider importing or sharing the quiz question schema.

A local QuizQuestionSchema is defined here that's similar to but less strict than the one in quiz-tools.ts. While the lenient schema makes sense for parsing LLM output (with post-processing at lines 560-581 to fix issues), maintaining two schemas increases drift risk.

Consider extracting a shared base schema or importing QuizQuestionSchema from quiz-tools.ts and using .passthrough() or a lenient variant for LLM output parsing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/api/workspaces/autogen/route.ts` around lines 507 - 525, The local
QuizQuestionSchema duplicates logic from quiz-tools.ts and risks schema drift;
replace the local definition in route.ts by importing the shared
QuizQuestionSchema from quiz-tools.ts (or extract a shared base schema there)
and use a lenient variant for LLM parsing (e.g., imported
QuizQuestionSchema.passthrough() or create a RelaxedQuizQuestionSchema that
extends the shared schema with .passthrough()/optional fields) then update
NOTE_FLASHCARD_QUIZ_SCHEMA to reference that imported/relaxed quiz question
schema instead of the locally defined QuizQuestionSchema so post-processing
lines (560-581) operate on the same canonical schema types.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/app/api/workspaces/autogen/route.ts`:
- Around line 507-525: The local QuizQuestionSchema duplicates logic from
quiz-tools.ts and risks schema drift; replace the local definition in route.ts
by importing the shared QuizQuestionSchema from quiz-tools.ts (or extract a
shared base schema there) and use a lenient variant for LLM parsing (e.g.,
imported QuizQuestionSchema.passthrough() or create a RelaxedQuizQuestionSchema
that extends the shared schema with .passthrough()/optional fields) then update
NOTE_FLASHCARD_QUIZ_SCHEMA to reference that imported/relaxed quiz question
schema instead of the locally defined QuizQuestionSchema so post-processing
lines (560-581) operate on the same canonical schema types.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4be02e9 and d681101.

📒 Files selected for processing (6)
  • src/app/api/workspaces/autogen/route.ts
  • src/components/assistant-ui/CreateQuizToolUI.tsx
  • src/components/assistant-ui/EditItemToolUI.tsx
  • src/lib/ai/tools/edit-item-tool.ts
  • src/lib/ai/tools/quiz-tools.ts
  • src/lib/ai/workers/workspace-worker.ts

…t blocks the Vercel build.

This commit fixes the issue reported at src/app/api/cards/from-message/route.ts:24

**Bug Explanation:** The file `src/app/api/cards/from-message/route.ts` declares a variable `userId` on line 24 (`const userId = session.user.id;`) but never uses it anywhere in the function. TypeScript's strict mode (specifically the `noUnusedLocals` compiler option or equivalent strict checking) treats unused variables as errors, not just warnings.

This caused the Vercel build to fail with the error:

```
Type error: 'userId' is declared but its value is never read.
```

The variable appears to be leftover code from development - likely intended for future use or accidentally left behind after refactoring. The function authenticates the user and validates the session, but doesn't actually need to store the `userId` since none of the subsequent operations (AI content processing, workspace worker calls) require it as a parameter.

**Fix:** Removed the unused variable declaration entirely. The line `const userId = session.user.id;` was deleted since:

1.  The userId value is never used in the function
2.  The session validation already ensures the user is authenticated
3.  Keeping unused variables violates TypeScript's strict checking and blocks builds

After the fix, the code flows directly from session validation to parsing the request body, which is the correct behavior.


Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: urjitc <chakrabortyurjit@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/utils/format-workspace-context.ts (1)

825-825: Consider compact JSON to reduce context-token overhead.

Line 825 and Line 850 pretty-print payloads with indentation. For large flashcard/quiz sets, this inflates prompt size and can crowd out higher-value context. Prefer compact JSON (or a size-capped mode) in workspace context formatting.

♻️ Proposed refactor
-    return [JSON.stringify(payload, null, 2)];
+    return [JSON.stringify(payload)];
-    lines.push(JSON.stringify(payload, null, 2));
+    lines.push(JSON.stringify(payload));

Also applies to: 850-850

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/format-workspace-context.ts` at line 825, Change the
pretty-printed JSON returned from the workspace context formatter to compact
JSON to reduce token usage: replace JSON.stringify(payload, null, 2) with
JSON.stringify(payload) (and do the same for the other occurrence) inside the
function that builds the workspace context (the expression that currently
returns [JSON.stringify(payload, null, 2)]); optionally implement a size-capped
branch that uses JSON.stringify(payload) and truncates or slices the string if
it exceeds a threshold before returning to avoid oversized contexts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/assistant-ui/thread.tsx`:
- Around line 1245-1246: The continue heuristic currently tests the final
character of the raw message against ENDS_WITH_SENTENCE_PUNCTUATION and
therefore misclassifies messages that end with trailing markup like
<citation>...</citation> (which leave a '>' as the last char); before applying
ENDS_WITH_SENTENCE_PUNCTUATION, strip any trailing HTML/XML-like tags/markup and
trailing whitespace from the message (e.g., remove /<[^>]+>$/ or strip balanced
trailing citation tags) so the punctuation check sees the actual last visible
character; update the code paths that use ENDS_WITH_SENTENCE_PUNCTUATION (the
continue/heuristic check) to run against the cleaned string.

---

Nitpick comments:
In `@src/lib/utils/format-workspace-context.ts`:
- Line 825: Change the pretty-printed JSON returned from the workspace context
formatter to compact JSON to reduce token usage: replace JSON.stringify(payload,
null, 2) with JSON.stringify(payload) (and do the same for the other occurrence)
inside the function that builds the workspace context (the expression that
currently returns [JSON.stringify(payload, null, 2)]); optionally implement a
size-capped branch that uses JSON.stringify(payload) and truncates or slices the
string if it exceeds a threshold before returning to avoid oversized contexts.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fba9e8 and db28530.

📒 Files selected for processing (2)
  • src/components/assistant-ui/thread.tsx
  • src/lib/utils/format-workspace-context.ts

Comment thread src/components/assistant-ui/thread.tsx
@urjitc urjitc merged commit 0493af4 into main Mar 2, 2026
4 of 5 checks passed
@urjitc urjitc deleted the fix/quizzes branch March 2, 2026 06:37
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Dev Board Mar 2, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 2, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
7.4% Duplication on New Code (required ≤ 3%)
B Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant