Studio: show total chunks in the aggregate indexing toast

The completion toast reported only document count. Capture each job's
num_chunks from its complete event into the index-progress store and sum
across the batch, so the toast reads 'N documents and M chunks indexed'.
Already-indexed (deduped) files contribute 0 new chunks.
This commit is contained in:
Roland Tannous 2026-05-28 20:24:15 +04:00
commit cbe4b0866a
4 changed files with 11 additions and 6 deletions

View file

@ -204,7 +204,7 @@ export function useThreadDocUploads(): UseThreadDocUploadsResult {
.getState()
.setRagSource({ kind: "thread" });
}
indexProgress.setReady(localChipId);
indexProgress.setReady(localChipId, event.num_chunks);
releaseSlot();
} else if (event.type === "error") {
setPendingDocs((prev) =>

View file

@ -694,7 +694,7 @@ export function SharedComposer({
.getState()
.setRagSource({ kind: "thread" });
}
indexProgress.setReady(localChipId);
indexProgress.setReady(localChipId, event.num_chunks);
releaseSlot();
} else if (event.type === "error") {
setPendingDocs((prev) =>

View file

@ -27,6 +27,7 @@ export function IngestionToastStack() {
(e) => e.status === "ready" || e.status === "error",
).length;
const errored = items.filter((e) => e.status === "error").length;
const totalChunks = items.reduce((sum, e) => sum + (e.chunks || 0), 0);
const allDone = total > 0 && done === total;
// Overall progress: completed/errored files count as 1, in-flight files
// contribute their fractional progress. Smooth even for a handful of files.
@ -74,7 +75,8 @@ export function IngestionToastStack() {
if (allDone) {
const indexed = total - errored;
subtitle =
`${indexed} document${indexed === 1 ? "" : "s"} indexed` +
`${indexed} document${indexed === 1 ? "" : "s"} and ` +
`${totalChunks} chunk${totalChunks === 1 ? "" : "s"} indexed` +
(errored > 0 ? ` · ${errored} failed` : "");
} else {
subtitle = `${done}/${total} · ${pct}%`;

View file

@ -16,6 +16,8 @@ export interface IndexEntry {
status: IndexEntryStatus;
/** 0..1; only meaningful while `indexing`. */
progress: number;
/** Chunks this file produced (from the job's complete event); 0 until done. */
chunks: number;
}
interface IndexProgressState {
@ -23,7 +25,7 @@ interface IndexProgressState {
add: (id: string, filename: string) => void;
setIndexing: (id: string) => void;
setProgress: (id: string, progress: number) => void;
setReady: (id: string) => void;
setReady: (id: string, chunks?: number) => void;
setError: (id: string) => void;
clear: () => void;
}
@ -46,13 +48,14 @@ export const useIndexProgressStore = create<IndexProgressState>((set) => ({
set((s) => ({
entries: {
...s.entries,
[id]: { filename, status: "queued", progress: 0 },
[id]: { filename, status: "queued", progress: 0, chunks: 0 },
},
})),
setIndexing: (id) => patch(set, id, { status: "indexing" }),
setProgress: (id, progress) =>
patch(set, id, { status: "indexing", progress }),
setReady: (id) => patch(set, id, { status: "ready", progress: 1 }),
setReady: (id, chunks = 0) =>
patch(set, id, { status: "ready", progress: 1, chunks }),
setError: (id) => patch(set, id, { status: "error" }),
clear: () => set({ entries: {} }),
}));