Skip to content

Conversation

@basnijholt
Copy link
Owner

No description provided.

- Enable CORS in .
- Add  directory with Vite + React + TypeScript + Electron.
- Configure  with proper primitives.
- Add basic tests for UI component.
- Exclude  from Python linting (ruff/mypy).
Pivot the UI implementation strategy to leverage assistant-ui's built-in
runtime adapters and primitives instead of building custom components.

Key changes to UI-PLAN.md:
- Add "Native Assistant-UI First" principle
- Document correct vs incorrect integration patterns
- Restructure phases: runtime adapter before custom UI
- Add anti-patterns section to prevent future missteps
- Add context section for continuity between sessions

Also removes debug check scripts and adds runtime inspection test.
Temporary submodule for AI agents to reference assistant-ui source code
and understand runtime interfaces, primitives, and integration patterns.
Will be removed after UI implementation is complete.
Add comprehensive documentation to make UI-PLAN.md a living document:

- Section 7: Backend API contract with request/response types
- Section 8: Step-by-step Phase 2 implementation guide
- Section 9: Assistant-UI reference paths for key source files
- Section 10: Additional anti-patterns
- Section 11: Decision log for tracking architectural choices
- Section 12: Open questions for future resolution

This provides enough detail for any developer (human or AI) to continue
the implementation without losing context.
Expand Section 6 with:
- Explicit file-by-file status (keep/delete/refactor)
- Concrete implementation steps with paths
- Key reference files that must be read
- Gotchas and tips for common issues
- Verification checklist for Phase 2 completion

This ensures no context is lost after session compression.
Replace custom components with native assistant-ui primitives:

- Add useAgentCLIRuntime hook using useLangGraphRuntime pattern
- Create ThreadList component using ThreadListPrimitive
- Refactor App.tsx to use AssistantRuntimeProvider
- Delete custom Sidebar, ChatArea, and SettingsModal components
- Update tests and plan documentation

The runtime adapter handles:
- Thread loading via GET /v1/conversations/{id}
- Thread creation with lazy backend persistence
- SSE streaming via POST /v1/chat/completions
- OpenAI <-> LangChain message format conversion
Add node_modules/ to .gitignore and remove 10,814 tracked files.
These should never have been committed.
- Create SettingsModal.tsx with model selector and memory_top_k input
- Update App.tsx to lift config state and integrate settings modal
- Add Settings button to ThreadList sidebar footer
- Use useRef in runtime adapter to fix stale closure with config changes
- Update tests to verify settings functionality
- Update UI-PLAN.md to mark Phase 3 complete
- SettingsModal now fetches models from /v1/models endpoint on open
- Shows loading state while fetching
- Falls back to manual text input if API fails or returns no models
- Remove hardcoded model list
- Runtime adapter only sends model param if explicitly set
- Update tests to mock /v1/models endpoint
- Fetch models on app startup, not just when settings opens
- Auto-select first available model if none configured
- Show loading state while fetching initial model
- Show warning overlay if no model is selected
- Model field is required by backend API
- Parse both delta.content and delta.reasoning_content from SSE
- Thinking models (qwen3-thinking) use reasoning_content
- Regular models use content
- Display reasoning while waiting for content
- Handle finish_reason to properly complete stream
The previous useLangGraphRuntime hook required AssistantCloud and silently
fell back to InMemoryThreadListAdapter which always returned externalId as
undefined, causing "Thread not found" errors.

Replaced with useExternalStoreRuntime which gives full control over:
- Message state management with stable IDs
- Thread switching (onSwitchToThread, onSwitchToNewThread)
- Streaming response handling

Also added Playwright E2E tests covering:
- UI element loading
- Settings modal with model fetching
- Chat message sending and streaming response
- Thinking model reasoning_content handling
- No-model-selected error state
- Document runtime refactor from useLangGraphRuntime to useExternalStoreRuntime
- Add Phase 3.5 for conversation persistence (next task)
- Document Playwright E2E test suite (5 tests)
- Update decision log with new technical decisions
- Fetch conversation list from /v1/conversations on startup
- Populate ThreadList sidebar with existing conversations
- Use adapters.threadList API to expose thread list to primitives
- Persist selected thread to localStorage for continuity
- Auto-select first conversation when returning to app
- Add 3 new E2E tests for persistence behavior

