Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
308 commits
Select commit Hold shift + click to select a range
028fb8c
feat: Adds chat attachments functionality
allozaur Aug 1, 2025
009f77b
refactor: Decouple chat attachments display into components
allozaur Aug 1, 2025
fc1a74e
feat: Improves file handling and paste functionality
allozaur Aug 1, 2025
f3a55ed
refactor: Rename post-build script for web UI
allozaur Aug 1, 2025
e01ae49
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 2, 2025
839140b
feat: Adds file attachment previews to chat
allozaur Aug 4, 2025
2b1b1f8
feat: Improves chat form and file handling
allozaur Aug 4, 2025
6830c25
feat: Adds converting SVG images to PNG
allozaur Aug 4, 2025
ecf1f04
feat: Adds PDF file support to chat
allozaur Aug 4, 2025
932f31e
feat: Enables previewing attachments in a dialog
allozaur Aug 4, 2025
2d0b873
chore: Update `index.html.gz` build
allozaur Aug 4, 2025
5b668bf
feat: UI/UX improvements
allozaur Aug 4, 2025
e9528f6
feat: Mobile UI & UI elements improvements
allozaur Aug 4, 2025
6ffa578
feat: UI improvements
allozaur Aug 4, 2025
93fb1dc
feat: Chat Sidebar Conversation Items UI improvements
allozaur Aug 4, 2025
b592954
feat: UI improvements
allozaur Aug 4, 2025
14e8ac8
chore: Update public build
allozaur Aug 4, 2025
34f3709
feat: Sets focus to `ChatForm`'s `<textarea>` after load
allozaur Aug 5, 2025
b5d9f55
feat: Formats message timestamps for readability
allozaur Aug 5, 2025
13c30d6
refactor: Components structure
allozaur Aug 6, 2025
377b808
feat: UI improvements for Chat Settings Dialog
allozaur Aug 6, 2025
fa0e729
fix: Close search results after clicking conversation item
allozaur Aug 6, 2025
e0c4f6b
chore: Update static webui build
allozaur Aug 6, 2025
f3a8758
feat: Updates server properties handling
allozaur Aug 6, 2025
54cfe15
feat: Adds context length check before sending message (PoC)
allozaur Aug 6, 2025
e714579
chore: Adds VS Code workspace file
allozaur Aug 6, 2025
2a3d057
feat: Improves chat settings and UI layout
allozaur Aug 6, 2025
d6ec058
feat: Binds Vite dev server to all interfaces
allozaur Aug 6, 2025
b54989e
refactor: Better structure for components
allozaur Aug 6, 2025
82996b8
docs: Adds JSDoc comments and improves utils
allozaur Aug 6, 2025
8908088
chore: Windsurf rules
allozaur Aug 6, 2025
ce2f9d1
feat: Refactors settings dialog with Svelte runes
allozaur Aug 6, 2025
3a45b7d
refactor: Component imports
allozaur Aug 6, 2025
3cde171
refactor: Centralize type definitions
allozaur Aug 6, 2025
f0af1ef
feat: Improves chat service architecture, starts implementing Setting…
allozaur Aug 6, 2025
2601cbf
feat: Add WebP image conversion utilities
allozaur Aug 7, 2025
dbb292d
refactor: Extract file upload processing to utilities
allozaur Aug 7, 2025
8242776
feat(app): Extract maximum context alert dialog into component
allozaur Aug 7, 2025
be5ba77
refactor: Updates order of imports
allozaur Aug 7, 2025
bd03cb2
Refactor: Consolidate ChatScreen imports, constants, and naming setup
allozaur Aug 7, 2025
111684c
Feat: Improve chat auto-scrolling behavior
allozaur Aug 7, 2025
7a63680
refactor: Changes order of imports
allozaur Aug 7, 2025
a14d3f6
chore: Updates static build
allozaur Aug 7, 2025
7d5cd2c
Build: Enhance frontend bundle compression and size validation
allozaur Aug 7, 2025
4f8bd9b
Refactor: Decouple utility imports from index.ts
allozaur Aug 7, 2025
75afbdc
Refactor: Rename context error state to maxContextError
allozaur Aug 7, 2025
e5d263a
chore: Update static build
allozaur Aug 7, 2025
afcc79c
feat: Adds proxy and headers for local development
allozaur Aug 7, 2025
82495d9
chore: Update static build
allozaur Aug 7, 2025
23510ae
feat: Enables processing math formulas for markdown content
allozaur Aug 8, 2025
05f976a
feat: Chat Form improvements
allozaur Aug 8, 2025
5e7efef
docs: MarkdownContent component stories
allozaur Aug 8, 2025
0a42402
fix: ScrollArea Height
allozaur Aug 8, 2025
2e0f1d7
chore: Creates `fixtures` folder and adds test files
allozaur Aug 9, 2025
4cad2b6
feat: Adds support for audio file uploads
allozaur Aug 9, 2025
4ba2e04
fix: Fixes chat attachment preview interactivity & displaying issues
allozaur Aug 9, 2025
c5b5812
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 9, 2025
6c9992a
refactor: Cleans up redundant console logs
allozaur Aug 9, 2025
ed4716c
fix: Improves scroll interval on active responses stream
allozaur Aug 9, 2025
ccf4bef
feat: Improve sidebar scrollarea
allozaur Aug 9, 2025
b026a17
feat: Improves chat sidebar and header layout & structure
allozaur Aug 11, 2025
5de7bc6
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 11, 2025
20174b1
feat: Enables editing of conversation names
allozaur Aug 11, 2025
b8c6795
feat: Implement basic `Processing...` UI
allozaur Aug 11, 2025
0b71fdf
fix: Chat Sidebar interactions
allozaur Aug 11, 2025
7919123
feat: Improves UI appearance
allozaur Aug 11, 2025
e23d39d
feat: Allows sending messages with attachments only
allozaur Aug 12, 2025
787f203
refactor: Simplifies API base URL handling
allozaur Aug 12, 2025
d5735bd
fix: Add missing validation logic updates
allozaur Aug 12, 2025
ceb3d81
fix: Data binding
allozaur Aug 12, 2025
01537bc
refactor: Refactors file type handling using enums
allozaur Aug 12, 2025
8d8372b
fix: Fix types & svelte issues
allozaur Aug 12, 2025
94a06de
feat: Validates file types before upload
allozaur Aug 12, 2025
5d1d146
refactor: DRYs text file extension handling
allozaur Aug 12, 2025
a6d846e
feat: Enables audio recording in chat form
allozaur Aug 12, 2025
78219cd
faet: Displays real-time processing details (WIP)
allozaur Aug 12, 2025
b67f888
fix: Wrong file extension
allozaur Aug 12, 2025
f02925d
fix: Missing import update
allozaur Aug 12, 2025
47ec32d
refactor: Removes debug logs from chat and attachment preview
allozaur Aug 12, 2025
7e2ab2a
feat: Improves file upload handling with modality support
allozaur Aug 12, 2025
f8fc579
feat: Adds SPA fallback route to server
allozaur Aug 12, 2025
4632deb
chore: Update static build
allozaur Aug 12, 2025
be0dfce
feat: UI improvements & tests
allozaur Aug 12, 2025
d16fb23
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 12, 2025
6c99820
chore: Remove old file
allozaur Aug 12, 2025
8699fd9
feat: Improves context handling and error reporting (WIP)
allozaur Aug 13, 2025
0465636
chore: Static build update
allozaur Aug 13, 2025
2fc3a8e
fix: Stops slots polling on context errors
allozaur Aug 13, 2025
5ff1575
chore: Lint
allozaur Aug 13, 2025
a5277b0
feat: Improves error handling and UI feedback
allozaur Aug 14, 2025
96870af
feat: Embeds favicon as base64 data URL
allozaur Aug 15, 2025
b95fe24
fix: Bundles PDF.js worker inline
allozaur Aug 15, 2025
49931c4
fix: Adds TooltipProvider decorator to Storybook
allozaur Aug 15, 2025
549bf25
feat: Enhances chat form with file attachment options
allozaur Aug 15, 2025
1cafa62
feat: Adds basic WebUI CI workflow
allozaur Aug 15, 2025
57aac56
debug: Removes branch restriction for webui workflow
allozaur Aug 15, 2025
5882dc2
debug: Updates WebUI workflow trigger
allozaur Aug 15, 2025
b667585
debug: Workflow trigger
allozaur Aug 15, 2025
d2e1794
debug: Workflow trigger
allozaur Aug 15, 2025
158ab08
fix: Workflow trigger
allozaur Aug 15, 2025
edd48eb
test: Add Storybook tests to CI
allozaur Aug 17, 2025
0d2ef37
chore: Add reset script
allozaur Aug 18, 2025
bddfcb6
fix: Handle only regular content
allozaur Aug 18, 2025
31035bc
refactor: Minor formatting and cleanup in chat attachments
allozaur Aug 19, 2025
f91120f
feat: Implement `reasoning_content`
allozaur Aug 19, 2025
5d8e515
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 19, 2025
f36cd8f
chore: Update static build
allozaur Aug 19, 2025
63e59f6
refactor: Separate jobs for webui GH actions workflow
allozaur Aug 19, 2025
e027b60
feat: Improve file attachments logic
allozaur Aug 21, 2025
cf408db
chore: Add `.windsurf` rule file
allozaur Aug 21, 2025
17b027f
test: Storybook interaction/unit tests WIP
allozaur Aug 21, 2025
96913d6
test: Storybook tests WIP
allozaur Aug 22, 2025
65ca9f9
feat: Chat Form improvements + storybook improvements
allozaur Aug 22, 2025
0ec3689
feat: Show thinking block before actual message
allozaur Aug 22, 2025
935fa01
feat: Use Collapsible component for Thinking Block UI
allozaur Aug 22, 2025
3517660
test: UI/Unit tests
allozaur Aug 22, 2025
ffe27e1
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 23, 2025
c2e4b20
test: Fix for Audio/Vision Modality storybook automated tests
allozaur Aug 24, 2025
d79a443
test: Storybook cleanup
allozaur Aug 24, 2025
8b77ac4
chore: Update `webui` GH Actions workflow job names
allozaur Aug 24, 2025
66bbf35
feat: Adds keyboard shortcuts
allozaur Aug 24, 2025
9ff3ed4
feat: Adds message deletion functionality
allozaur Aug 24, 2025
9911485
feat: Edit Message UI appearance with `inputClasses`
allozaur Aug 24, 2025
9f0682a
feat: Implements conversation branching
allozaur Aug 25, 2025
8cf3cff
fix: System message handling in chat service
allozaur Aug 25, 2025
362f743
feat: Displays slot usage details in the UI above the Chat Form
allozaur Aug 25, 2025
de7add3
refactor: Chat Settings Dialog structure
allozaur Aug 25, 2025
3a17b2c
feat: Thought process setting
allozaur Aug 25, 2025
d99934a
feat: Conditionally includes reasoning format in request
allozaur Aug 25, 2025
45150e3
feat: Adds Enter key support to delete dialogs
allozaur Aug 25, 2025
923a088
refactor: Consts
allozaur Aug 25, 2025
c81046e
feat: Adds theme selection to chat settings
allozaur Aug 26, 2025
98b55cd
feat: Handles empty file uploads gracefully
allozaur Aug 26, 2025
52b4b65
chore: Update static build
allozaur Aug 26, 2025
056f20c
docs: Update README
allozaur Aug 26, 2025
f95cc3c
fix: Update script name in WebUI CI
allozaur Aug 26, 2025
16ede84
fix: Max context
allozaur Aug 26, 2025
be3ed2d
chore: Remove legacy `webui-old` React app
allozaur Aug 26, 2025
71d73c5
chore: Ignore `tools/server/webui/**` in .editorconfig
allozaur Aug 26, 2025
49ff4e3
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Aug 26, 2025
aeaeada
fix: Autoscroll on regenerating message
allozaur Aug 26, 2025
218cbcf
feat: Improve destructive actions UI & interactions
allozaur Aug 26, 2025
7fd78b6
fix: Linting
allozaur Aug 27, 2025
3029de2
feat: Improves slots processing and token rate accuracy
allozaur Aug 27, 2025
8220c80
feat: Removes 'excludeThoughtOnReq' setting
allozaur Aug 27, 2025
3a49539
feat: Fix code block default text color for light mode
allozaur Aug 27, 2025
f8c1e73
refactor: Remove legacy method for sending messages
allozaur Aug 27, 2025
2a702b7
fix: Auto-scroll after user action on a message
allozaur Aug 27, 2025
6995ca2
chore: Update static build of `webui`
allozaur Aug 28, 2025
9e7f48e
refactor: Const for `/slots` request debounce
allozaur Aug 28, 2025
de207be
fix: Fixes slots update debouncing
allozaur Aug 28, 2025
b2d38af
chore: Update static build of `webui`
allozaur Aug 28, 2025
b98d464
fix: Remove redundant call
allozaur Aug 28, 2025
604d89f
fix: Refactors slots endpoint availability check
allozaur Aug 28, 2025
aac118c
chore: Update static build of `webui`
allozaur Aug 28, 2025
eb3ffb3
refactor: Remove redundant import
allozaur Aug 28, 2025
79b2ef2
chore: Update static build of `webui`
allozaur Aug 28, 2025
369bcf2
refactor: Removes unneeded script
allozaur Aug 28, 2025
dbc44e7
chore: Bump version
allozaur Aug 28, 2025
3d515d0
test: Improve testing pipeline
allozaur Aug 28, 2025
f5a5888
reafactor: Code cleanup
allozaur Aug 28, 2025
fffb4e1
chore: Linting
allozaur Aug 28, 2025
af1473f
refactor: Code formatting and cleanup
allozaur Aug 28, 2025
dd5ed65
test: Add code formatting & eslint check to webui CI
allozaur Aug 28, 2025
6f60c03
fix: Types
allozaur Aug 28, 2025
8570a56
fix: Re-add missing prop
allozaur Aug 28, 2025
1f5276a
reafactor: Use `for...of` loops
allozaur Aug 29, 2025
8dcf66d
refactor: Cleanup
allozaur Aug 29, 2025
2f54040
refactor: Componentize Chat Message UI
allozaur Aug 29, 2025
ae77aad
refactor: Components cleanup
allozaur Aug 29, 2025
d3f8fde
refactor: Clean up Services & Hooks
allozaur Aug 29, 2025
93ae5dd
refactor: Improve architecture and documentation of services
allozaur Aug 29, 2025
d42469f
refactor: Singleton exports from service files
allozaur Aug 29, 2025
a704dd3
refactor: `PdfMimeType` -> `ApplicationMimeType`
allozaur Aug 29, 2025
7476077
refactor: Cleanup
allozaur Aug 29, 2025
ed372e3
chore: Code formatting
allozaur Aug 29, 2025
b74ea41
feat: Switch jobs order in CI
allozaur Aug 29, 2025
9a0349b
fix: Scroll to bottom of chat on refresh
allozaur Aug 31, 2025
0242c41
feat: Slots Info UI improvements
allozaur Aug 31, 2025
b4ebb5e
fix: Increase auto-scroll threshold
allozaur Aug 31, 2025
773dfd8
chore: Update static build of `webui`
allozaur Aug 31, 2025
37a9fb7
chore: Formatting
allozaur Aug 31, 2025
df5df1f
refactor: Cleanup types
allozaur Sep 1, 2025
eddd627
chore: Formatting
allozaur Sep 1, 2025
1e9c287
chore: Update `.gitignore`
allozaur Sep 1, 2025
2710127
Merge branch 'master' into allozaur/svelte-webui
allozaur Sep 1, 2025
0fb9310
chore: Update dependencies
allozaur Sep 1, 2025
c13eda4
feat: Improve Keyboard Shortcuts UI & logic
allozaur Sep 1, 2025
f52c59c
chore: Code formatting
allozaur Sep 1, 2025
aef0339
feat: UI improvements for Keyboard Shortcut Info
allozaur Sep 1, 2025
f0f6f20
feat: Update conversation title based on current first message branch
allozaur Sep 1, 2025
c6223b3
feat: Improves token usage tracking and display
allozaur Sep 1, 2025
702bf1d
chore: Code formatting
allozaur Sep 1, 2025
e7aa527
chore: Update `webui` static build
allozaur Sep 1, 2025
5ee2f29
fix: Use proper lifecycle hook
allozaur Sep 1, 2025
10c41c6
chore: Code formatting + static build update
allozaur Sep 1, 2025
55b2a9f
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 1, 2025
3775b79
refactor: Components structure & naming
allozaur Sep 3, 2025
3aa9a5e
refactor: Simplify logic for processing state
allozaur Sep 3, 2025
43a7192
chore: Code formatting
allozaur Sep 3, 2025
88356b9
chore: Update `webui` static build
allozaur Sep 3, 2025
14760f8
refactor: Cleanup
allozaur Sep 3, 2025
90476a2
docs: Add JSDocs and add missing type definitions
allozaur Sep 3, 2025
c3ffacd
test: Update `sever.yml` CI with newest WebUI jobs
allozaur Sep 3, 2025
3f6e9bd
refactor: Update CI job name
allozaur Sep 3, 2025
2833815
fix: Add missing build
allozaur Sep 3, 2025
fad84e3
fix: Update test
allozaur Sep 3, 2025
78b79e2
fix: Don't remove uncompressed `index.html` after build
allozaur Sep 3, 2025
eac36a8
fix: Retrieve `--no-webui` functionality
allozaur Sep 3, 2025
34777cd
fix: Retrieve removing uncompressed `index.html` file in post-build s…
allozaur Sep 3, 2025
9b48e33
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 5, 2025
08d09ed
fix: Post-feedback fixes
allozaur Sep 5, 2025
c74daef
test: Add Markdown Content story with interaction tests for URLs
allozaur Sep 5, 2025
2a70cc5
feat: Update Settings defaults
allozaur Sep 6, 2025
d40a712
feat: Add toast suggesting enabling PDF as image parsing with vision …
allozaur Sep 6, 2025
3b49f44
chore: Code formatting
allozaur Sep 6, 2025
510d6b2
test: Remove legacy test
allozaur Sep 6, 2025
b0845fb
chore: Update `webui` static build
allozaur Sep 6, 2025
909cee9
chore: Adds script to install pre-commit hook
allozaur Sep 6, 2025
a862318
feat: Improve pre-commit
allozaur Sep 6, 2025
e09cf6a
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 8, 2025
a22da20
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 8, 2025
d54858a
feat: Enhance processing state updates
allozaur Sep 8, 2025
69152d0
feat: Allow to re-send request for unchanged edited message
allozaur Sep 8, 2025
1b37cf3
feat: Enable editing Assistant message with optional branching
allozaur Sep 8, 2025
0bd46da
feat: Chat Form auto-focus on refresh improvements
allozaur Sep 8, 2025
a3b5393
feat: Improve auto-scroll enabling/disabling
allozaur Sep 8, 2025
67be91b
fix: No error on manual stop when re-generating messages
allozaur Sep 9, 2025
63ce684
refactor: Clean up types
allozaur Sep 9, 2025
114c342
feat: Improve chat processing info persistence
allozaur Sep 9, 2025
fd6d6f6
feat: Improve message editing features
allozaur Sep 9, 2025
a9bfe9e
fix: Add missing API Key headers if provided in settings
allozaur Sep 11, 2025
0f226a4
feat: Better Error Handling UX
allozaur Sep 11, 2025
00fd662
refactor: Remove unused code
allozaur Sep 11, 2025
d187602
feat: Use `uuid` package instead of `crypto.randomUUID()`
allozaur Sep 12, 2025
b992243
fix: Navigator fallback for non-secure context
allozaur Sep 15, 2025
1098d0d
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 15, 2025
8daa38e
refactor: Cleanup
allozaur Sep 16, 2025
31ca791
refactor: Types cleanup
allozaur Sep 16, 2025
a247414
refactor: Cleanup
allozaur Sep 16, 2025
a9a493e
refactor: Cleanup
allozaur Sep 16, 2025
b368674
refactor: Enums folder
allozaur Sep 16, 2025
d91d350
chore: Remove code workspace file
allozaur Sep 16, 2025
7a47779
refactor: Cleanup
allozaur Sep 16, 2025
ca7d99d
Add resumable downloads for llama-server model loading
ericcurtin Sep 16, 2025
66305cc
fix: Remove unused import
allozaur Sep 16, 2025
606d3f8
Merge remote-tracking branch 'ggml-org/resumable' into allozaur/svelt…
allozaur Sep 17, 2025
b5d2f1e
Merge remote-tracking branch 'ggml-org/master' into allozaur/svelte-w…
allozaur Sep 17, 2025
e0187df
fix: Don't send empty system message in the `messages` array
allozaur Sep 17, 2025
5156706
Revert "Add resumable downloads for llama-server model loading"
allozaur Sep 17, 2025
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
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,11 @@ insert_final_newline = unset
[vendor/miniaudio/miniaudio.h]
trim_trailing_whitespace = unset
insert_final_newline = unset

