Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
f696e20
Merge pull request #126 from Ontos-AI/main
suguanYang Jul 2, 2026
9c1def1
feat: add page citation asset support
suguanYang Jul 3, 2026
a44e522
Consume server page citation assets
suguanYang Jul 3, 2026
ce83573
Mirror page citation assets to Blob
suguanYang Jul 3, 2026
109bf36
Read page citation assets from metadata
suguanYang Jul 3, 2026
3377032
Sync page citation assets to Blob
suguanYang Jul 3, 2026
907083e
Read parsed chunks from Blob snapshot
suguanYang Jul 3, 2026
6b30c48
Sync remote parsed snapshots into Notebook Blob
suguanYang Jul 3, 2026
95a8796
Use server-safe parsed snapshot loads
suguanYang Jul 4, 2026
0304aee
Sync legacy parsed sources before chunk reads
suguanYang Jul 4, 2026
1269fb2
Move parsed chunk reads and sync into the SDK storage model
suguanYang Jul 4, 2026
012d729
Add parsed sync capacity guard
suguanYang Jul 5, 2026
1d0d6a9
Update Knowhere SDK to 2.1.1
suguanYang Jul 5, 2026
c9c6f28
Merge pull request #127 from Ontos-AI/feature/wangbinqi/notebook-pars…
suguanYang Jul 5, 2026
f23ef69
Align remote source processed row state
suguanYang Jul 5, 2026
b17f8b9
Merge pull request #128 from Ontos-AI/fix/wangbinqi/remote-source-pro…
suguanYang Jul 5, 2026
b71073d
fix: harden chat assets on demand
suguanYang Jul 5, 2026
81b3e19
Merge pull request #129 from Ontos-AI/fix/wangbinqi/chat-asset-harden…
suguanYang Jul 5, 2026
6fa2d04
Fix source selection, archive idempotency, and tool metadata
suguanYang Jul 5, 2026
a880548
Merge pull request #132 from Ontos-AI/fix/wangbinqi/chat-asset-harden…
suguanYang Jul 5, 2026
8c1a443
Fix chat retrieval payload guard
suguanYang Jul 5, 2026
e45cb54
Merge pull request #133 from Ontos-AI/fix/wangbinqi/chat-retrieval-pa…
suguanYang Jul 5, 2026
a8b66e6
Fix chat harness finalization budget
suguanYang Jul 5, 2026
98a3278
Merge pull request #134 from Ontos-AI/fix/wangbinqi/chat-finalize-ste…
suguanYang Jul 5, 2026
f836600
Add agentic Gemini image inspection
suguanYang Jul 6, 2026
a34352d
Merge pull request #135 from Ontos-AI/fix/wangbinqi/agentic-gemini-im…
suguanYang Jul 6, 2026
88d6b47
Keep parsed storage sync non-blocking
suguanYang Jul 6, 2026
1cfeece
Merge pull request #136 from Ontos-AI/fix/wangbinqi/non-blocking-pars…
suguanYang Jul 6, 2026
59737a0
Fix hidden library source auto-selection
suguanYang Jul 6, 2026
5aeb660
Merge pull request #137 from Ontos-AI/fix/wangbinqi/visible-source-se…
suguanYang Jul 6, 2026
660204f
Present page-mode sources as page assets
suguanYang Jul 7, 2026
d955a81
Tolerate missing remote display reads
suguanYang Jul 7, 2026
b5e0c2d
Lazy detect page asset documents
suguanYang Jul 7, 2026
f6198d9
Make page asset viewing non-blocking
suguanYang Jul 7, 2026
2d82594
Adapt parsed document storage layout
suguanYang Jul 7, 2026
fde8027
Align Notebook with SDK result layout storage
suguanYang Jul 7, 2026
7c2bba4
Keep home page route exports valid
suguanYang Jul 7, 2026
203f72c
Install published Knowhere SDK 2.1.2
suguanYang Jul 7, 2026
3fe8206
fix(sources): render page assets from chunks
suguanYang Jul 7, 2026
c83a0f3
Fix remote document refresh and page dedupe
suguanYang Jul 7, 2026
15db165
Fix inline parsed image viewing
suguanYang Jul 7, 2026
6d01583
Refactor chat to Knowhere tool runtime
suguanYang Jul 7, 2026
b59db5a
fix(chat): validate citation source refs
suguanYang Jul 7, 2026
e4bc2b6
Trust agent chat output
suguanYang Jul 7, 2026
0cefda8
Merge pull request #138 from Ontos-AI/fix/wangbinqi/sdk-result-layout…
suguanYang Jul 7, 2026
df83e1b
Attach notebook client metadata on Knowhere job creates.
suguanYang Jul 13, 2026
19bd88b
Merge pull request #139 from Ontos-AI/feat/wangbinqi/oss-telemetry-cl…
suguanYang Jul 13, 2026
e90d0af
feat(chat): add agentic retrieval toggle to chat composer
suguanYang Aug 9, 2026
edd8a79
feat(chat): refine deep search toggle UI
suguanYang Aug 10, 2026
6c5a253
Merge pull request #141 from Ontos-AI/feat/wangbinqi/chat-use-agentic…
suguanYang Aug 10, 2026
112dc29
feat: add parsed-results citation UX with page chips
suguanYang Aug 19, 2026
f06f8d9
fix: narrow knowledge before hydrating citation pages
suguanYang Aug 20, 2026
32df690
Merge pull request #143 from Ontos-AI/feat/wangbinqi/parsed-results-c…
suguanYang Aug 20, 2026
af497f6
chore: bump knowhere-sdk to 2.2.0 for grep page numbers
suguanYang Aug 20, 2026
3232b51
Merge pull request #144 from Ontos-AI/feat/wangbinqi/bump-knowhere-sd…
suguanYang Aug 20, 2026
6671a0a
feat: archive remote Knowhere sources and filter by client origin
suguanYang Aug 20, 2026
f4569ea
fix: keep overlapping page-memory sections in parsed results
suguanYang Aug 20, 2026
f2f8bd2
Merge pull request #146 from Ontos-AI/feat/wangbinqi/remote-archive-o…
suguanYang Aug 20, 2026
11d6f71
feat: render demo seed answers with citation chips
suguanYang Aug 20, 2026
2692fbc
feat: map demo seed citations through the live chat citation path
suguanYang Aug 20, 2026
0ef6314
test: expect guest demo seed answers to include cite markers
suguanYang Aug 20, 2026
8120a22
Merge pull request #145 from Ontos-AI/feat/wangbinqi/demo-chat-citati…
suguanYang Aug 20, 2026
16ee713
fix: keep Official Library demo sources selected on citation click
suguanYang Aug 20, 2026
3f61aa8
Merge pull request #147 from Ontos-AI/fix/wangbinqi/demo-citation-lib…
suguanYang Aug 20, 2026
af70055
feat: overlay answer provenance highlights on displayed page images
EricNGOntos Aug 21, 2026
c33739d
fix: resolve page-highlight typecheck failures for CI
EricNGOntos Aug 21, 2026
680d772
Merge pull request #148 from Ontos-AI/feat/wuchengke/page-answer-high…
EricNGOntos Aug 21, 2026
f29dcbd
fix: require inspected citation regions
suguanYang Aug 21, 2026
cf9aac6
fix: harden inspected citation provenance
suguanYang Aug 21, 2026
95fb6e6
Merge pull request #149 from Ontos-AI/fix/wangbinqi/citation-vlm-regions
suguanYang Aug 21, 2026
20db3ec
fix: recognize prefixed auth session cookies
suguanYang Aug 24, 2026
245c1af
Merge pull request #150 from Ontos-AI/fix/wangbinqi/environment-sessi…
suguanYang Aug 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ DASHBOARD_ORIGIN=http://dashboard.local.knowhereto.ai:3000
# local: http://notebook.local.knowhereto.ai:3001
NOTEBOOK_PUBLIC_URL=http://notebook.local.knowhereto.ai:3001