All 8 E2E tests passing.
- Add dark mode with toggle button and persistent theme preference
- Add keyboard shortcuts: Cmd/Ctrl+, for settings, Cmd/Ctrl+D for dark mode
- Create useTheme hook for theme management with localStorage persistence
- Update all components with dark mode classes (bg, text, border colors)
- Add markdown rendering support for assistant messages using react-markdown
- Fix test setup with localStorage, matchMedia, and scrollTo mocks
- Update E2E tests to use more specific role-based selectors
- Exclude e2e tests from vitest to prevent framework conflicts
Phase 3.6 adds:
- Dark mode with toggle and localStorage persistence
- Keyboard shortcuts (Cmd/Ctrl+, for settings, Cmd/Ctrl+D for dark mode)
- Markdown rendering for assistant messages
- Test infrastructure improvements (mocks for localStorage, matchMedia, scrollTo)
- Add bouncing dots animation when thread is running
- Use ThreadPrimitive.If with running condition
- Fix scrollTo mock type in test setup
- Fix empty message box showing before content by using MessagePrimitive.If
  with hasContent condition to only show typing indicator when no content yet
- Add collapsible reasoning display using assistant-ui's ReasoningGroup and
  Reasoning components for viewing model thinking/reasoning content
- Move typing indicator inside AssistantMessage component for proper placement
- Add proper Reasoning and ReasoningGroup components following the official
  assistant-ui documentation pattern from the local repo clone
- Uses MarkdownTextPrimitive for automatic text context reading
- Uses Radix UI Collapsible for smooth expand/collapse animations
- Includes useScrollLock to prevent scroll jumps on collapse
- Detects streaming state for shimmer animation effect
- Adds @radix-ui/react-collapsible, clsx, and tailwind-merge dependencies
- Creates reusable ui/collapsible and utils/utils modules
Parse delta.reasoning_content separately from delta.content in SSE
streaming. Store reasoning on messages and convert to proper
assistant-ui content parts with type: "reasoning" for display in
collapsible boxes.
Add a model selector dropdown above the message input that:
- Fetches available models from /v1/models endpoint
- Filters out embedding models
- Persists selection to localStorage
- Updates runtime config when model changes

Components added:
- ModelPicker: fetches and displays model list
- Select UI component (radix-ui based)
… nav

- Move model selector from composer area to sidebar footer
- Add fuzzy search with auto-focus on dropdown open
- Add keyboard navigation (Arrow Up/Down, Enter, Escape)
- Persist selected model to localStorage across refreshes
- Remove standalone ModelPicker and Select components
- Add response metadata fields to MemoryMetadata model (model, tokens, timing)
- Create ResponseMetadata class and add to Turn entity
- Update write_memory_file() and persist_entries() to store metadata
- Create StreamingAccumulator to capture metadata from SSE streams
- Update engine.py streaming/non-streaming paths for metadata capture
- Update client.py get_history() to return metadata for assistant messages
- Fix loadThreadMessages() to parse metadata from API response
- Refactor: extract ModelSelector, SSE utils, and config to separate files
…React

- Install ESLint 9 with flat config, TypeScript-ESLint, React plugins, Prettier
- Create eslint.config.mjs with browser/Node globals and sensible rules
- Create .prettierrc with consistent formatting settings
- Add lint, lint:fix, format, format:check, typecheck scripts to package.json
- Add pre-commit hooks for eslint, prettier, and typecheck
- Auto-fix all formatting issues (single quotes to double quotes)
- Fix unused variable in e2e tests
- Create types.ts with shared MessageMetadata and Model interfaces
- Create useModels.ts hook to centralize model fetching logic
- Simplify useTheme.ts (40→24 lines) with cleaner implementation
- Simplify sse.ts (123→72 lines) using object accumulator pattern
- Update App.tsx, ModelSelector.tsx, SettingsModal.tsx to use shared hooks
- Update Thread.tsx and useAgentCLIRuntime.ts to use shared types
- Fix react-hooks/exhaustive-deps warning in useAgentCLIRuntime.ts

Net reduction of ~150 lines while maintaining all functionality.
Replace 11 individual metadata kwargs with embedded ResponseMetadata
Pydantic model. Maintains backward compatibility by flattening to YAML
on write and un-flattening on read. Also adds DELETE conversation
endpoint and thread archive functionality in UI.
Simplify _files.py by removing flat-to-nested conversion logic since
there is no existing data to maintain compatibility with.
- Rename MessageMetadata to ResponseMetadata in types.ts
- Add DisplayMetadata type for UI display
- Update all TypeScript files to use snake_case property names
- Ensures consistent naming between Python and TypeScript
- Clarify why useLangGraphRuntime was replaced: InMemoryThreadListAdapter
  fallback returns empty lists and undefined externalIds
- useExternalStoreRuntime is correct "bring your own backend" pattern
- Document SSE parser necessity for non-standard fields
- Mark DELETE endpoint and thread archiving as implemented
- Update open questions with current status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants