Commit Graph

108 Commits

Author SHA1 Message Date
Woody d444c99c23 feat(config): log resolved llm and embedding model names on startup
Add INFO log in get_settings() to print the actual model names
after merging .env and class defaults. Confirms pydantic-settings
priority: env values override class defaults as expected.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-27 15:11:36 +08:00
Woody a7a22f1494 fix(relevance): tolerate LLM score count mismatches via padding instead of discarding
The per-sub-question filter was all-or-nothing: if the LLM returned
9 scores for 10 chunks (common with qwen3.5-35b), every chunk was
discarded and the user got 'no relevant information found'.

Now: fewer scores → pad with 0.0; more scores → truncate. Changed
from error→warning since this is recoverable.

Also improve LTT page UI: sources collapsed by default in per-sub-q
sections, and the 'Your question' text now shows the full question
instead of being truncated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-27 14:31:18 +08:00
Woody 2656f9ca08 refactor(test): rewrite tests to comply with integration-first rules
Replace mocked DB/internal-services with real ChromaDB/SQLite via tmp_path.
Only mock truly external APIs (LLM, embedding for deterministic vectors).

13 test files rewritten (314 pass, 0 fail):
- Route tests: use TestClient + real ChromaDB, seed test data
- Service tests: use real PersistentClient/SQLite instances
- Pipeline tests: TestClient hits SSE /query endpoint, verify history
- Converted unittest.TestCase to pytest where applicable

Plus: fix metadata.py to filter None values from ChromaDB metadata
(pre-existing bug caught by real-DB ingestion tests)
2026-04-27 11:46:58 +08:00
Woody 3b868a0133 feat(prompts): integrate filter_per_subq with PromptService, fix seed bugs, restructure UI
Break the hardcoded per-sub-q filter prompt into 3 editable PromptService templates (filter_intro, filter_section, filter_outro) with placeholders for the for-loop iteration pattern. Refactor RelevanceFilter._build_per_subq_prompt() to compose them at runtime, falling back to built-in defaults when PromptService is unavailable.

Fix two latent bugs from Package 4:
- generate_per_subq was called by rag.py but never added to _VALID_STEPS or DB seed (would ValueError at runtime)
- _SEED_GENERATE placeholder mismatch: flat generate_response() expects {question}/{context} but Package 4 changed it to {context_sections}. Restored flat template; generate_per_subq now holds {context_sections}.

Add database backfill migration in seed_default_profiles() to INSERT OR IGNORE missing steps into existing profile rows, ensuring all 7 steps exist on restart.