# Optional override of the session cookie names Dashboard sets. Defaults
# to Better Auth's standard cookie names.
# Optional additional session cookie names Dashboard sets.
# Without an override, Notebook recognizes Better Auth session-token cookies
# with standard or environment-prefixed names.
# SESSION_COOKIE_NAMES=better-auth.session_token,__Secure-better-auth.session_token

# --- Product analytics (client-side) ---
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
# misc
.DS_Store
*.pem
.repos/effect

# debug
npm-debug.log*
Expand Down
72 changes: 72 additions & 0 deletions docs/parsed-results-citation-ux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Parsed Results + citation UX

Recorded 2026-08-18 so we do not relitigate the Figma / issue discussion.

Sources:

- Figma [Knowhere (Copy) / brain](https://www.figma.com/design/0jjj7SQ1N0zo4D9WzJoNJh/Knowhere--Copy-?node-id=4000-37742) (`4000:37742`)
- GitHub [knowhere#222](https://github.com/Ontos-AI/knowhere/issues/222), [knowhere#223](https://github.com/Ontos-AI/knowhere/issues/223)
- Product lock from that conversation (issues and Figma notes are partly stale)

This work lands in **Knowhere Notebook**. Region geometry later lands in **Knowhere retrieval** (`Ontos-AI/knowhere`) and is only consumed here when the payload exists.

## Locked product

Vision / page-image mode only. There is **no original PDF preview** as a citation destination.

| Topic | Decision |
| --- | --- |
| Layout | Sources \| Parsed Results \| Assistant (today’s Notebook columns). Ignore the Figma frame that put Assistant in the middle. |
| Rename | Knowhere Notebook → **Knowhere Brain** |
| Canvas | Title **Parsed Results**, subtitle **From {source title}** |
| Page card | **Page N + parse path**, page image, keywords. No keywords → hide the keyword row, still show the image. Screen 2 “text” is a crop overlay on the page image, not a text chunk. |
| List / Tree | Keep **both**. Tree is the **existing** section tree, also in page-image mode. **Default Tree**. Citation click may switch to List so the page card is visible. |
| Inline chips | One chip **per citation**, not per page. Label `{source title}/pN` (same name as the Sources row). Max width 250px, truncate. Same page can be two chips; later they get different crop boxes. |
| Chip / `pN` click | Switch the **viewed** source if needed (not query checkboxes), open that file’s parsed page, scroll to it. Chat may cite any workspace file while the canvas shows another. |
| Footer SOURCES | Numbered list, one row per file, `{title}` + cited page links `p25 p26 p27`. Those links do the **same jump** as chips. |
| Copy / download | Copy answer / code / tables. Download **this assistant turn** as **Markdown and PDF**, **without citations** (no chips, no SOURCES list). |
| Region box | **Required product**, **not this slice**. When retrieval sends a crop, draw `#8E51FF` / 25% / 8px radius on that page image (flash twice, 3s, fade). Until then, page jump only. Do not fake a full-page box. |

Out of this slice: original-file viewer for citations, region overlay, faking geometry.

## Current code (gaps)

Almost all of this is UI in this repo. Page images, keywords, page numbers, and source-title chips already exist in pieces.

| Area | Today | Need |
| --- | --- | --- |
| Branding | “Knowhere Notebook” in `top-nav.tsx`, `lib/app-metadata.ts`, login, `global-error.tsx` | Brain |
| Canvas copy | “Parsed Chunks” / “Showing all parsed chunks from …” | Parsed Results / From {title} |
| Original preview | Hidden for `page-assets` sources (`chunks-panel.tsx`) | Keep hidden. Citations must not reopen it. |
| List / Tree | Tree **hidden** for page-asset sources (`!isPageAssetSource`). Default mode is already `"tree"` but unused in page mode. | Show the toggle for page mode; Tree uses existing `ChunkSectionTree`. |
| Page cards | `PageChunkCard` already shows page image + `ChunkKeywords` | Match Figma title (`Page N` + path). Image-first. Hide keywords when empty (already returns null). |
| Inline chips | `[Source N: …]` tokens are **stripped** (`buildCitationContentMarkdown`). Chips live in a footer `AssistantSources`. | Replace tokens with inline `{title}/pN` chips in the answer. |
| Chip label | Filename / source title only, **no `/pN`**. | `{title}/pN` |
| Dedupe | `getDisplayCitations` and `selectCitationRawResults` drop same-key citations. | Keep one chip per citation so two regions on one page stay two chips. |
| Footer SOURCES | Flat chips | Numbered per-file list + page links |
| Click target | `handleCitationClick` focuses a **chunk**. `focusedPage` is plumbed to `ChunksPanel` but **not used**. | Focus/scroll the **page** card; `onSelectSource` for file B while viewing A already exists. |
| Export | None | Per-turn copy + MD/PDF without citations |

Later API (do not block Notebook UI):

- Retrieval / agent citation payload has page number and page image today (`pageCitationPageNumber`, `pageCitationAssetUrl`).
- It does **not** have a citation crop box. Worker bboxes are for asset crops, not “this quote lives here.”
- When Knowhere adds a region on the citation, extend `ChatCitationView` + persistence, then overlay on `PageCitationAssetImage`.

## Implementation slices (Notebook)

Do these in order. Tests follow existing ownership: model tests for labels/grouping, component tests for chips/cards/export, panel tests for click → source + page.

1. **Chrome** — rename Brain; Parsed Results header/subtitle; enable List/Tree on page-asset sources; default Tree.
2. **Page cards** — Figma card header (page + path); image + optional keywords; citation click forces List (already does via `citationListViewRequestId`) and scrolls to the page chunk.
3. **Citations** — stop stripping without replacement; inline chips `{title}/pN`; stop collapsing same-page citations; numbered SOURCES with `pN` links; click switches viewed source and page-focuses.
4. **Copy / download** — message actions: clipboard of visible answer (code/tables included as rendered); MD + PDF of this turn with the same citation-stripped body we already produce for display (`buildCitationContentMarkdown` / equivalent). PDF is client-side from that Markdown, not the original document.
5. **Later** — region overlay when retrieval sends a box. Keep citation identity stable (do not key chips by `title+page` only).

## Do not

- Route citation clicks to original PDF preview.
- Deduplicate inline chips by page.
- Draw a highlight without retrieval geometry.
- Change which sources are **checked for the next query** when jumping the canvas.
- Put this feature in archived `knowhere-api`; new retrieval fields go in `Ontos-AI/knowhere`.
2 changes: 2 additions & 0 deletions drizzle/0010_minor_piledriver.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE "source_parse_results" ADD COLUMN "snapshot_manifest_url" text;--> statement-breakpoint
ALTER TABLE "source_parse_results" ADD COLUMN "snapshot_manifest_key" text;
5 changes: 5 additions & 0 deletions drizzle/0011_rare_deadpool.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TABLE "source_parse_results" ALTER COLUMN "result_blob_url" DROP NOT NULL;--> statement-breakpoint
ALTER TABLE "source_parse_results" ADD COLUMN "revision_key" text;--> statement-breakpoint
ALTER TABLE "source_parse_results" ADD COLUMN "sync_status" text;--> statement-breakpoint
ALTER TABLE "source_parse_results" ADD COLUMN "sync_error" text;--> statement-breakpoint
ALTER TABLE "sources" ADD COLUMN "failure_stage" text;
21 changes: 21 additions & 0 deletions drizzle/0012_lazy_wendell_rand.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE TABLE "parsed_document_sync_leases" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"workspace_id" uuid NOT NULL,
"source_id" uuid NOT NULL,
"document_id" text NOT NULL,
"revision_key" text,
"lease_token" text NOT NULL,
"acquired_at" timestamp with time zone DEFAULT now() NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"released_at" timestamp with time zone,
"release_reason" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "parsed_document_sync_leases" ADD CONSTRAINT "parsed_document_sync_leases_workspace_id_workspaces_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "parsed_document_sync_leases" ADD CONSTRAINT "parsed_document_sync_leases_source_id_sources_id_fk" FOREIGN KEY ("source_id") REFERENCES "public"."sources"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE UNIQUE INDEX "parsed_document_sync_leases_token_idx" ON "parsed_document_sync_leases" USING btree ("lease_token");--> statement-breakpoint
CREATE INDEX "parsed_document_sync_leases_active_idx" ON "parsed_document_sync_leases" USING btree ("expires_at") WHERE released_at IS NULL;--> statement-breakpoint
CREATE INDEX "parsed_document_sync_leases_workspace_active_idx" ON "parsed_document_sync_leases" USING btree ("workspace_id") WHERE released_at IS NULL;--> statement-breakpoint
CREATE INDEX "parsed_document_sync_leases_document_active_idx" ON "parsed_document_sync_leases" USING btree ("document_id") WHERE released_at IS NULL;
Loading
Loading