[tools/server/webui/**]
indent_style = unset
indent_size = unset
end_of_line = unset
charset = unset
trim_trailing_whitespace = unset
insert_final_newline = unset
235 changes: 195 additions & 40 deletions .github/workflows/server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,51 +76,206 @@ jobs:
run: |
pip install -r tools/server/tests/requirements.txt
# Setup nodejs (to be used for verifying bundled index.html)
- uses: actions/setup-node@v4
webui-setup:
name: WebUI Setup
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
node-version: '22.11.0'
fetch-depth: 0
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}

- name: WebUI - Install dependencies
id: webui_lint
run: |
cd tools/server/webui
npm ci
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: "tools/server/webui/package-lock.json"

- name: Cache node_modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: tools/server/webui/node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('tools/server/webui/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-modules-
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
working-directory: tools/server/webui

webui-check:
needs: webui-setup
name: WebUI Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Restore node_modules cache
uses: actions/cache@v4
with:
path: tools/server/webui/node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('tools/server/webui/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-modules-
- name: Run type checking
run: npm run check
working-directory: tools/server/webui

- name: Run linting
run: npm run lint
working-directory: tools/server/webui

webui-build:
needs: webui-check
name: WebUI Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Restore node_modules cache
uses: actions/cache@v4
with:
path: tools/server/webui/node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('tools/server/webui/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-modules-
- name: Build application
run: npm run build
working-directory: tools/server/webui

webui-tests:
needs: webui-build
name: Run WebUI tests
permissions:
contents: read

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Restore node_modules cache
uses: actions/cache@v4
with:
path: tools/server/webui/node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('tools/server/webui/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-modules-
- name: Install Playwright browsers
run: npx playwright install --with-deps
working-directory: tools/server/webui

- name: Build Storybook
run: npm run build-storybook
working-directory: tools/server/webui

- name: Run Client tests
run: npm run test:client
working-directory: tools/server/webui

- name: WebUI - Check code format
id: webui_format
- name: Run Server tests
run: npm run test:server
working-directory: tools/server/webui

- name: Run UI tests
run: npm run test:ui
working-directory: tools/server/webui

- name: Run E2E tests
run: npm run test:e2e
working-directory: tools/server/webui

server-build:
needs: [webui-tests]
runs-on: ubuntu-latest

strategy:
matrix:
sanitizer: [ADDRESS, UNDEFINED] # THREAD is broken
build_type: [RelWithDebInfo]
include:
- build_type: Release
sanitizer: ""
fail-fast: false # While -DLLAMA_SANITIZE_THREAD=ON is broken

steps:
- name: Dependencies
id: depends
run: |
git config --global --add safe.directory $(realpath .)
cd tools/server/webui
git status
npm run format
git status
modified_files="$(git status -s)"
echo "Modified files: ${modified_files}"
if [ -n "${modified_files}" ]; then
echo "Files do not follow coding style. To fix: npm run format"
echo "${modified_files}"
exit 1
fi
- name: Verify bundled index.html
id: verify_server_index_html
sudo apt-get update
sudo apt-get -y install \
build-essential \
xxd \
git \
cmake \
curl \
wget \
language-pack-en \
libcurl4-openssl-dev
- name: Clone
id: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}

- name: Python setup
id: setup_python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Tests dependencies
id: test_dependencies
run: |
git config --global --add safe.directory $(realpath .)
cd tools/server/webui
git status
npm run build
git status
modified_files="$(git status -s)"
echo "Modified files: ${modified_files}"
if [ -n "${modified_files}" ]; then
echo "Repository is dirty or server/webui is not built as expected"
echo "Hint: You may need to follow Web UI build guide in server/README.md"
echo "${modified_files}"
exit 1
fi
pip install -r tools/server/tests/requirements.txt
- name: Setup Node.js for WebUI
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: "tools/server/webui/package-lock.json"

- name: Install WebUI dependencies
run: npm ci
working-directory: tools/server/webui

- name: Build WebUI
run: npm run build
working-directory: tools/server/webui

- name: Build (no OpenMP)
id: cmake_build_no_openmp
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,7 @@ poetry.toml
/run-vim.sh
/run-chat.sh
.ccache/

# Code Workspace
*.code-workspace

7 changes: 7 additions & 0 deletions .windsurf/rules/css-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
trigger: manual
---

#### Tailwind & CSS

- We are using Tailwind v4 which uses oklch colors so we now want to refer to the CSS vars directly, without wrapping it with any color function like `hsla/hsl`, `rgba` etc.
48 changes: 48 additions & 0 deletions .windsurf/rules/sveltekit-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
trigger: manual
---

# Coding rules

## Svelte & SvelteKit

### Services vs Stores Separation Pattern

#### `lib/services/` - Pure Business Logic

- **Purpose**: Stateless business logic and external communication
- **Contains**:
- API calls to external services (ApiService)
- Pure business logic functions (ChatService, etc.)
- **Rules**:
- NO Svelte runes ($state, $derived, $effect)
- NO reactive state management
- Pure functions and classes only
- Can import types but not stores
- Focus on "how" - implementation details

#### `lib/stores/` - Reactive State Management

- **Purpose**: Svelte-specific reactive state with runes
- **Contains**:
- Reactive state classes with $state, $derived, $effect
- Database operations (DatabaseStore)
- UI-focused state management
- Store orchestration logic
- **Rules**:
- USE Svelte runes for reactivity
- Import and use services for business logic
- NO direct database operations
- NO direct API calls (use services)
- Focus on "what" - reactive state for UI

#### Enforcement

- Services should be testable without Svelte
- Stores should leverage Svelte's reactivity system
- Clear separation: services handle data, stores handle state
- Services can be reused across multiple stores

#### Misc

- Always use `let` for $derived state variables
9 changes: 9 additions & 0 deletions .windsurf/rules/tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
trigger: manual
---

# Automated Tests

## General rules

- NEVER include any test code in the production code - we should always have it in a separate dedicated files
7 changes: 7 additions & 0 deletions .windsurf/rules/typescript-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
trigger: manual
---

## TypeScript

- Add JSDocs for functions
Binary file modified tools/server/public/index.html.gz
Binary file not shown.
36 changes: 36 additions & 0 deletions tools/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5261,6 +5261,42 @@ int main(int argc, char ** argv) {
svr->Get (params.api_prefix + "/slots", handle_slots);
svr->Post(params.api_prefix + "/slots/:id_slot", handle_slots_action);

// SPA fallback route - serve index.html for any route that doesn't match API endpoints
// This enables client-side routing for dynamic routes like /chat/[id]
if (params.webui && params.public_path.empty()) {
// Only add fallback when using embedded static files
svr->Get(".*", [](const httplib::Request & req, httplib::Response & res) {
// Skip API routes - they should have been handled above
if (req.path.find("/v1/") != std::string::npos ||
req.path.find("/health") != std::string::npos ||
req.path.find("/metrics") != std::string::npos ||
req.path.find("/props") != std::string::npos ||
req.path.find("/models") != std::string::npos ||
req.path.find("/api/tags") != std::string::npos ||
req.path.find("/completions") != std::string::npos ||
req.path.find("/chat/completions") != std::string::npos ||
req.path.find("/embeddings") != std::string::npos ||
req.path.find("/tokenize") != std::string::npos ||
req.path.find("/detokenize") != std::string::npos ||
req.path.find("/lora-adapters") != std::string::npos ||
req.path.find("/slots") != std::string::npos) {
return false; // Let other handlers process API routes
}

// Serve index.html for all other routes (SPA fallback)
if (req.get_header_value("Accept-Encoding").find("gzip") == std::string::npos) {
res.set_content("Error: gzip is not supported by this browser", "text/plain");
} else {
res.set_header("Content-Encoding", "gzip");
// COEP and COOP headers, required by pyodide (python interpreter)
res.set_header("Cross-Origin-Embedder-Policy", "require-corp");
res.set_header("Cross-Origin-Opener-Policy", "same-origin");
res.set_content(reinterpret_cast<const char*>(index_html_gz), index_html_gz_len, "text/html; charset=utf-8");
}
return false;
});
}

//
// Start the server
//
Expand Down
2 changes: 1 addition & 1 deletion tools/server/tests/unit/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_no_webui():
url = f"http://{server.server_host}:{server.server_port}"
res = requests.get(url)
assert res.status_code == 200
assert "<html>" in res.text
assert "<!doctype html>" in res.text
server.stop()

# with --no-webui
Expand Down
Loading
Loading