Restructure System Prompts UI: remove unused flat filter/generate steps, replace with Step 2.1-2.3 (filter_intro/section/outro) and Step 3 (generate_per_subq). Update PlaceholderDocs with {context_sections}, {subq_idx}, {subq_question}.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-27 11:14:27 +08:00
Woody 7069f15b95 docs: update testing rules to integration-first approach
- Prefer integration tests (TestClient + real DB) over mocked unit tests
- Never mock database or internal services; only mock external APIs (LLM/ASR)
- Rename 'unit tests' to 'integration tests' throughout for consistency
2026-04-27 10:55:43 +08:00
Woody a72d5b0773 docs: update AGENTS.md with per-sub-question pipeline architecture
Replace flat 3-step LLM workflow with per-sub-question architecture diagram. Document per-sub-question retrieval, filtering (single LLM call with sub-q grouping), and response generation with ## headers. Update CODE MAP to reflect completed implementation status. Add SSE event sequence with generating_subquestion events, history XML format with <sub_q> wrappers, and sources as list-of-lists JSON.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:30:19 +08:00
Woody 3f292abe1b test(frontend): add Phase 4 UI and e2e tests for per-sub-q rendering
6 stream state tests for completed, backward compat, generating_subquestion, null sources, lifecycle, and reset. 7 type tests for SubQuestionSources shape, discriminated union narrowing, and QueryResponse. 8 ResponsePanel tests for per-subq sections, source scoping, backward compat flat rendering, copy button, skeletons, and empty states. 7 citationParser tests for per-subq lookup, cross-section isolation, and processCitationsForSubq. 2 e2e tests for per-subq SSE display and progressive generation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:30:08 +08:00
Woody 7d072e5ea1 feat(frontend): redesign ResponsePanel for per-sub-question sections with grouped sources
Redesign ResponsePanel with SubQuestionSections component that parses answer markdown on ## Sub-question N: boundaries and renders per-sub-question cards with headers, ReactMarkdown body, and collapsible sources scoped to each section. Extract FlatResponse for backward compatibility when subQuestionSources is null. Add buildCitationLookupForSubq and processCitationsForSubq for per-sub-question citation lookup scope isolation. Add anchor links in ExtractedQuestionsDisplay that smooth-scroll to matching ResponsePanel sections. Pass subQuestionSources through LTTPage.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:29:51 +08:00
Woody 098368bb42 feat(frontend): add per-sub-question types and stream state management
Add SubQuestionSources interface for grouped per-sub-question sources. Convert QueryStreamEvent from flat interface to discriminated union with 7 variants including generating_subquestion and completed with sub_question_sources. Add subQuestionSources to QueryStreamState. Update completed event handler to populate subQuestionSources. Make sub_question_sources optional for backward compatibility with old SSE format.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:29:38 +08:00
Woody 3f50f81bfe test(backend): extend existing tests for per-sub-q methods and templates
Add 6 tests for retrieve_per_subquestion and generate_response_per_subquestion to Phase 1 rag service tests. Add 4 tests for filter_per_subquestion to Phase 1 relevance filter tests. Add 2 tests for new {context_sections} generate template to Phase 3 prompt injection tests. Add TestPerSubQPipelineHistory class with 3 per-sub-q pipeline simulation tests to Phase 3 integration tests. Add generate_per_subq template seed to conftest mock_prompt_service fixture.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:29:27 +08:00
Woody 201bddecf0 test(backend): add Phase 4 integration and acceptance tests
5 integration tests simulating full per-sub-question pipeline with mocked services covering 2-sub-q, empty decomposition fallback, single sub-q, all-filtered, and partial retrieval. 2 acceptance tests (manual run) for real LLM verification of per-sub-question organized answers with grouped sources and ## Sub-question headers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:29:09 +08:00
Woody dd98fa0b65 test(backend): add Phase 4 unit tests for generate, format, history, prompts
9 tests for generate_response_per_subquestion() and answer format validation covering multi-sub-q, empty, prompt construction, and markdown format. 8 tests for new history XML/JSON formats (sources as list-of-lists, <sub_q> wrappers in XML) and new {context_sections} prompt template.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:28:58 +08:00
Woody ab6ec28de6 test(backend): add Phase 4 unit tests for retrieval and filtering
10 tests for retrieve_per_subquestion() covering multi-sub-q, empty, single, call counting, n_results passthrough, and empty results. 14 tests for filter_per_subquestion() covering basic filtering, threshold behavior, JSON parsing edge cases, markdown extraction, LLM exceptions, and format helpers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:28:45 +08:00
Woody 0ecae11bf8 feat(db): update history schema and generate prompt template for Package 4
Add chunks_retrieved_per_subq_count and chunks_filtered_per_subq_count columns to query_history table with safe ALTER TABLE migration. Replace generate template {question}/{context} placeholders with {context_sections} for per-sub-question organized context sections. Update Phase 3 test assertions to match new template and schema shapes.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:28:28 +08:00
Woody 40393d81f8 feat(models): add SubQuestionSources model and per-sub-q history fields
Add SubQuestionSources, SubQuestionResult, GeneratingSubquestionEvent Pydantic models for the new per-sub-question response format. Add chunks_retrieved_per_subq_count and chunks_filtered_per_subq_count optional fields to QueryHistoryRecord and QueryHistoryDetail for per-sub-question chunk count tracking.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:28:19 +08:00
Woody 666b603639 feat(query): refactor pipeline for per-sub-question flow with progressive SSE
Restructure _query_stream() to use per-sub-question retrieval, filtering, and generation. Add generative_subquestion SSE events for progressive frontend rendering. Add format_chunks_retrieved_per_subq() and format_chunks_filtered_per_subq() with <sub_q> XML wrappers. Add empty decomposition fallback using original question as single sub-q. Update history recording for grouped sources JSON (list-of-lists format).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:28:06 +08:00
Woody 57a130dc96 feat(services): add per-sub-question retrieval, filtering, and response generation
Add retrieve_per_subquestion() that queries ChromaDB independently per sub-question instead of joining all sub-qs into one query string. Add filter_per_subquestion() that evaluates each chunk against its own originating sub-question in a single LLM call with a redesigned grouped prompt. Add generate_response_per_subquestion() that produces markdown sections per sub-question with grouped sources and {context_sections} template support. All existing methods preserved for backward compatibility.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:27:50 +08:00
Woody d509c14b80 docs(plan): add Package 4 per-sub-question enhancement plan
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 23:27:36 +08:00
Woody 0d3e8ce0ce fix(frontend): save button always disabled on System Prompts page
Root cause: PromptEditor useEffect synced localPrompts back to match prompts after every keystroke, making isDirty() always false.

