- AddError() now skips broadcast after Finish() to prevent cancelled
goroutines from emitting error events to UI after user stops enrichment
- batchSummarize skips AddError when context is cancelled (expected on stop)
- Rescan always re-enqueues unenriched docs alongside new/updated files,
worker-level dedup prevents double-processing
Backend:
- Add error tracking to EnrichProgress (error_count, last_error)
- Broadcast error events when LLM calls fail
- Add POST /v1/vault/enrichment/stop endpoint
- Wire enrichWorker to VaultHandler for stop functionality
Web UI:
- Add stop button (appears when enriching)
- Show error toast when enrichment errors occur
- Display error count in progress bar
- Add useStopEnrichment hook
i18n: en/vi/zh translations for new strings
9 fixes for vault enrichment pipeline:
1. Queue key = tenant-only (was per-agent, caused multiple batches
blocking EventBus workers and progress bar flashing)
2. Classify chunks 5 candidates per LLM call (prevents response
truncation that caused parse_still_failed errors)
3. Classify prompt improved: explicit "EXACTLY one entry per
candidate", 5-entry example, ctx capped at 30 words
4. max_tokens kept at 1024 (sufficient for 5 candidates)
5. Progress AddDone removes !running guard (safe before Start)
6. Rescan defers event publishing via PendingEvents — Start()
called before workers receive events, eliminating race
7. Upload handler same deferred publish pattern
8. Frontend enrichment timer cancels stale "complete" timeout
when new enrichment starts (prevents bar disappearing)
9. Sidebar tree reloads after rescan completes
Classify now searches across entire tenant (empty agentID) to
build cross-agent links for future vault sharing. Access control
enforced at query time — agents only see their own docs.
After rescan agent_key fix, docs split into per-agent batch queues.
Each batch was calling Start()/Finish() independently, causing the
progress bar to flash 0/1 per agent instead of showing global progress.
Now: handler Start(total) sets global count, worker batches call
TrackBatch()/MarkBatchDone() for lifecycle, AddDone(n) auto-completes
when done >= total. Progress bar shows smooth 0→N across all agents.
Start() is called each drain loop in processBatch to update total.
Only reset done=0 when transitioning from idle→running (new batch),
not when already running (same batch, total growing).
Backend:
- Add cross-agent routes for all vault CRUD (/v1/vault/documents/*, /v1/vault/links/*)
alongside existing per-agent routes for backward compat.
- All handlers skip agent ownership check when agentID is empty.
- Path traversal validation (reject .. and leading /) on create.
- Scope defaults to "shared" when creating without agent.
- Enrichment progress broadcast via WS event (vault.enrich.progress)
using existing MessageBus infrastructure.
- GET /v1/vault/enrichment/status for polling fallback.
Frontend:
- Fix VaultDocument.agent_id type to optional/nullable — prevents
runtime crash on shared/team docs without agent.
- All vault hooks use cross-agent URLs (/v1/vault/...) — no more
skipping docs with null agent_id in graph/links/mutations.
- Remove dead agentId params from useUpdateDocument, useDeleteDocument,
useCreateLink, useDeleteLink, useVaultLinks, LinkBadge.
- Pass team_id from selected team filter to create dialog.
- WS-based enrichment progress bar on vault page (useWsEvent hook).
- Disable rescan button during enrichment, auto-clear after 3s.