shinalok and Claude Sonnet 4.6
ab437d5d2e
UI/UX D3: dark mode toggle, chat export, accessibility, onboarding modal
...
- app.py: _JS with dark mode toggle (localStorage + system preference) (D3-17)
- app.py: dark mode CSS overrides for custom chat bubble colors (D3-17)
- app.py: export_chat() -> gr.File .md download button in controls row (D3-18)
- app.py: JS aria-label/role/aria-live injection for chatbot and inputs (D3-19)
- app.py: :focus-visible CSS 3px blue outline for keyboard navigation (D3-19)
- app.py: first-visit onboarding modal with localStorage guard (D3-20)
- app.py: js=_JS wired into gr.Blocks()
- ROADMAP.md: mark all D3 items complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 14:45:49 +09:00
shinalok and Claude Sonnet 4.6
fb438864b1
UI/UX D2: branded header, custom theme, bubble styles, streaming animation, responsive
...
- app.py: styled HTML header with robot icon + subtitle (D2-11)
- app.py: gr.themes.Soft(blue/indigo/slate) applied to gr.Blocks (D2-12)
- app.py: user_selector moved to header Row, right-aligned scale=0 (D2-13)
- app.py: .message-wrap .user/.bot custom background + border-radius CSS (D2-14)
- app.py: streaming-indicator blink animation on _live_html (D2-15)
- app.py: @media max-width:768px responsive CSS (D2-16)
- ROADMAP.md: mark all D2 items complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 14:41:51 +09:00
shinalok and Claude Sonnet 4.6
c1a28bfdcc
UI/UX D1: examples, image accordion, layout improvements, table select, button size
...
- app.py: add gr.Examples with 3 sample questions (D1-5)
- app.py: wrap image input in gr.Accordion(open=False) (D1-6)
- app.py: checkboxes left Column(scale=3), reset btn right Column(scale=1) (D1-7)
- app.py: msg_box lines=2, send_btn .send-btn CSS min-height 80px (D1-8)
- app.py: doc_table.select -> select_doc_row auto-fills delete_source (D1-9)
- app.py: ingest_btn scale=0 min_width=200 to avoid full-width stretch (D1-10)
- ROADMAP.md: mark all D1 items complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 14:28:21 +09:00
shinalok and Claude Sonnet 4.6
e08b43c785
UI/UX D0: fix Textbox label, hide audio accordion, hide footer, hide ingest result box
...
- app.py: show_label=False on msg_box to remove "Textbox" label
- app.py: wrap audio input in gr.Accordion(open=False) to hide microphone error on load
- app.py: add CSS to hide Gradio footer branding
- app.py: ingest_status starts visible=False; ingest_files returns gr.update(visible=True)
- ROADMAP.md: add UI/UX design improvement section (D0–D3) and mark D0 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 14:25:54 +09:00
shinalok
20f385e2a0
Merge remote-tracking branch 'origin/main'
2026-06-02 14:12:45 +09:00
shinalok
4565980915
Merge remote-tracking branch 'origin/main'
...
# Conflicts:
# .env.example
2026-06-02 14:09:54 +09:00
shinalok
b13e3dfdd7
Add .env.example file with API and voice configuration templates
2026-06-02 14:09:40 +09:00
shinalok and Claude Sonnet 4.6
0803479438
Fix: move image_input to separate row for cleaner layout
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 14:04:01 +09:00
shinalok and Claude Sonnet 4.6
7f50333bdb
Phase 17: Add image upload to chat UI
...
- app.py: image_input gr.Image component, respond() accepts image_path,
all yields updated to 7 outputs
- api_client.py: chat(image_path=None), base64-encodes image for API
- services/chat.py: chat(image_path=None) passes through to api_client
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 13:52:21 +09:00
shinalok and Claude Sonnet 4.6
974bab7cd8
Phase 28: P3 — Pydantic Settings, dependency-injector IoC, tenacity retry
...
- config.py: dataclasses → pydantic-settings BaseSettings (flat AppConfig,
env vars auto-loaded from .env, type-safe validation)
- api_client.py: HTTPAPIClient takes AppConfig directly (APIConfig removed);
tenacity retry on 5 methods (reset/ingest/list/delete/feedback) —
retries on 5xx + TransportError, 3 attempts, exponential backoff 1-8s
- container.py: manual DI → dependency_injector DeclarativeContainer with
providers.Singleton; Container() needs no args
- app.py: container.X → container.X() calls, remove AppConfig import
- requirements.txt: add pydantic-settings, tenacity, dependency-injector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-02 05:59:23 +09:00
shinalok and Claude Sonnet 4.6
148211e236
Phase 27: P2 quality improvements — logging, httpx pooling, validation, tests
...
- app.py: replace print() with logging, basicConfig with LOG_LEVEL env var
- api_client.py: shared AsyncClient instance (connection pooling), URL-encode
delete_document path parameter, aclose() for cleanup
- services/document.py: validate file exists and extension before ingest
- tests/: ChatService (4) + DocumentService (6) unit tests via pytest-asyncio
- pyproject.toml: asyncio_mode = auto
- requirements-dev.txt: pytest, pytest-asyncio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:52:43 +09:00
shinalok and Claude Sonnet 4.6
511c87b290
docs: update ROADMAP to reflect P0/P1 completion and services/ package structure
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:46:53 +09:00
shinalok and Claude Sonnet 4.6
79f2abe7cf
chore: exclude .claude/ from git tracking
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:41:17 +09:00
shinalok and Claude Sonnet 4.6
7eed70d7f7
chore: add .gitignore rules for IDE and cache files, remove tracked artifacts
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:40:08 +09:00
shinalok and Claude Sonnet 4.6
1e93def909
Refactor: split services.py into services/ package
...
ChatService → services/chat.py
DocumentService → services/document.py
TTSService → services/tts.py
services/__init__.py re-exports all three for backward-compatible imports
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:39:52 +09:00
shinalok and Claude Sonnet 4.6
d81a2f5888
Phase 26: P1 architecture refactor — DI container, service layer, async callbacks
...
- config.py: APIConfig + AppConfig dataclasses, env vars centralized
- api_client.py: APIClientProtocol (Protocol) + HTTPAPIClient class, remove module-level globals
- services.py: ChatService, DocumentService, TTSService (TTS moved from app.py)
- container.py: manual DI container with lazy singleton properties
- app.py: all callbacks converted to async, asyncio.run() fully removed, container wired in
- .env.example: add TTS_EDGE_VOICE entry
- ROADMAP.md: P0/P1 checklist updated to reflect completed work
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 17:36:35 +09:00
shinalok
be4b7c40cb
Merge remote-tracking branch 'origin/main'
2026-06-01 16:42:58 +09:00
shinalok
5ea7948ed3
Add project roadmap outlining improvements and priorities
2026-06-01 16:42:37 +09:00
shinalok and Claude Sonnet 4.6
38d2edeeec
Phase 25: Separate RAG sources into collapsible box below chatbot
...
- Add source_box gr.HTML component below chatbot
- Add _sources_html() helper rendering <details> expand/collapse
- Handle __sources token in respond(): update source_box independently of thinking_box
- Reset both thinking_box and source_box on each new message
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 16:15:06 +09:00
shinalok and Claude Sonnet 4.6
55ea69d902
Fix details close-on-update: use div during streaming, details on complete
...
During streaming: _live_html (plain div) shows only the current line —
no DOM reset, no closing issue. __thinking shows last non-empty line,
__meta shows the full trimmed message.
On completion: _thinking_html (<details>) shows all accumulated content
collapsed, expands on click.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 13:50:21 +09:00
shinalok and Claude Sonnet 4.6
18609a4f7d
Collapsible thinking box with details/summary, thinking on by default
...
- Thinking box uses <details>/<summary> — collapsed by default, expands on click
- Simple __status header shown before content arrives (no expand needed)
- show_thinking checkbox default changed to True
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 13:34:47 +09:00
shinalok and Claude Sonnet 4.6
5cf8bdabfd
Handle __status tokens for instant thinking box feedback
...
__status tokens show immediately in the thinking box but do not
accumulate in thinking_acc. When real content (__meta/__thinking)
arrives it overwrites the status message naturally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 13:08:30 +09:00
shinalok and Claude Sonnet 4.6
4956ab7085
Replace gr.Markdown thinking box with gr.HTML for reliable streaming
...
gr.Markdown visible toggling is unreliable in Gradio streaming generators.
Switched to gr.HTML with inline styles — empty string hides the element,
HTML string shows the styled box. No visibility state needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 11:30:57 +09:00
shinalok and Claude Sonnet 4.6
2348f17791
Move progress logs into thinking box alongside LLM reasoning
...
Both __meta (LangGraph/search progress) and __thinking (LLM reasoning)
tokens now stream into the thinking box instead of the chatbot.
Chatbot shows only the final answer. Thinking box shows the full
analysis pipeline: [LangGraph → ...], 문서 검색 중, thinking content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 10:56:01 +09:00
shinalok and Claude Sonnet 4.6
8c859971d1
Add thinking box UI and fix async event loop errors
...
- Show thinking progress in a separate animated box above chatbot
(🤔 사고 중... while streaming, 💭 사고 완료 when answer starts)
- Fix ValueError: add missing 5th yield value (thinking_box) to all
respond() yield statements
- Fix [Reset] and other sync handlers: replace asyncio.get_event_loop()
.run_until_complete() with asyncio.run() for AnyIO thread compatibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-01 10:33:15 +09:00
shinalok
0424cf4b31
Add thinking process visualization to WebUI
...
- Introduced "thinking box" UI to display intermediate thought processes.
- Added CSS styling for the thinking box with scrollable and formatted design.
- Updated response handling to show thinking progress and completion dynamically.
- Enhanced Gradio outputs to include the new thinking box component.
2026-06-01 10:26:29 +09:00
shinalok and Claude Sonnet 4.6
6435af5837
Separate TTS text from metadata tokens in respond()
...
Filter __meta dict tokens from TTS accumulator so progress messages
([LangGraph], thinking blocks, source references) are displayed in chat
but not read aloud. Answer tokens continue to accumulate in tts_text.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-31 23:08:22 +09:00
shinalok
7fa45afc7f
Fix TTS to use pure response content without meta tokens
2026-05-31 23:05:28 +09:00
shinalok
cf68e19f38
Add cross-platform TTS support and update dependencies
2026-05-30 23:54:41 +09:00
shinalok
9455b591de
Add initial implementation of Youlbot WebUI with Gradio frontend
2026-05-30 22:09:53 +09:00