- Delegate disabled control to parent via hasChanges prop (no local sync)

- Derive currentPrompts synchronously to avoid empty-textarea flash

- Add key={selectedProfile} for clean remount on profile switch

- Update PromptEditor tests for new hasChanges prop

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 18:48:52 +08:00
Woody 9f41a328e3 fix(frontend): remove duplicate History link from NavBar
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-26 18:48:31 +08:00
Woody d7cf785452 feat(frontend): Phase 3.6 — History page with timing bars, expandable cards, and pagination 2026-04-26 13:19:52 +08:00
Woody 475306f2b1 feat(history): Phase 3.5 — Query History backend (service, API, timing, XML capture) 2026-04-25 22:59:53 +08:00
Woody 8e6597a86e feat(frontend): Phase 3.3 — System Prompt Configuration page
- SystemPromptsPage: profile selector, activation, edit with TanStack Query
- ProfileList: 3 profile cards (A/B/C) with active indicator + edit button
- PromptEditor: 3 monospace textareas, placeholder badges, char count,
  unknown placeholder warnings, per-step reset (↺), action bar
- PlaceholderDocs: info box showing {question}/{chunks}/{context}
- Data layer: +7 types, +6 API functions, +6 TanStack Query hooks
- Routing: /system-prompts route + NavBar link
- Tests: 27 tests (PlaceholderDocs 6, ProfileList 7, PromptEditor 14)
- 0TS errors, 27/27 tests pass, 1 pre-existing e2e failure (unrelated)
2026-04-25 21:26:42 +08:00
Woody e49a68b0bd feat(prompts): Phase 3.2 — Prompt Backend (CRUD service, REST API, 33 tests)
- PromptService (services/prompt_service.py): full CRUD for 3 profiles A/B/C
  with seed template reset, validation, and sqlite3.Row access
- REST API (routers/prompts.py): 6 endpoints on /api/v1/prompts
- Pydantic models (models/prompts.py): 6 schemas
- DI wiring (dependencies.py): get_prompt_service()
- App registration (main.py): prompts router
- Mock fixture (conftest.py): mock_prompt_service
- Tests: test_phase3_prompt_service.py (22) + test_phase3_prompts_router.py (11)
- 162/166 total pass, 4 skipped, 0 fail
2026-04-25 21:11:17 +08:00
Woody f4b404f27d feat(db): Phase 3.1 — SQLite infrastructure (prompts.db + history.db)
- Add sqlite_db.py with dual-DB connection factories (WAL mode, foreign keys)
- init_prompts_db() creates system_prompt_profiles + system_prompts tables
- init_history_db() creates query_history table + created_at index
- seed_default_profiles() inserts 3 profiles (A/B/C) x 3 steps each
- All 3 profiles start with identical seed templates; Profile A active
- Add prompts_db_path + history_db_path to config (./data/ default)
- Startup init in main.py creates data/ dir, inits both DBs, seeds profiles
- Add PROMPTS_DB_PATH + HISTORY_DB_PATH to .env.example
- Add data/ to .gitignore
- 17 new tests in test_phase3_sqlite_db.py (all passing)
2026-04-25 20:29:29 +08:00
Woody b710002c6e chore: clean up accidentally committed temp files 2026-04-25 18:29:38 +08:00
Woody 3b741c1844 feat(query): stream extracted questions immediately via SSE
Convert /query endpoint from synchronous JSON to Server-Sent Events (SSE)
streaming. The frontend now receives extracted_questions as soon as the
first LLM call completes, without waiting for retrieval, filtering, and
answer generation.

