diff --git a/apps/desktop/src/DocumentPreview.tsx b/apps/desktop/src/DocumentPreview.tsx
index 672b663..09e8a71 100644
--- a/apps/desktop/src/DocumentPreview.tsx
+++ b/apps/desktop/src/DocumentPreview.tsx
@@ -58,7 +58,7 @@ function DocumentPreview({ isOpen, onClose, documentUrl, filename, highlightText
const page = await pdf.getPage(i);
const textContent = await page.getTextContent();
const pageText = normalizeText(
- textContent.items.map((item: { str?: string }) => item.str || '').join(' ')
+ textContent.items.map((item) => ('str' in item ? item.str : '')).join(' ')
);
if (pageText.includes(searchSnippet)) {
setPageNumber(i);
diff --git a/apps/desktop/src/components/layout/SourcePanel.tsx b/apps/desktop/src/components/layout/SourcePanel.tsx
index 1a49557..0d211b5 100644
--- a/apps/desktop/src/components/layout/SourcePanel.tsx
+++ b/apps/desktop/src/components/layout/SourcePanel.tsx
@@ -27,7 +27,7 @@ export function SourcePanel({ onSourceClick }: SourcePanelProps) {
{activeSources.map((source, i) => {
- const nbId = (source as Record
).notebook_id as string | undefined;
+ const nbId = source.notebook_id;
const nbName = nbId ? notebooks.find((nb) => nb.notebook_id === nbId)?.title : null;
return (
diff --git a/apps/desktop/src/components/ui/SetupWizard.tsx b/apps/desktop/src/components/ui/SetupWizard.tsx
index 8d20cb2..42310fc 100644
--- a/apps/desktop/src/components/ui/SetupWizard.tsx
+++ b/apps/desktop/src/components/ui/SetupWizard.tsx
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
-import { fetchConfig, uploadDocument } from '../../api';
+import { uploadDocument } from '../../api';
import { useAppStore } from '../../store/app-store';
import { useNotebooks } from '../../hooks/useNotebooks';
import { showToast } from './Toast';
@@ -34,7 +34,6 @@ export function SetupWizard({ onComplete }: { onComplete: () => void }) {
const [ollamaStatus, setOllamaStatus] = useState({ state: 'checking' });
const [selectedModel, setSelectedModel] = useState(null);
const [uploading, setUploading] = useState(false);
- const [uploadedFilename, setUploadedFilename] = useState(null);
const fileInputRef = useRef(null);
const { refresh: refreshNotebooks } = useNotebooks();
@@ -95,7 +94,6 @@ export function SetupWizard({ onComplete }: { onComplete: () => void }) {
const result = await uploadDocument(file);
useAppStore.getState().setActiveNotebookId(result.notebook_id);
await refreshNotebooks();
- setUploadedFilename(file.name);
showToast(`${file.name} indexed successfully`, 'success');
// Mark wizard complete and hand off
diff --git a/apps/desktop/src/components/ui/ZoteroImport.tsx b/apps/desktop/src/components/ui/ZoteroImport.tsx
index 211de6d..09b6a13 100644
--- a/apps/desktop/src/components/ui/ZoteroImport.tsx
+++ b/apps/desktop/src/components/ui/ZoteroImport.tsx
@@ -1,5 +1,4 @@
import { useEffect, useState } from 'react';
-import { useAppStore } from '../../store/app-store';
import { useNotebooks } from '../../hooks/useNotebooks';
import { showToast } from './Toast';
import './zotero-import.css';
diff --git a/apps/desktop/src/hooks/useChat.ts b/apps/desktop/src/hooks/useChat.ts
index ed56838..34e5b30 100644
--- a/apps/desktop/src/hooks/useChat.ts
+++ b/apps/desktop/src/hooks/useChat.ts
@@ -47,7 +47,7 @@ export function useChat() {
const sources: SourceChunk[] = (event.sources ?? []).map((src) => ({
...src,
document_name: src.source_path.split(/[/\\]/).pop() ?? src.source_path,
- relevance_score: (src as Record).relevance_score as number | undefined,
+ relevance_score: src.relevance_score,
}));
s.setActiveSources(sources);
// Capture conversation_id from backend (created on first message)
diff --git a/apps/desktop/src/types.ts b/apps/desktop/src/types.ts
index 9c48dc7..d425e3f 100644
--- a/apps/desktop/src/types.ts
+++ b/apps/desktop/src/types.ts
@@ -21,6 +21,8 @@ export interface StreamSource {
source_path: string;
preview: string;
distance?: number | null;
+ relevance_score?: number;
+ notebook_id?: string;
}
export type ChatStreamEvent =
@@ -94,6 +96,7 @@ export interface SourceChunk {
distance?: number | null;
document_name: string;
relevance_score?: number;
+ notebook_id?: string;
}
export interface CreateNotebookRequest {
diff --git a/backend/notebooklm_backend/models/chat.py b/backend/notebooklm_backend/models/chat.py
index 76c2d30..5ac3fcb 100644
--- a/backend/notebooklm_backend/models/chat.py
+++ b/backend/notebooklm_backend/models/chat.py
@@ -14,7 +14,10 @@ class ChatRequest(BaseModel):
prompt: str
history: List[ChatMessage] | None = None
notebook_id: str | None = Field(None, description="Optional notebook ID for RAG-enabled chat")
- notebook_ids: List[str] | None = Field(None, description="Optional list of notebook IDs for cross-notebook synthesis")
+ notebook_ids: List[str] | None = Field(
+ None,
+ description="Optional list of notebook IDs for cross-notebook synthesis",
+ )
conversation_id: str | None = Field(None, description="Optional conversation ID for persistence")
diff --git a/backend/notebooklm_backend/routes/chat.py b/backend/notebooklm_backend/routes/chat.py
index aadddb5..7f20377 100644
--- a/backend/notebooklm_backend/routes/chat.py
+++ b/backend/notebooklm_backend/routes/chat.py
@@ -46,7 +46,6 @@ async def event_generator():
accumulated_reply = ""
sources_data: list[dict] | None = None
conversation_id = payload.conversation_id
- persist_warning = False
try:
# Create conversation on first message if no conversation_id provided
diff --git a/backend/notebooklm_backend/services/conversation_store.py b/backend/notebooklm_backend/services/conversation_store.py
index 7a9df0e..bc8518f 100644
--- a/backend/notebooklm_backend/services/conversation_store.py
+++ b/backend/notebooklm_backend/services/conversation_store.py
@@ -5,8 +5,7 @@
import uuid
from contextlib import contextmanager
from datetime import datetime, timezone
-from dataclasses import dataclass, field
-from pathlib import Path
+from dataclasses import dataclass
from typing import Iterable
from ..config import AppConfig
diff --git a/backend/tests/test_conversation_store.py b/backend/tests/test_conversation_store.py
index aefec72..6627c76 100644
--- a/backend/tests/test_conversation_store.py
+++ b/backend/tests/test_conversation_store.py
@@ -143,9 +143,9 @@ def test_messages_ordered_by_created_at(store):
def test_conversations_ordered_by_updated_at(store):
c1 = store.create_conversation(notebook_id="nb1", title="Older")
- c2 = store.create_conversation(notebook_id="nb1", title="Newer")
+ store.create_conversation(notebook_id="nb1", title="Newer")
- # c2 was created after c1, so it should appear first (DESC order)
+ # The newer conversation was created after c1, so it should appear first (DESC order)
convs = store.list_conversations("nb1")
assert convs[0].title == "Newer"
assert convs[1].title == "Older"
diff --git a/backend/tests/test_cross_notebook.py b/backend/tests/test_cross_notebook.py
index 595b0e8..e5bc5eb 100644
--- a/backend/tests/test_cross_notebook.py
+++ b/backend/tests/test_cross_notebook.py
@@ -2,7 +2,7 @@
import pytest
from notebooklm_backend.config import AppConfig
-from notebooklm_backend.services.vector_store import VectorStoreManager, create_vector_store
+from notebooklm_backend.services.vector_store import create_vector_store
from notebooklm_backend.services.chunking import TextChunk