Backend:
- Add StreamingQueryEvent union type (Decomposed, Retrieving, Filtering,
  Generating, Completed, Error)
- Convert /query to return StreamingResponse with SSE format
- Yield events after each pipeline phase

Frontend:
- Add queryDocumentStream() using fetch + ReadableStream
- Add useQueryDocumentStream() hook with phase-aware state
- Update LTTPage to use streaming instead of mutation
- Update ResponsePanel to show phase messages (Searching documents...,
  Filtering passages..., Generating answer...)
- Update ExtractedQuestionsDisplay to accept null

Tests:
- Update query_flow e2e test to mock queryDocumentStream
- 84/85 tests pass (1 pre-existing failure from removed file-input)
2026-04-25 18:29:22 +08:00
Woody 15b17a74ff fix(frontend): chunk PDFs are single-page — always render page 1
Chunk PDFs like 'NEC4 ACC_page_5.pdf' contain only 1 page (the extracted
page). Passing the original page number (e.g. 5) to <Page> caused
'Invalid page request' because the file only has 1 page.

- Always render pageNumber={1} for <Page> component
- Display originalPage in UI title to show source page number
- Disable prev/next navigation since chunk PDFs are single-page
2026-04-25 17:56:06 +08:00
Woody e34067fe9c fix(frontend): URL-encode file paths in PDF viewer + add page error handling
- Encode filePath with encodeURIComponent to handle spaces/special chars
- Add page-level error handling in PdfViewerPage for better diagnostics
- Show PDF URL in error message to aid debugging
2026-04-25 17:39:54 +08:00
Woody 7a89651512 fix(frontend): PDF viewer version mismatch — use CDN worker matching react-pdf bundled version
pdfjs-dist 5.6.205 was installed separately from react-pdf's bundled 5.4.296.
Change workerSrc from local pdfjs-dist import to unpkg CDN with dynamic version.
Uses pdfjs.version from react-pdf to ensure API/worker version match.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-25 14:50:23 +08:00
Woody 60fd37c90a fix(frontend): resizable panel sizing — use percentage strings for constraints
react-resizable-panels v4 interprets numeric minSize/maxSize as PIXELS, not percentages.
Change minSize={15} → minSize='15%' and maxSize={60} → maxSize='60%'.
Add defaultLayout on Group for explicit 30/70 initial split.
Add min-h-0 to grid container and shrink-0 to separator.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-25 14:50:05 +08:00
Woody 5ff4eaa104 docs: mark sub-phase 2.6 complete — Package 2 all done
All 6 UX enhancements implemented and tested.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:53:56 +08:00
Woody 95f7cb04bf fix(tests): add DOMMatrix polyfill for react-pdf/jsdom compatibility
Required for react-pdf v10 in test environment.
Refactor polyfills to use named variables to avoid TS class name conflicts.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:53:39 +08:00
Woody f07e14aafd feat(frontend): render inline citations as clickable PDF links (sub-phase 2.6)
ResponsePanel now calls processCitations() on answer text before rendering.
Custom ReactMarkdown 'a' component adds target="_blank" to all citation links.
Adds tests for citation link rendering and unmatched citation fallback.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:53:25 +08:00
Woody 9095432806 feat(frontend): add citation parser utility with tests (sub-phase 2.6)
processCitations() parses [filename, page N] patterns from LLM answers.
Cross-references with sources[] array to build clickable markdown links.
Graceful fallback: unmatched citations remain as plain text.
Handles markdown images/links, case-insensitive matching, DOCX without pages.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:53:10 +08:00
Woody e78b670baa feat(backend): use [filename, page N] citation labels in RAG context (sub-phase 2.6)
Replace numeric [1] labels with [filename, page N] format in context chunks.
Update LLM prompt to instruct inline citation using bracket labels.
Enables traceable source references in generated answers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:52:54 +08:00
Woody 06f016c83d docs: update enhancement plan with sub-phase 2.5 completion
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:10:03 +08:00
Woody a3028df4e1 feat(frontend): update View PDF links to open in-browser viewer (sub-phase 2.5)
ResponsePanel and ChunkList View PDF links now open /pdf-viewer page instead of raw PDF download.
Update ChunkList test mock from getChunkPdfUrl to getPdfViewerUrl.
Add DOMMatrix polyfill to test setup for react-pdf/jsdom compatibility.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:09:50 +08:00
Woody 67e411cdca feat(frontend): add PDF viewer page with react-pdf (sub-phase 2.5)
Dedicated /pdf-viewer route renders PDFs in-browser using react-pdf v10 + pdfjs-dist.
Page navigation, zoom controls, back-to-LTT link.
Standalone layout (no NavBar) for clean viewing experience.
Add getPdfViewerUrl helper and exclude pdfjs-dist from Vite optimizeDeps.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 17:09:32 +08:00
Woody c518955d31 docs: update enhancement plan with sub-phase 2.4 completion
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:52:40 +08:00
Woody 55eee6b98b feat(frontend): add resizable split panel layout to LTT page (sub-phase 2.4)
Replace fixed CSS Grid with react-resizable-panels v4 (Group/Panel/Separator).
Upper panel (video + query) defaults to 30%, lower panel (response) to 70%.
Draggable divider with hover/active state via data-separator attributes.
Add ResizeObserver and DOMRect polyfills to test setup for jsdom compatibility.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:52:25 +08:00
Woody f62dcad630 docs: update enhancement plan with sub-phase 2.3 completion
Mark sub-phase 2.3 (Extracted Questions) as done. Status: 2.1 , 2.2 , 2.3 .

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:25:02 +08:00
Woody 467d88489c test(frontend): update tests for extracted questions and inline question display (sub-phase 2.2/2.3)
Replace KeywordsDisplay test with ExtractedQuestionsDisplay test. Update e2e mock data for extracted_questions. Fix QueryInput to show submitted question inline with submit button.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:24:49 +08:00
Woody 4c51758348 feat(frontend): replace KeywordsDisplay with ExtractedQuestionsDisplay (sub-phase 2.3)
Delete KeywordsDisplay (blue pills) and create ExtractedQuestionsDisplay (numbered list). Rename keywords to extracted_questions in types and LTTPage.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:24:30 +08:00
Woody 51640201f3 test(backend): update query tests for sub-question generation (sub-phase 2.3)
Update prompt assertion in decomposer test and field assertions in query endpoint tests to match extracted_questions rename.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:24:10 +08:00
Woody f9dda7bd18 feat(backend): rename keywords to extracted_questions in query pipeline (sub-phase 2.3)
Change QueryDecomposer prompt to generate 2-5 sub-questions instead of keywords. Rename API field from keywords to extracted_questions across models, service, and router.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 16:23:53 +08:00
Woody ecaa9ebb26 docs: update enhancement plan with sub-phase 2.1 and 2.2 completion
Mark sub-phases 2.1 (Remove Upload) and 2.2 (Question Display) as done.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 15:56:50 +08:00
Woody 87acb8816a feat(frontend): display submitted question below input (sub-phase 2.2)
Show submitted question as italic text below the input area after clicking submit. Clears when user starts typing a new question.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 15:56:35 +08:00
Woody 0ba8ff2e24 feat(frontend): remove IngestPanel from LTT page (sub-phase 2.1)
Remove redundant upload panel from LTT page. Upload functionality lives on the RAG Database page.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-24 15:56:21 +08:00
Woody d49756f374 feat: add chunk PDF serving endpoint and frontend clickable source links (1.5.6)
- Add page_number and chunk_file_path to SourceMetadata model and query router
- Add GET /chunks/{file_path}/pdf endpoint with path traversal protection
- Add View PDF links in ResponsePanel source cards and ChunkList component
- Update TypeScript types and API helper for chunk PDF URLs
- Add backend tests (5) and frontend ChunkList tests (7)
- Update enhancement plan: all 3 features complete
2026-04-24 11:49:39 +08:00