mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2026-05-16 19:59:16 +00:00
ui: Restructure repo to use tools/ui folder and ui / UI / llama-ui / LLAMA_UI naming (#23064)
* webui: Move static build output from `tools/server/public` to `build/ui` directory * refactor: Move to `tools/ui` * refactor: rename CMake variables and preprocessor defines - Rename LLAMA_BUILD_WEBUI -> LLAMA_BUILD_UI (old kept as deprecated) - Rename LLAMA_USE_PREBUILT_WEBUI -> LLAMA_USE_PREBUILT_UI (old kept as deprecated) - Backward compat: old vars auto-forward to new ones with DEPRECATION warning - Rename internal vars: WEBUI_SOURCE -> UI_SOURCE, WEBUI_SOURCE_DIR -> UI_SOURCE_DIR, etc. - Rename HF bucket: LLAMA_WEBUI_HF_BUCKET -> LLAMA_UI_HF_BUCKET - Emit both LLAMA_BUILD_WEBUI and LLAMA_BUILD_UI preprocessor defines - Emit both LLAMA_WEBUI_DEFAULT_ENABLED and LLAMA_UI_DEFAULT_ENABLED * refactor: rename CLI flags (--webui -> --ui) with backward compat - Add --ui/--no-ui (old --webui/--no-webui kept as deprecated aliases) - Add --ui-config (old --webui-config kept as deprecated alias) - Add --ui-config-file (old --webui-config-file kept as deprecated alias) - Add --ui-mcp-proxy/--no-ui-mcp-proxy (old --webui-mcp-proxy kept as deprecated) - Add new env vars: LLAMA_ARG_UI, LLAMA_ARG_UI_CONFIG, LLAMA_ARG_UI_CONFIG_FILE, LLAMA_ARG_UI_MCP_PROXY - C++ struct fields: params.ui, params.ui_config_json, params.ui_mcp_proxy added alongside old fields - Backward compat: old fields synced to new ones in g_params_to_internals * refactor: update C++ server internals with backward compat - Rename json_webui_settings -> json_ui_settings (both kept in server_context_meta) - Rename params.webui usage -> params.ui (both synced, old still works) - JSON API emits both "ui"/"ui_settings" and "webui"/"webui_settings" keys - Server routes use params.ui_mcp_proxy || params.webui_mcp_proxy - Preprocessor guards use #if defined(LLAMA_BUILD_UI) || defined(LLAMA_BUILD_WEBUI) * refactor: rename CI/CD workflows, artifacts, and build script - Rename webui-build.yml -> ui-build.yml; artifact webui-build -> ui-build - Rename webui-publish.yml -> ui-publish.yml; var HF_BUCKET_WEBUI_STATIC_OUTPUT -> HF_BUCKET_UI_STATIC_OUTPUT - Rename server-webui.yml -> server-ui.yml; job webui-build/checks -> ui-build/checks - Update server.yml: job/artifact refs webui-build -> ui-build - Update release.yml: all webui-build/publish refs -> ui-build/publish; HF_TOKEN_WEBUI_STATIC_OUTPUT -> HF_TOKEN_UI_STATIC_OUTPUT - Update server-self-hosted.yml: webui-build -> ui-build - Update build-self-hosted.yml: HF_WEBUI_VERSION -> HF_UI_VERSION - Rename webui-download.cmake -> ui-download.cmake (internal refs updated) - Update labeler.yml: server/webui -> server/ui path label * docs: update CODEOWNERS and server README docs - Update CODEOWNERS: team ggml-org/llama-webui -> ggml-org/llama-ui, path /tools/server/webui/ -> /tools/ui/ - Update server README.md: CLI tables show --ui flags with deprecated --webui aliases - Update server README-dev.md: "WebUI" -> "UI", paths updated to tools/ui/ * fix: Small fixes for UI build * fix: CMake.txt syntax * chore: Formatting * fix: `.editorconfig` for llama-ui * chore: Formatting * refactor: Use `APP_NAME` in Error route * refactor: Cleanup * refactor: Single migration service * make llama-ui a linkable target * fix: UI Build output * fix: Missing change * fix: separate llama-ui npm build output into build/tools/ui/dist subfolder + use cmake npm build instead of downloading ui-build.yml artifacts in CI * refactor: UI workflows cleanup --------- Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
This commit is contained in:
parent
49d1701bd2
commit
59778f0196
565 changed files with 1610 additions and 694 deletions
|
|
@ -45,7 +45,7 @@ insert_final_newline = unset
|
|||
trim_trailing_whitespace = unset
|
||||
insert_final_newline = unset
|
||||
|
||||
[tools/server/webui/**]
|
||||
[tools/ui/**]
|
||||
indent_style = unset
|
||||
indent_size = unset
|
||||
end_of_line = unset
|
||||
|
|
|
|||
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
|
|
@ -73,10 +73,10 @@ android:
|
|||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- examples/llama.android/**
|
||||
server/webui:
|
||||
server/ui:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- tools/server/webui/**
|
||||
- tools/ui/**
|
||||
server:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
|
|
|||
20
.github/workflows/build-self-hosted.yml
vendored
20
.github/workflows/build-self-hosted.yml
vendored
|
|
@ -68,6 +68,8 @@ jobs:
|
|||
- name: Determine tag name
|
||||
id: tag
|
||||
uses: ./.github/actions/get-tag-name
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
|
||||
ggml-ci-nvidia-cuda:
|
||||
needs: determine-tag
|
||||
|
|
@ -81,7 +83,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
nvidia-smi
|
||||
GG_BUILD_CUDA=1 bash ./ci/run.sh ~/results/llama.cpp /mnt/llama.cpp
|
||||
|
|
@ -98,7 +100,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
vulkaninfo --summary
|
||||
GG_BUILD_VULKAN=1 GGML_VK_DISABLE_COOPMAT2=1 bash ./ci/run.sh ~/results/llama.cpp /mnt/llama.cpp
|
||||
|
|
@ -115,7 +117,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
vulkaninfo --summary
|
||||
GG_BUILD_VULKAN=1 bash ./ci/run.sh ~/results/llama.cpp /mnt/llama.cpp
|
||||
|
|
@ -205,7 +207,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
GG_BUILD_METAL=1 bash ./ci/run.sh ~/results/llama.cpp ~/mnt/llama.cpp
|
||||
|
||||
|
|
@ -234,7 +236,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
GG_BUILD_WEBGPU=1 GG_BUILD_WEBGPU_DAWN_PREFIX="$GITHUB_WORKSPACE/dawn" \
|
||||
bash ./ci/run.sh ~/results/llama.cpp ~/mnt/llama.cpp
|
||||
|
|
@ -251,7 +253,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
vulkaninfo --summary
|
||||
GG_BUILD_VULKAN=1 bash ./ci/run.sh ~/results/llama.cpp ~/mnt/llama.cpp
|
||||
|
|
@ -270,7 +272,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
vulkaninfo --summary
|
||||
GG_BUILD_VULKAN=1 bash ./ci/run.sh ~/results/llama.cpp ~/mnt/llama.cpp
|
||||
|
|
@ -291,7 +293,7 @@ jobs:
|
|||
MSYSTEM: UCRT64
|
||||
CHERE_INVOKING: 1
|
||||
PATH: C:\msys64\ucrt64\bin;C:\msys64\usr\bin;C:\Windows\System32;${{ env.PATH }}
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
vulkaninfo --summary
|
||||
# Skip python related tests with GG_BUILD_LOW_PERF=1 since Windows MSYS2 UCRT64 currently fails to create
|
||||
|
|
@ -332,7 +334,7 @@ jobs:
|
|||
- name: Test
|
||||
id: ggml-ci
|
||||
env:
|
||||
HF_WEBUI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
HF_UI_VERSION: ${{ needs.determine-tag.outputs.tag_name }}
|
||||
run: |
|
||||
source ./openvino_toolkit/setupvars.sh
|
||||
GG_BUILD_OPENVINO=1 GGML_OPENVINO_DEVICE=GPU GG_BUILD_LOW_PERF=1 bash ./ci/run.sh ./tmp/results ./tmp/mnt
|
||||
|
|
|
|||
142
.github/workflows/release.yml
vendored
142
.github/workflows/release.yml
vendored
|
|
@ -36,13 +36,8 @@ env:
|
|||
CMAKE_ARGS: "-DLLAMA_BUILD_EXAMPLES=OFF -DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_TOOLS=ON -DLLAMA_BUILD_SERVER=ON -DGGML_RPC=ON"
|
||||
|
||||
jobs:
|
||||
webui-build:
|
||||
name: Build WebUI
|
||||
uses: ./.github/workflows/webui-build.yml
|
||||
|
||||
macOS-cpu:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
@ -71,11 +66,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -113,8 +109,6 @@ jobs:
|
|||
name: llama-bin-macos-${{ matrix.build }}.tar.gz
|
||||
|
||||
ubuntu-cpu:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
@ -135,11 +129,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
if: ${{ matrix.build != 's390x' }}
|
||||
|
|
@ -191,8 +186,6 @@ jobs:
|
|||
name: llama-bin-ubuntu-${{ matrix.build }}.tar.gz
|
||||
|
||||
ubuntu-vulkan:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
@ -211,11 +204,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -268,8 +262,6 @@ jobs:
|
|||
name: llama-bin-ubuntu-vulkan-${{ matrix.build }}.tar.gz
|
||||
|
||||
android-arm64:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
|
@ -283,11 +275,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -346,8 +339,6 @@ jobs:
|
|||
name: llama-bin-android-arm64.tar.gz
|
||||
|
||||
ubuntu-24-openvino:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
|
|
@ -370,11 +361,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -435,8 +427,6 @@ jobs:
|
|||
name: llama-bin-ubuntu-openvino-${{ env.OPENVINO_VERSION_MAJOR }}-x64.tar.gz
|
||||
|
||||
windows-cpu:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: windows-2025
|
||||
|
||||
|
|
@ -452,11 +442,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -496,8 +487,6 @@ jobs:
|
|||
name: llama-bin-win-cpu-${{ matrix.arch }}.zip
|
||||
|
||||
windows:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: windows-2025
|
||||
|
||||
|
|
@ -522,11 +511,12 @@ jobs:
|
|||
id: checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -587,8 +577,6 @@ jobs:
|
|||
name: llama-bin-win-${{ matrix.backend }}-${{ matrix.arch }}.zip
|
||||
|
||||
windows-cuda:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
|
|
@ -601,11 +589,12 @@ jobs:
|
|||
id: checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Install ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -667,8 +656,6 @@ jobs:
|
|||
name: cudart-llama-bin-win-cuda-${{ matrix.cuda }}-x64.zip
|
||||
|
||||
windows-sycl:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
|
|
@ -708,11 +695,12 @@ jobs:
|
|||
Expand-Archive -Path "level-zero-win-sdk.zip" -DestinationPath "C:/level-zero-sdk" -Force
|
||||
"LEVEL_ZERO_V1_SDK_PATH=C:/level-zero-sdk" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -781,8 +769,6 @@ jobs:
|
|||
name: llama-bin-win-sycl-x64.zip
|
||||
|
||||
ubuntu-24-sycl:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
|
@ -831,11 +817,12 @@ jobs:
|
|||
wget -q "https://github.com/oneapi-src/level-zero/releases/download/v${LEVEL_ZERO_VERSION}/level-zero-devel_${LEVEL_ZERO_VERSION}%2B${LEVEL_ZERO_UBUNTU_VERSION}_amd64.deb" -O level-zero-devel.deb
|
||||
sudo apt-get install -y ./level-zero.deb ./level-zero-devel.deb
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: ccache
|
||||
uses: ggml-org/ccache-action@v1.2.21
|
||||
|
|
@ -876,8 +863,6 @@ jobs:
|
|||
name: llama-bin-ubuntu-sycl-${{ matrix.build }}-x64.tar.gz
|
||||
|
||||
ubuntu-22-rocm:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
|
|
@ -895,11 +880,12 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Free up disk space
|
||||
uses: ggml-org/free-disk-space@v1.3.1
|
||||
|
|
@ -988,8 +974,6 @@ jobs:
|
|||
name: llama-bin-ubuntu-rocm-${{ env.ROCM_VERSION_SHORT }}-${{ matrix.build }}.tar.gz
|
||||
|
||||
windows-hip:
|
||||
needs:
|
||||
- webui-build
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
|
|
@ -1007,11 +991,12 @@ jobs:
|
|||
id: checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Grab rocWMMA package
|
||||
id: grab_rocwmma
|
||||
|
|
@ -1259,7 +1244,6 @@ jobs:
|
|||
runs-on: ubuntu-slim
|
||||
|
||||
needs:
|
||||
- webui-build
|
||||
- windows
|
||||
- windows-cpu
|
||||
- windows-cuda
|
||||
|
|
@ -1404,14 +1388,14 @@ jobs:
|
|||
}
|
||||
}
|
||||
|
||||
webui-publish:
|
||||
ui-publish:
|
||||
if: ${{ ( github.event_name == 'push' && github.ref == 'refs/heads/master' ) || github.event.inputs.create_release == 'true' }}
|
||||
|
||||
needs:
|
||||
- release
|
||||
|
||||
uses: ./.github/workflows/webui-publish.yml
|
||||
uses: ./.github/workflows/ui-publish.yml
|
||||
with:
|
||||
version_tag: ${{ needs.release.outputs.tag_name }}
|
||||
secrets:
|
||||
hf_token: ${{ secrets.HF_TOKEN_WEBUI_STATIC_OUTPUT }}
|
||||
hf_token: ${{ secrets.HF_TOKEN_UI_STATIC_OUTPUT }}
|
||||
|
|
|
|||
7
.github/workflows/server-sanitize.yml
vendored
7
.github/workflows/server-sanitize.yml
vendored
|
|
@ -67,6 +67,13 @@ jobs:
|
|||
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@v6
|
||||
with:
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
run: |
|
||||
|
|
|
|||
14
.github/workflows/server-self-hosted.yml
vendored
14
.github/workflows/server-self-hosted.yml
vendored
|
|
@ -39,12 +39,7 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
webui-build:
|
||||
name: Build WebUI
|
||||
uses: ./.github/workflows/webui-build.yml
|
||||
|
||||
server-metal:
|
||||
needs: webui-build
|
||||
runs-on: [self-hosted, llama-server, macOS, ARM64]
|
||||
|
||||
name: server-metal (${{ matrix.wf_name }})
|
||||
|
|
@ -72,11 +67,12 @@ jobs:
|
|||
fetch-depth: 0
|
||||
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
|
|
|
|||
22
.github/workflows/server.yml
vendored
22
.github/workflows/server.yml
vendored
|
|
@ -54,12 +54,7 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
webui-build:
|
||||
name: Build WebUI
|
||||
uses: ./.github/workflows/webui-build.yml
|
||||
|
||||
server:
|
||||
needs: webui-build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
name: server (${{ matrix.wf_name }})
|
||||
|
|
@ -98,11 +93,12 @@ jobs:
|
|||
fetch-depth: 0
|
||||
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
|
|
@ -136,7 +132,6 @@ jobs:
|
|||
SLOW_TESTS=1 pytest -v -x
|
||||
|
||||
server-windows:
|
||||
needs: webui-build
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
|
|
@ -147,11 +142,10 @@ jobs:
|
|||
fetch-depth: 0
|
||||
ref: ${{ github.event.inputs.sha || github.event.pull_request.head.sha || github.sha || github.head_ref || github.ref_name }}
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
node-version: "24"
|
||||
|
||||
- name: Build
|
||||
id: cmake_build
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
name: Build WebUI
|
||||
name: UI Build
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build WebUI
|
||||
name: Build static output
|
||||
runs-on: ubuntu-slim
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
|
|
@ -19,26 +19,26 @@ jobs:
|
|||
with:
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/server/webui/package-lock.json"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Build application
|
||||
run: npm run build
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
cd tools/server/public
|
||||
cd build/tools/ui/dist
|
||||
for f in *; do
|
||||
sha256sum "$f" | awk '{print $1, $2}' >> checksums.txt
|
||||
done
|
||||
|
||||
- name: Upload built webui
|
||||
- name: Upload built UI
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
name: ui-build
|
||||
path: build/tools/ui/dist/
|
||||
retention-days: 1
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name: Server WebUI
|
||||
name: CI (UI)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
|
@ -11,15 +11,15 @@ on:
|
|||
branches:
|
||||
- master
|
||||
paths: [
|
||||
'.github/workflows/server-webui.yml',
|
||||
'tools/server/webui/**.*',
|
||||
'.github/workflows/ui-ci.yml',
|
||||
'tools/ui/**.*',
|
||||
'tools/server/tests/**.*'
|
||||
]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths: [
|
||||
'.github/workflows/server-webui.yml',
|
||||
'tools/server/webui/**.*',
|
||||
'.github/workflows/ui-ci.yml',
|
||||
'tools/ui/**.*',
|
||||
'tools/server/tests/**.*'
|
||||
]
|
||||
|
||||
|
|
@ -34,13 +34,13 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
webui-build:
|
||||
name: Build WebUI
|
||||
uses: ./.github/workflows/webui-build.yml
|
||||
ui-build:
|
||||
name: Build static output
|
||||
uses: ./.github/workflows/ui-build.yml
|
||||
|
||||
webui-checks:
|
||||
name: WebUI Checks
|
||||
needs: webui-build
|
||||
ui-checks:
|
||||
name: UI Checks
|
||||
needs: ui-build
|
||||
runs-on: ubuntu-24.04-arm
|
||||
continue-on-error: true
|
||||
steps:
|
||||
|
|
@ -56,43 +56,43 @@ jobs:
|
|||
with:
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/server/webui/package-lock.json"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Install dependencies
|
||||
id: setup
|
||||
if: ${{ steps.node.conclusion == 'success' }}
|
||||
run: npm ci
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run type checking
|
||||
if: ${{ always() && steps.setup.conclusion == 'success' }}
|
||||
run: npm run check
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run linting
|
||||
if: ${{ always() && steps.setup.conclusion == 'success' }}
|
||||
run: npm run lint
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Install Playwright browsers
|
||||
id: playwright
|
||||
if: ${{ always() && steps.setup.conclusion == 'success' }}
|
||||
run: npx playwright install --with-deps
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run Client tests
|
||||
if: ${{ always() && steps.playwright.conclusion == 'success' }}
|
||||
run: npm run test:client
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run Unit tests
|
||||
if: ${{ always() && steps.playwright.conclusion == 'success' }}
|
||||
run: npm run test:unit
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
e2e-tests:
|
||||
name: E2E Tests
|
||||
needs: webui-build
|
||||
needs: ui-build
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
@ -107,36 +107,36 @@ jobs:
|
|||
with:
|
||||
node-version: "24"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "tools/server/webui/package-lock.json"
|
||||
cache-dependency-path: "tools/ui/package-lock.json"
|
||||
|
||||
- name: Install dependencies
|
||||
id: setup
|
||||
if: ${{ steps.node.conclusion == 'success' }}
|
||||
run: npm ci
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Build application
|
||||
if: ${{ always() && steps.setup.conclusion == 'success' }}
|
||||
run: npm run build
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Install Playwright browsers
|
||||
id: playwright
|
||||
if: ${{ always() && steps.setup.conclusion == 'success' }}
|
||||
run: npx playwright install --with-deps
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Build Storybook
|
||||
if: ${{ always() && steps.playwright.conclusion == 'success' }}
|
||||
run: npm run build-storybook
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run UI tests
|
||||
if: ${{ always() && steps.playwright.conclusion == 'success' }}
|
||||
run: npm run test:ui -- --testTimeout=60000
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
||||
- name: Run E2E tests
|
||||
if: ${{ always() && steps.playwright.conclusion == 'success' }}
|
||||
run: npm run test:e2e
|
||||
working-directory: tools/server/webui
|
||||
working-directory: tools/ui
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
name: WebUI Publish
|
||||
name: UI Publish
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
|
@ -14,14 +14,14 @@ on:
|
|||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish WebUI Static Output
|
||||
name: Publish UI Static Output
|
||||
runs-on: ubuntu-24.04-arm
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
HF_BUCKET_NAME: ${{ vars.HF_BUCKET_WEBUI_STATIC_OUTPUT }}
|
||||
HF_BUCKET_NAME: ${{ vars.HF_BUCKET_UI_STATIC_OUTPUT }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
@ -29,11 +29,11 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Download WebUI build artifact
|
||||
- name: Download UI build artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: webui-build
|
||||
path: tools/server/public/
|
||||
name: ui-build
|
||||
path: build/tools/ui/dist/
|
||||
|
||||
- name: Install Hugging Face Hub CLI
|
||||
run: pip install -U huggingface_hub
|
||||
|
|
@ -44,12 +44,12 @@ jobs:
|
|||
- name: Sync built files to Hugging Face bucket (version tag)
|
||||
run: |
|
||||
# Upload the built files to the Hugging Face bucket under the release version
|
||||
hf buckets sync tools/server/public hf://buckets/ggml-org/${{ env.HF_BUCKET_NAME }}/${{ inputs.version_tag }} --delete --quiet
|
||||
hf buckets sync build/tools/ui/dist hf://buckets/ggml-org/${{ env.HF_BUCKET_NAME }}/${{ inputs.version_tag }} --delete --quiet
|
||||
|
||||
- name: Sync built files to Hugging Face bucket (latest)
|
||||
run: |
|
||||
# Also upload to the 'latest' directory for fallback downloads
|
||||
hf buckets sync tools/server/public hf://buckets/ggml-org/${{ env.HF_BUCKET_NAME }}/latest --delete --quiet
|
||||
hf buckets sync build/tools/ui/dist hf://buckets/ggml-org/${{ env.HF_BUCKET_NAME }}/latest --delete --quiet
|
||||
|
||||
- name: Verify upload
|
||||
run: |
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -54,7 +54,6 @@
|
|||
/tmp/
|
||||
/autogen-*.md
|
||||
/common/build-info.cpp
|
||||
/tools/server/public
|
||||
|
||||
# Deprecated
|
||||
|
||||
|
|
@ -93,10 +92,12 @@
|
|||
!/examples/sycl/*.bat
|
||||
!/examples/sycl/*.sh
|
||||
|
||||
# Server Web UI temporary files
|
||||
# Server Web UI temporary files (+ legacy directory)
|
||||
|
||||
/tools/server/webui/node_modules
|
||||
/tools/server/webui/dist
|
||||
/tools/ui/node_modules
|
||||
/tools/ui/dist
|
||||
|
||||
# Python
|
||||
|
||||
|
|
|
|||
|
|
@ -108,8 +108,23 @@ option(LLAMA_BUILD_TESTS "llama: build tests"
|
|||
option(LLAMA_BUILD_TOOLS "llama: build tools" ${LLAMA_STANDALONE})
|
||||
option(LLAMA_BUILD_EXAMPLES "llama: build examples" ${LLAMA_STANDALONE})
|
||||
option(LLAMA_BUILD_SERVER "llama: build server example" ${LLAMA_STANDALONE})
|
||||
option(LLAMA_BUILD_WEBUI "llama: build the embedded Web UI for server" ON)
|
||||
option(LLAMA_USE_PREBUILT_WEBUI "llama: use prebuilt WebUI from HF Bucket when available (requires LLAMA_BUILD_WEBUI=ON)" ON)
|
||||
# Deprecated: use LLAMA_BUILD_UI instead (kept for backward compat)
|
||||
option(LLAMA_BUILD_WEBUI "llama: build the embedded Web UI for server (deprecated: use LLAMA_BUILD_UI)" ON)
|
||||
option(LLAMA_USE_PREBUILT_WEBUI "llama: use prebuilt WebUI from HF Bucket when available (deprecated: use LLAMA_USE_PREBUILT_UI)" ON)
|
||||
|
||||
# New option names
|
||||
option(LLAMA_BUILD_UI "llama: build the embedded Web UI for server" ON)
|
||||
option(LLAMA_USE_PREBUILT_UI "llama: use prebuilt UI from HF Bucket when available (requires LLAMA_BUILD_UI=ON)" ON)
|
||||
|
||||
# Backward compat: when old var is set but new one isn't, forward the value
|
||||
if(DEFINED LLAMA_BUILD_WEBUI AND NOT DEFINED LLAMA_BUILD_UI)
|
||||
set(LLAMA_BUILD_UI ${LLAMA_BUILD_WEBUI})
|
||||
message(DEPRECATION "LLAMA_BUILD_WEBUI is deprecated, use LLAMA_BUILD_UI instead")
|
||||
endif()
|
||||
if(DEFINED LLAMA_USE_PREBUILT_WEBUI AND NOT DEFINED LLAMA_USE_PREBUILT_UI)
|
||||
set(LLAMA_USE_PREBUILT_UI ${LLAMA_USE_PREBUILT_WEBUI})
|
||||
message(DEPRECATION "LLAMA_USE_PREBUILT_WEBUI is deprecated, use LLAMA_USE_PREBUILT_UI instead")
|
||||
endif()
|
||||
option(LLAMA_TOOLS_INSTALL "llama: install tools" ${LLAMA_TOOLS_INSTALL_DEFAULT})
|
||||
option(LLAMA_TESTS_INSTALL "llama: install tests" ON)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# ggml-org/llama-common : ggerganov, aldehir, angt, danbev, ngxson, pwilkin
|
||||
# ggml-org/llama-mtmd : ngxson
|
||||
# ggml-org/llama-server : ggerganov, ngxson, allozaur, angt, ServeurpersoCom
|
||||
# ggml-org/llama-webui : allozaur
|
||||
# ggml-org/llama-ui : allozaur
|
||||
|
||||
/.devops/*.Dockerfile @ngxson
|
||||
/.github/actions/ @ggml-org/ci
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
/tools/rpc/ @ggml-org/ggml-rpc
|
||||
/tools/server/* @ggml-org/llama-server # no subdir
|
||||
/tools/server/tests/ @ggml-org/llama-server
|
||||
/tools/server/webui/ @ggml-org/llama-webui
|
||||
/tools/ui/ @ggml-org/llama-ui
|
||||
/tools/tokenize/ @ggerganov
|
||||
/tools/tts/ @ggerganov
|
||||
/vendor/ @ggerganov
|
||||
|
|
|
|||
|
|
@ -2844,28 +2844,64 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
|||
params.api_prefix = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_API_PREFIX"));
|
||||
// Deprecated: use --ui-config instead (kept for backward compat)
|
||||
add_opt(common_arg(
|
||||
{"--webui-config"}, "JSON",
|
||||
"JSON that provides default WebUI settings (overrides WebUI defaults)",
|
||||
"[DEPRECATED: use --ui-config] JSON that provides default WebUI settings (overrides WebUI defaults)",
|
||||
[](common_params & params, const std::string & value) {
|
||||
params.ui_config_json = value;
|
||||
params.webui_config_json = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_WEBUI_CONFIG"));
|
||||
|
||||
add_opt(common_arg(
|
||||
{"--ui-config"}, "JSON",
|
||||
"JSON that provides default UI settings (overrides UI defaults)",
|
||||
[](common_params & params, const std::string & value) {
|
||||
params.ui_config_json = value;
|
||||
params.webui_config_json = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_UI_CONFIG"));
|
||||
|
||||
// Deprecated: use --ui-config-file instead (kept for backward compat)
|
||||
add_opt(common_arg(
|
||||
{"--webui-config-file"}, "PATH",
|
||||
"JSON file that provides default WebUI settings (overrides WebUI defaults)",
|
||||
"[DEPRECATED: use --ui-config-file] JSON file that provides default WebUI settings (overrides WebUI defaults)",
|
||||
[](common_params & params, const std::string & value) {
|
||||
params.webui_config_json = read_file(value);
|
||||
params.ui_config_json = read_file(value);
|
||||
params.webui_config_json = params.ui_config_json;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_WEBUI_CONFIG_FILE"));
|
||||
|
||||
add_opt(common_arg(
|
||||
{"--ui-config-file"}, "PATH",
|
||||
"JSON file that provides default UI settings (overrides UI defaults)",
|
||||
[](common_params & params, const std::string & value) {
|
||||
params.ui_config_json = read_file(value);
|
||||
params.webui_config_json = params.ui_config_json;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_UI_CONFIG_FILE"));
|
||||
|
||||
// Deprecated: use --ui-mcp-proxy instead (kept for backward compat)
|
||||
add_opt(common_arg(
|
||||
{"--webui-mcp-proxy"},
|
||||
{"--no-webui-mcp-proxy"},
|
||||
string_format("experimental: whether to enable MCP CORS proxy - do not enable in untrusted environments (default: %s)", params.webui_mcp_proxy ? "enabled" : "disabled"),
|
||||
"[DEPRECATED: use --ui-mcp-proxy/--no-ui-mcp-proxy] experimental: whether to enable MCP CORS proxy",
|
||||
[](common_params & params, bool value) {
|
||||
params.ui_mcp_proxy = value;
|
||||
params.webui_mcp_proxy = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_WEBUI_MCP_PROXY"));
|
||||
|
||||
add_opt(common_arg(
|
||||
{"--ui-mcp-proxy"},
|
||||
{"--no-ui-mcp-proxy"},
|
||||
"experimental: whether to enable MCP CORS proxy - do not enable in untrusted environments (default: disabled)",
|
||||
[](common_params & params, bool value) {
|
||||
params.ui_mcp_proxy = value;
|
||||
params.webui_mcp_proxy = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_UI_MCP_PROXY"));
|
||||
add_opt(common_arg(
|
||||
{"--tools"}, "TOOL1,TOOL2,...",
|
||||
"experimental: whether to enable built-in tools for AI agents - do not enable in untrusted environments (default: no tools)\n"
|
||||
|
|
@ -2875,14 +2911,26 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
|
|||
params.server_tools = parse_csv_row(value);
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_TOOLS"));
|
||||
// Deprecated: use --ui/--no-ui instead (kept for backward compat)
|
||||
add_opt(common_arg(
|
||||
{"--webui"},
|
||||
{"--no-webui"},
|
||||
string_format("whether to enable the Web UI (default: %s)", params.webui ? "enabled" : "disabled"),
|
||||
"[DEPRECATED: use --ui/--no-ui] whether to enable the Web UI",
|
||||
[](common_params & params, bool value) {
|
||||
params.ui = value;
|
||||
params.webui = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_WEBUI"));
|
||||
|
||||
add_opt(common_arg(
|
||||
{"--ui"},
|
||||
{"--no-ui"},
|
||||
string_format("whether to enable the Web UI (default: %s)", params.ui ? "enabled" : "disabled"),
|
||||
[](common_params & params, bool value) {
|
||||
params.ui = value;
|
||||
params.webui = value;
|
||||
}
|
||||
).set_examples({LLAMA_EXAMPLE_SERVER}).set_env("LLAMA_ARG_UI"));
|
||||
add_opt(common_arg(
|
||||
{"--embedding", "--embeddings"},
|
||||
string_format("restrict to only support embedding use case; use only with dedicated embedding models (default: %s)", params.embedding ? "enabled" : "disabled"),
|
||||
|
|
|
|||
|
|
@ -604,15 +604,23 @@ struct common_params {
|
|||
|
||||
std::map<std::string, std::string> default_template_kwargs;
|
||||
|
||||
// webui configs
|
||||
#ifdef LLAMA_WEBUI_DEFAULT_ENABLED
|
||||
bool webui = LLAMA_WEBUI_DEFAULT_ENABLED != 0;
|
||||
// UI configs
|
||||
#ifdef LLAMA_UI_DEFAULT_ENABLED
|
||||
bool ui = LLAMA_UI_DEFAULT_ENABLED != 0;
|
||||
#elif defined(LLAMA_WEBUI_DEFAULT_ENABLED)
|
||||
bool ui = LLAMA_WEBUI_DEFAULT_ENABLED != 0;
|
||||
#else
|
||||
bool webui = true; // default to enabled when not set
|
||||
bool ui = true; // default to enabled when not set
|
||||
#endif
|
||||
|
||||
// Deprecated: use ui, ui_mcp_proxy, ui_config_json instead
|
||||
bool webui = ui;
|
||||
bool webui_mcp_proxy = false;
|
||||
std::string webui_config_json;
|
||||
|
||||
bool ui_mcp_proxy = false;
|
||||
std::string ui_config_json;
|
||||
|
||||
// "advanced" endpoints are disabled by default for better security
|
||||
bool endpoint_slots = true;
|
||||
bool endpoint_props = false; // only control POST requests, not GET
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Download webui assets from Hugging Face Bucket at build time
|
||||
# Usage: cmake -DPUBLIC_DIR=... -DHF_BUCKET=... -DHF_VERSION=... -DASSETS="a;b;c" -P scripts/webui-download.cmake
|
||||
# Download UI assets from Hugging Face Bucket at build time
|
||||
# Usage: cmake -DPUBLIC_DIR=... -DHF_BUCKET=... -DHF_VERSION=... -DASSETS="a;b;c" -P scripts/ui-download.cmake
|
||||
#
|
||||
# Asset provisioning priority:
|
||||
# 1. Pre-built assets already in PUBLIC_DIR (cached from a previous run)
|
||||
|
|
@ -14,7 +14,7 @@ set(HF_VERSION "" CACHE STRING "Version to download (empty = resolve from git)
|
|||
set(ASSETS "" CACHE STRING "Plus-separated list of asset filenames (+)")
|
||||
set(STAMP_FILE "" CACHE STRING "Stamp file to create on success (optional)")
|
||||
set(SOURCE_DIR "" CACHE STRING "Project source root (to resolve version from git)")
|
||||
set(NPM_DIR "" CACHE STRING "WebUI source directory (to run npm build)")
|
||||
set(NPM_DIR "" CACHE STRING "UI source directory (to run npm build)")
|
||||
set(HF_ENABLED "" CACHE STRING "Whether to allow HF Bucket download (ON/OFF)")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -25,8 +25,8 @@ if("${RESOLVED_VERSION}" STREQUAL "" AND NOT "${SOURCE_DIR}" STREQUAL "")
|
|||
if(EXISTS "${SOURCE_DIR}/cmake/build-info.cmake")
|
||||
include("${SOURCE_DIR}/cmake/build-info.cmake")
|
||||
if(NOT "${BUILD_NUMBER}" STREQUAL "" AND NOT BUILD_NUMBER EQUAL 0)
|
||||
set(RESOLVED_VERSION "${BUILD_NUMBER}")
|
||||
message(STATUS "WebUI: resolved version from git: ${RESOLVED_VERSION}")
|
||||
set(RESOLVED_VERSION "b${BUILD_NUMBER}")
|
||||
message(STATUS "UI: resolved version from git: ${RESOLVED_VERSION}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -43,7 +43,7 @@ if(NOT "${STAMP_FILE}" STREQUAL "" AND EXISTS "${STAMP_FILE}")
|
|||
file(READ "${STAMP_FILE}" STAMPED_VERSION)
|
||||
string(STRIP "${STAMPED_VERSION}" STAMPED_VERSION)
|
||||
if(NOT "${STAMPED_VERSION}" STREQUAL "${RESOLVED_VERSION}")
|
||||
message(STATUS "WebUI: version changed (${STAMPED_VERSION} -> ${RESOLVED_VERSION}), re-building")
|
||||
message(STATUS "UI: version changed (${STAMPED_VERSION} -> ${RESOLVED_VERSION}), re-building")
|
||||
set(FORCE_REBUILD TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -60,7 +60,7 @@ foreach(asset ${ASSETS})
|
|||
endforeach()
|
||||
|
||||
if(ALL_EXISTS AND NOT FORCE_REBUILD)
|
||||
message(STATUS "WebUI: all assets already exist in ${PUBLIC_DIR}, skipping")
|
||||
message(STATUS "UI: all assets already exist in ${PUBLIC_DIR}, skipping")
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
|
@ -76,27 +76,27 @@ if(NOT PROVISION_SUCCESS AND NOT "${NPM_DIR}" STREQUAL "")
|
|||
# Check if npm is available before attempting npm build
|
||||
find_program(NPM_EXECUTABLE npm)
|
||||
if(NPM_EXECUTABLE)
|
||||
message(STATUS "WebUI: building from source in ${NPM_DIR}")
|
||||
message(STATUS "UI: building from source in ${NPM_DIR}")
|
||||
|
||||
# Run npm install if node_modules is missing
|
||||
if(NOT EXISTS "${NPM_DIR}/node_modules")
|
||||
message(STATUS "WebUI: running npm install (first time)")
|
||||
message(STATUS "UI: running npm install (first time)")
|
||||
execute_process(
|
||||
COMMAND npm install
|
||||
COMMAND ${NPM_EXECUTABLE} install
|
||||
WORKING_DIRECTORY "${NPM_DIR}"
|
||||
RESULT_VARIABLE NPM_INSTALL_RESULT
|
||||
OUTPUT_VARIABLE NPM_OUT
|
||||
ERROR_VARIABLE NPM_ERR
|
||||
)
|
||||
if(NOT NPM_INSTALL_RESULT EQUAL 0)
|
||||
message(STATUS "WebUI: npm install failed (${NPM_INSTALL_RESULT}), falling back to download")
|
||||
message(STATUS "UI: npm install failed (${NPM_INSTALL_RESULT}), falling back to download")
|
||||
message(STATUS " stderr: ${NPM_ERR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Run the build
|
||||
execute_process(
|
||||
COMMAND npm run build
|
||||
COMMAND ${NPM_EXECUTABLE} run build
|
||||
WORKING_DIRECTORY "${NPM_DIR}"
|
||||
RESULT_VARIABLE NPM_BUILD_RESULT
|
||||
OUTPUT_VARIABLE NPM_OUT
|
||||
|
|
@ -114,20 +114,20 @@ if(NOT PROVISION_SUCCESS AND NOT "${NPM_DIR}" STREQUAL "")
|
|||
endforeach()
|
||||
|
||||
if(ALL_BUILT)
|
||||
message(STATUS "WebUI: local npm build succeeded")
|
||||
message(STATUS "UI: local npm build succeeded")
|
||||
set(PROVISION_SUCCESS TRUE)
|
||||
else()
|
||||
message(STATUS "WebUI: npm build completed but assets missing from ${PUBLIC_DIR}, falling back to download")
|
||||
message(STATUS "UI: npm build completed but assets missing from ${PUBLIC_DIR}, falling back to download")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "WebUI: npm build failed (${NPM_BUILD_RESULT}), falling back to download")
|
||||
message(STATUS "UI: npm build failed (${NPM_BUILD_RESULT}), falling back to download")
|
||||
message(STATUS " stderr: ${NPM_ERR}")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "WebUI: npm not found, skipping npm build and trying HF Bucket download")
|
||||
message(STATUS "UI: npm not found, skipping npm build and trying HF Bucket download")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "WebUI: NPM_DIR (${NPM_DIR}) has no package.json, skipping npm build")
|
||||
message(STATUS "UI: NPM_DIR (${NPM_DIR}) has no package.json, skipping npm build")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ if(NOT PROVISION_SUCCESS AND HF_ENABLED)
|
|||
string(REGEX REPLACE "^([^:]+):.*$" "\\1" url_label "${entry}")
|
||||
string(REGEX REPLACE "^[^:]+:(.*)$" "\\1" base_url "${entry}")
|
||||
|
||||
message(STATUS "WebUI: downloading assets from ${url_label}: ${base_url}")
|
||||
message(STATUS "UI: downloading assets from ${url_label}: ${base_url}")
|
||||
|
||||
# Download each asset
|
||||
set(ALL_OK TRUE)
|
||||
|
|
@ -161,11 +161,11 @@ if(NOT PROVISION_SUCCESS AND HF_ENABLED)
|
|||
list(GET download_status 0 download_result)
|
||||
if(NOT download_result EQUAL 0)
|
||||
list(GET download_status 1 error_message)
|
||||
message(STATUS "WebUI: failed to download ${asset} from ${url_label}: ${error_message}")
|
||||
message(STATUS "UI: failed to download ${asset} from ${url_label}: ${error_message}")
|
||||
set(ALL_OK FALSE)
|
||||
break()
|
||||
endif()
|
||||
message(STATUS "WebUI: downloaded ${asset}")
|
||||
message(STATUS "UI: downloaded ${asset}")
|
||||
endforeach()
|
||||
|
||||
if(NOT ALL_OK)
|
||||
|
|
@ -179,7 +179,7 @@ if(NOT PROVISION_SUCCESS AND HF_ENABLED)
|
|||
)
|
||||
list(GET checksum_status 0 checksum_result)
|
||||
if(checksum_result EQUAL 0)
|
||||
message(STATUS "WebUI: verifying checksums...")
|
||||
message(STATUS "UI: verifying checksums...")
|
||||
file(STRINGS "${PUBLIC_DIR}/checksums.txt" CHECKSUMS_CONTENT)
|
||||
foreach(asset ${ASSETS})
|
||||
set(download_path "${PUBLIC_DIR}/${asset}")
|
||||
|
|
@ -187,12 +187,13 @@ if(NOT PROVISION_SUCCESS AND HF_ENABLED)
|
|||
string(TOLOWER "${asset_hash}" EXPECTED_HASH_LOWER)
|
||||
string(REGEX MATCH "${EXPECTED_HASH_LOWER}[ \\t]+${asset}" CHECKSUM_LINE "${CHECKSUMS_CONTENT}")
|
||||
if(NOT CHECKSUM_LINE)
|
||||
message(WARNING "WebUI: checksum verification failed for ${asset}")
|
||||
message(WARNING " downloaded file may not match expected checksum, but will be used")
|
||||
message(WARNING "UI: checksum verification failed for ${asset}")
|
||||
set(ALL_OK FALSE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if(ALL_OK)
|
||||
message(STATUS "WebUI: all checksums verified")
|
||||
message(STATUS "UI: all checksums verified")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -203,9 +204,9 @@ if(NOT PROVISION_SUCCESS AND HF_ENABLED)
|
|||
endforeach()
|
||||
|
||||
if(PROVISION_SUCCESS)
|
||||
message(STATUS "WebUI: provisioning complete")
|
||||
message(STATUS "UI: provisioning complete")
|
||||
else()
|
||||
message(WARNING "WebUI: failed to download assets from HF Bucket (${HF_BUCKET})")
|
||||
message(WARNING "UI: failed to download assets from HF Bucket (${HF_BUCKET})")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -217,6 +218,6 @@ if(PROVISION_SUCCESS)
|
|||
file(WRITE "${STAMP_FILE}" "${RESOLVED_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "WebUI: no source available. Neither local build (${NPM_DIR}) nor HF Bucket download succeeded.")
|
||||
message(WARNING "WebUI: building server without embedded WebUI. Set LLAMA_BUILD_WEBUI=OFF to suppress this warning.")
|
||||
message(WARNING "UI: no source available. Neither local build (${NPM_DIR}) nor HF Bucket download succeeded.")
|
||||
message(WARNING "UI: building server without embedded UI. Set LLAMA_BUILD_UI=OFF to suppress this warning.")
|
||||
endif()
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# CMake equivalent of `xxd -i ${INPUT} ${OUTPUT}`
|
||||
# Usage: cmake -DINPUT=tools/server/public/index.html -DOUTPUT=tools/server/index.html.hpp -P scripts/xxd.cmake
|
||||
# Usage: cmake -DINPUT=build/tools/ui/dist/index.html -DOUTPUT=build/tools/ui/dist/index.html.hpp -P scripts/xxd.cmake
|
||||
|
||||
SET(INPUT "" CACHE STRING "Input File")
|
||||
SET(OUTPUT "" CACHE STRING "Output File")
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ else()
|
|||
add_subdirectory(perplexity)
|
||||
add_subdirectory(quantize)
|
||||
if (LLAMA_BUILD_SERVER)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(cli)
|
||||
add_subdirectory(server)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -40,136 +40,11 @@ set(TARGET_SRCS
|
|||
server-models.h
|
||||
)
|
||||
|
||||
# Option to specify custom HF bucket for webui (defaults to llama-ui)
|
||||
# Usage: cmake -B build -DLLAMA_WEBUI_HF_BUCKET=llama-ui
|
||||
set(LLAMA_WEBUI_HF_BUCKET "llama-ui" CACHE STRING "Hugging Face bucket name for prebuilt webui assets")
|
||||
|
||||
if (LLAMA_BUILD_WEBUI)
|
||||
set(PUBLIC_ASSETS
|
||||
index.html
|
||||
bundle.js
|
||||
bundle.css
|
||||
loading.html
|
||||
)
|
||||
|
||||
# Determine source of webui assets (priority: local > HF Bucket)
|
||||
set(WEBUI_SOURCE "")
|
||||
set(WEBUI_SOURCE_DIR "")
|
||||
|
||||
# Priority 1: Check for local webui build output
|
||||
set(LOCAL_WEBUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/public")
|
||||
|
||||
# Verify all required assets exist before declaring local source valid
|
||||
set(ALL_ASSETS_PRESENT TRUE)
|
||||
foreach(asset ${PUBLIC_ASSETS})
|
||||
if(NOT EXISTS "${LOCAL_WEBUI_DIR}/${asset}")
|
||||
set(ALL_ASSETS_PRESENT FALSE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(ALL_ASSETS_PRESENT)
|
||||
set(WEBUI_SOURCE "local")
|
||||
set(WEBUI_SOURCE_DIR "${LOCAL_WEBUI_DIR}")
|
||||
message(STATUS "WebUI: using local build from ${WEBUI_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
# Priority 2: Build-time asset provisioning (npm build → HF Bucket fallback)
|
||||
if(NOT WEBUI_SOURCE_DIR)
|
||||
# Environment variable takes precedence (e.g., from CI workflows)
|
||||
if(DEFINED ENV{HF_WEBUI_VERSION})
|
||||
set(HF_WEBUI_VERSION "$ENV{HF_WEBUI_VERSION}")
|
||||
# Validate against allowed characters to prevent CMake list separator
|
||||
# or path-traversal issues in stamp filenames and download URLs
|
||||
if(NOT HF_WEBUI_VERSION MATCHES "^[A-Za-z0-9._-]+$")
|
||||
message(FATAL_ERROR "WebUI: invalid HF_WEBUI_VERSION='${HF_WEBUI_VERSION}' - must match ^[A-Za-z0-9._-]+$")
|
||||
endif()
|
||||
message(STATUS "WebUI: using HF_WEBUI_VERSION from environment=${HF_WEBUI_VERSION}")
|
||||
elseif(DEFINED LLAMA_BUILD_NUMBER)
|
||||
set(HF_WEBUI_VERSION "b${LLAMA_BUILD_NUMBER}")
|
||||
message(STATUS "WebUI: using LLAMA_BUILD_NUMBER=${HF_WEBUI_VERSION}")
|
||||
else()
|
||||
set(HF_WEBUI_VERSION "")
|
||||
message(STATUS "WebUI: version not specified (will use HF 'latest')")
|
||||
endif()
|
||||
|
||||
# Stamp file embeds the version tag so a changed build number triggers
|
||||
# a fresh provision run on the next `cmake --build` without reconfiguring.
|
||||
if("${HF_WEBUI_VERSION}" STREQUAL "")
|
||||
set(WEBUI_VERSION_TAG "provisioned")
|
||||
else()
|
||||
set(WEBUI_VERSION_TAG "${HF_WEBUI_VERSION}")
|
||||
endif()
|
||||
set(WEBUI_STAMP "${CMAKE_CURRENT_BINARY_DIR}/.webui-${WEBUI_VERSION_TAG}.stamp")
|
||||
|
||||
# Join assets with + separator (safe across all platforms, unlike ; and |)
|
||||
string(REPLACE ";" "+" PUBLIC_ASSETS_JOINED "${PUBLIC_ASSETS}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${WEBUI_STAMP}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DSOURCE_DIR=${PROJECT_SOURCE_DIR}"
|
||||
"-DPUBLIC_DIR=${CMAKE_CURRENT_SOURCE_DIR}/public"
|
||||
"-DHF_BUCKET=${LLAMA_WEBUI_HF_BUCKET}"
|
||||
"-DHF_VERSION=${HF_WEBUI_VERSION}"
|
||||
"-DHF_ENABLED=${LLAMA_USE_PREBUILT_WEBUI}"
|
||||
"-DASSETS=${PUBLIC_ASSETS_JOINED}"
|
||||
"-DSTAMP_FILE=${WEBUI_STAMP}"
|
||||
"-DNPM_DIR=${CMAKE_CURRENT_SOURCE_DIR}/webui"
|
||||
-P ${PROJECT_SOURCE_DIR}/scripts/webui-download.cmake
|
||||
COMMENT "Building/provisioning WebUI assets (npm build -> HF Bucket fallback)"
|
||||
)
|
||||
|
||||
set(WEBUI_SOURCE "provisioned")
|
||||
set(WEBUI_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/public")
|
||||
endif()
|
||||
|
||||
# Process assets from the determined source
|
||||
if(WEBUI_SOURCE_DIR)
|
||||
foreach(asset ${PUBLIC_ASSETS})
|
||||
set(input "${WEBUI_SOURCE_DIR}/${asset}")
|
||||
set(output "${CMAKE_CURRENT_BINARY_DIR}/${asset}.hpp")
|
||||
list(APPEND TARGET_SRCS ${output})
|
||||
|
||||
if(WEBUI_SOURCE STREQUAL "local")
|
||||
# Local build: files exist at configure time
|
||||
if(NOT EXISTS "${input}")
|
||||
message(FATAL_ERROR "WebUI asset not found: ${input}")
|
||||
endif()
|
||||
set(dependency "${input}")
|
||||
else()
|
||||
# HF Bucket: files are downloaded at build time
|
||||
set(dependency "${WEBUI_STAMP}")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
DEPENDS ${dependency}
|
||||
OUTPUT "${output}"
|
||||
COMMAND "${CMAKE_COMMAND}" "-DINPUT=${input}" "-DOUTPUT=${output}" -P "${PROJECT_SOURCE_DIR}/scripts/xxd.cmake"
|
||||
)
|
||||
set_source_files_properties(${output} PROPERTIES GENERATED TRUE)
|
||||
endforeach()
|
||||
|
||||
add_definitions(-DLLAMA_BUILD_WEBUI)
|
||||
add_definitions(-DLLAMA_WEBUI_DEFAULT_ENABLED=1)
|
||||
message(STATUS "WebUI: embedded with source: ${WEBUI_SOURCE}")
|
||||
else()
|
||||
# WebUI source not found - issue warning but don't fail the build
|
||||
# The server will still build but without webui embedded
|
||||
message(WARNING "WebUI: no source available. Neither local build (tools/server/public/) nor HF Bucket download succeeded.")
|
||||
message(WARNING "WebUI: building server without embedded WebUI. Set LLAMA_BUILD_WEBUI=OFF to suppress this warning.")
|
||||
add_definitions(-DLLAMA_WEBUI_DEFAULT_ENABLED=0)
|
||||
endif()
|
||||
else()
|
||||
# WebUI is disabled at build time
|
||||
add_definitions(-DLLAMA_WEBUI_DEFAULT_ENABLED=0)
|
||||
endif()
|
||||
|
||||
add_executable(${TARGET} ${TARGET_SRCS})
|
||||
install(TARGETS ${TARGET} RUNTIME)
|
||||
|
||||
target_include_directories(${TARGET} PRIVATE ../mtmd)
|
||||
target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR})
|
||||
target_link_libraries(${TARGET} PRIVATE server-context PUBLIC llama-common cpp-httplib ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries(${TARGET} PRIVATE server-context llama-ui PUBLIC llama-common cpp-httplib ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
target_compile_features(${TARGET} PRIVATE cxx_std_17)
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ The SvelteKit-based Web UI is introduced in this PR: https://github.com/ggml-org
|
|||
|
||||
### Architecture
|
||||
|
||||
The WebUI follows a layered architecture:
|
||||
The UI follows a layered architecture:
|
||||
|
||||
```
|
||||
Routes → Components → Hooks → Stores → Services → Storage/API
|
||||
|
|
@ -234,7 +234,7 @@ Routes → Components → Hooks → Stores → Services → Storage/API
|
|||
- **Services** - stateless API/database communication (`ChatService`, `ModelsService`, `PropsService`, `DatabaseService`)
|
||||
- **Hooks** - reusable logic (`useModelChangeValidation`, `useProcessingState`)
|
||||
|
||||
For detailed architecture diagrams, see [`tools/server/webui/docs/`](webui/docs/):
|
||||
For detailed architecture diagrams, see [`tools/ui/docs/`](../ui/docs/):
|
||||
|
||||
- `high-level-architecture.mmd` - full architecture with all modules
|
||||
- `high-level-architecture-simplified.mmd` - simplified overview
|
||||
|
|
@ -246,7 +246,7 @@ For detailed architecture diagrams, see [`tools/server/webui/docs/`](webui/docs/
|
|||
|
||||
```sh
|
||||
# make sure you have Node.js installed
|
||||
cd tools/server/webui
|
||||
cd tools/ui
|
||||
npm i
|
||||
|
||||
# run dev server (with hot reload)
|
||||
|
|
|
|||
|
|
@ -189,11 +189,11 @@ For the full list of features, please refer to [server's changelog](https://gith
|
|||
| `--reuse-port` | allow multiple sockets to bind to the same port (default: disabled)<br/>(env: LLAMA_ARG_REUSE_PORT) |
|
||||
| `--path PATH` | path to serve static files from (default: )<br/>(env: LLAMA_ARG_STATIC_PATH) |
|
||||
| `--api-prefix PREFIX` | prefix path the server serves from, without the trailing slash (default: )<br/>(env: LLAMA_ARG_API_PREFIX) |
|
||||
| `--webui-config JSON` | JSON that provides default WebUI settings (overrides WebUI defaults)<br/>(env: LLAMA_ARG_WEBUI_CONFIG) |
|
||||
| `--webui-config-file PATH` | JSON file that provides default WebUI settings (overrides WebUI defaults)<br/>(env: LLAMA_ARG_WEBUI_CONFIG_FILE) |
|
||||
| `--webui-mcp-proxy, --no-webui-mcp-proxy` | experimental: whether to enable MCP CORS proxy - do not enable in untrusted environments (default: disabled)<br/>(env: LLAMA_ARG_WEBUI_MCP_PROXY) |
|
||||
| `--ui-config JSON` / `--webui-config JSON` (deprecated) | JSON that provides default UI settings (overrides UI defaults)<br/>(env: LLAMA_ARG_UI_CONFIG / LLAMA_ARG_WEBUI_CONFIG) |
|
||||
| `--ui-config-file PATH` / `--webui-config-file PATH` (deprecated) | JSON file that provides default UI settings (overrides UI defaults)<br/>(env: LLAMA_ARG_UI_CONFIG_FILE / LLAMA_ARG_WEBUI_CONFIG_FILE) |
|
||||
| `--ui-mcp-proxy, --no-ui-mcp-proxy` / `--webui-mcp-proxy, --no-webui-mcp-proxy` (deprecated) | experimental: whether to enable MCP CORS proxy - do not enable in untrusted environments (default: disabled)<br/>(env: LLAMA_ARG_UI_MCP_PROXY / LLAMA_ARG_WEBUI_MCP_PROXY) |
|
||||
| `--tools TOOL1,TOOL2,...` | experimental: whether to enable built-in tools for AI agents - do not enable in untrusted environments (default: no tools)<br/>specify "all" to enable all tools<br/>available tools: read_file, file_glob_search, grep_search, exec_shell_command, write_file, edit_file, apply_diff, get_datetime<br/>(env: LLAMA_ARG_TOOLS) |
|
||||
| `--webui, --no-webui` | whether to enable the Web UI (default: enabled)<br/>(env: LLAMA_ARG_WEBUI) |
|
||||
| `--ui, --no-ui` / `--webui, --no-webui` (deprecated) | whether to enable the Web UI (default: enabled)<br/>(env: LLAMA_ARG_UI / LLAMA_ARG_WEBUI) |
|
||||
| `--embedding, --embeddings` | restrict to only support embedding use case; use only with dedicated embedding models (default: disabled)<br/>(env: LLAMA_ARG_EMBEDDINGS) |
|
||||
| `--rerank, --reranking` | enable reranking endpoint on server (default: disabled)<br/>(env: LLAMA_ARG_RERANKING) |
|
||||
| `--api-key KEY` | API key to use for authentication, multiple keys can be provided as a comma-separated list (default: none)<br/>(env: LLAMA_API_KEY) |
|
||||
|
|
@ -1831,10 +1831,12 @@ Apart from error types supported by OAI, we also have custom types that are spec
|
|||
|
||||
### Custom default Web UI preferences
|
||||
|
||||
You can specify default preferences for the web UI using `--webui-config <JSON config>` or `--webui-config-file <path to JSON config>`. For example, you can disable pasting long text as attachments and enable rendering Markdown in user messages with this command:
|
||||
You can specify default preferences for the web UI using `--ui-config <JSON config>` or `--ui-config-file <path to JSON config>`. For example, you can disable pasting long text as attachments and enable rendering Markdown in user messages with this command:
|
||||
|
||||
```bash
|
||||
./llama-server -m model.gguf --webui-config '{"pasteLongTextToFileLen": 0, "renderUserContentAsMarkdown": true}'
|
||||
./llama-server -m model.gguf --ui-config '{"pasteLongTextToFileLen": 0, "renderUserContentAsMarkdown": true}'
|
||||
```
|
||||
|
||||
You may find available preferences in [settings-config.ts](webui/src/lib/constants/settings-config.ts).
|
||||
> **Note:** The old flags `--webui-config` and `--webui-config-file` are deprecated but still work as aliases.
|
||||
|
||||
You may find available preferences in [settings-config.ts](../ui/src/lib/constants/settings-config.ts).
|
||||
|
|
|
|||
|
|
@ -671,7 +671,8 @@ private:
|
|||
|
||||
server_metrics metrics;
|
||||
|
||||
json json_webui_settings = json::object();
|
||||
json json_ui_settings = json::object(); // Primary: new name
|
||||
json json_webui_settings = json::object(); // Deprecated: use json_ui_settings instead (kept for compat)
|
||||
|
||||
// Necessary similarity of prompt for slot selection
|
||||
float slot_prompt_similarity = 0.0f;
|
||||
|
|
@ -996,13 +997,18 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// populate webui settings
|
||||
// populate UI settings (from either new ui_config_json or deprecated webui_config_json)
|
||||
{
|
||||
if (!params_base.webui_config_json.empty()) {
|
||||
const std::string & cfg = !params_base.ui_config_json.empty()
|
||||
? params_base.ui_config_json
|
||||
: params_base.webui_config_json;
|
||||
if (!cfg.empty()) {
|
||||
try {
|
||||
json_webui_settings = json::parse(params_base.webui_config_json);
|
||||
json json_settings = json::parse(cfg);
|
||||
json_ui_settings = json_settings;
|
||||
json_webui_settings = json_settings; // deprecated: keep in sync
|
||||
} catch (const std::exception & e) {
|
||||
SRV_ERR("%s: failed to parse webui config: %s\n", __func__, e.what());
|
||||
SRV_ERR("%s: failed to parse UI config: %s\n", __func__, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3292,7 +3298,8 @@ server_context_meta server_context::get_meta() const {
|
|||
/* has_mtmd */ impl->mctx != nullptr,
|
||||
/* has_inp_image */ impl->chat_params.allow_image,
|
||||
/* has_inp_audio */ impl->chat_params.allow_audio,
|
||||
/* json_webui_settings */ impl->json_webui_settings,
|
||||
/* json_ui_settings */ impl->json_ui_settings,
|
||||
/* json_webui_settings */ impl->json_webui_settings, // Deprecated
|
||||
/* slot_n_ctx */ impl->get_slot_n_ctx(),
|
||||
/* pooling_type */ llama_pooling_type(impl->ctx_tgt),
|
||||
|
||||
|
|
@ -3814,8 +3821,12 @@ void server_routes::init_routes() {
|
|||
{ "endpoint_slots", params.endpoint_slots },
|
||||
{ "endpoint_props", params.endpoint_props },
|
||||
{ "endpoint_metrics", params.endpoint_metrics },
|
||||
{ "webui", params.webui },
|
||||
{ "webui_settings", meta->json_webui_settings },
|
||||
// New keys
|
||||
{ "ui", params.ui },
|
||||
{ "ui_settings", meta->json_ui_settings },
|
||||
// Deprecated: use ui/ui_settings instead (kept for backward compat)
|
||||
{ "webui", params.webui },
|
||||
{ "webui_settings", meta->json_webui_settings },
|
||||
{ "chat_template", tmpl_default },
|
||||
{ "chat_template_caps", meta->chat_template_caps },
|
||||
{ "bos_token", meta->bos_token_str },
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ struct server_context_meta {
|
|||
bool has_mtmd;
|
||||
bool has_inp_image;
|
||||
bool has_inp_audio;
|
||||
json json_webui_settings;
|
||||
json json_ui_settings; // Primary: new name
|
||||
json json_webui_settings; // Deprecated: use json_ui_settings instead (kept for backward compat)
|
||||
int slot_n_ctx;
|
||||
enum llama_pooling_type pooling_type;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "common.h"
|
||||
#include "server-http.h"
|
||||
#include "server-common.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include <cpp-httplib/httplib.h>
|
||||
|
||||
|
|
@ -10,14 +11,6 @@
|
|||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#ifdef LLAMA_BUILD_WEBUI
|
||||
// auto generated files (see README.md for details)
|
||||
#include "index.html.hpp"
|
||||
#include "bundle.js.hpp"
|
||||
#include "bundle.css.hpp"
|
||||
#include "loading.html.hpp"
|
||||
#endif
|
||||
|
||||
//
|
||||
// HTTP implementation using cpp-httplib
|
||||
//
|
||||
|
|
@ -238,10 +231,11 @@ bool server_http_context::init(const common_params & params) {
|
|||
};
|
||||
|
||||
auto middleware_server_state = [this](const httplib::Request & req, httplib::Response & res) {
|
||||
(void)req; // suppress unused parameter warning when LLAMA_BUILD_WEBUI is not defined
|
||||
(void)req; // suppress unused parameter warning when LLAMA_BUILD_UI / LLAMA_BUILD_WEBUI is not defined
|
||||
bool ready = is_ready.load();
|
||||
if (!ready) {
|
||||
#ifdef LLAMA_BUILD_WEBUI
|
||||
// Support both old and new preprocessor defines
|
||||
#if defined(LLAMA_BUILD_UI) || defined(LLAMA_BUILD_WEBUI)
|
||||
auto tmp = string_split<std::string>(req.path, '.');
|
||||
if (req.path == "/" || (tmp.size() > 0 && tmp.back() == "html")) {
|
||||
res.status = 503;
|
||||
|
|
@ -305,8 +299,10 @@ bool server_http_context::init(const common_params & params) {
|
|||
// Web UI setup
|
||||
//
|
||||
|
||||
if (!params.webui) {
|
||||
SRV_INF("%s", "the WebUI is disabled\n");
|
||||
// Use new `params.ui` field (backed by old `params.webui` for compat)
|
||||
if (!params.ui) {
|
||||
SRV_INF("%s", "The UI is disabled\n");
|
||||
SRV_INF("%s", "Use --ui/--no-ui (or deprecated --webui/--no-webui) to enable/disable\n");
|
||||
} else {
|
||||
// register static assets routes
|
||||
if (!params.public_path.empty()) {
|
||||
|
|
@ -317,7 +313,8 @@ bool server_http_context::init(const common_params & params) {
|
|||
return 1;
|
||||
}
|
||||
} else {
|
||||
#ifdef LLAMA_BUILD_WEBUI
|
||||
// Support both old and new preprocessor defines
|
||||
#if defined(LLAMA_BUILD_UI) || defined(LLAMA_BUILD_WEBUI)
|
||||
// using embedded static index.html
|
||||
srv->Get(params.api_prefix + "/", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||
// COEP and COOP headers, required by pyodide (python interpreter)
|
||||
|
|
|
|||
|
|
@ -1152,14 +1152,17 @@ void server_models_routes::init_routes() {
|
|||
{"role", "router"},
|
||||
{"max_instances", params.models_max},
|
||||
{"models_autoload", params.models_autoload},
|
||||
// this is a dummy response to make sure webui doesn't break
|
||||
// this is a dummy response to make sure the UI doesn't break
|
||||
{"model_alias", "llama-server"},
|
||||
{"model_path", "none"},
|
||||
{"default_generation_settings", {
|
||||
{"params", json{}},
|
||||
{"n_ctx", 0},
|
||||
}},
|
||||
{"webui_settings", webui_settings},
|
||||
// New key
|
||||
{"ui_settings", ui_settings},
|
||||
// Deprecated: use ui_settings instead (kept for backward compat)
|
||||
{"webui_settings", webui_settings},
|
||||
{"build_info", std::string(llama_build_info())},
|
||||
});
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -175,15 +175,22 @@ public:
|
|||
|
||||
struct server_models_routes {
|
||||
common_params params;
|
||||
json webui_settings = json::object();
|
||||
json ui_settings = json::object(); // Primary: new name
|
||||
json webui_settings = json::object(); // Deprecated: use ui_settings (kept for compat)
|
||||
server_models models;
|
||||
server_models_routes(const common_params & params, int argc, char ** argv)
|
||||
: params(params), models(params, argc, argv) {
|
||||
if (!this->params.webui_config_json.empty()) {
|
||||
// Support both new ui_config_json and deprecated webui_config_json
|
||||
const std::string & cfg = !this->params.ui_config_json.empty()
|
||||
? this->params.ui_config_json
|
||||
: this->params.webui_config_json;
|
||||
if (!cfg.empty()) {
|
||||
try {
|
||||
webui_settings = json::parse(this->params.webui_config_json);
|
||||
json json_settings = json::parse(cfg);
|
||||
ui_settings = json_settings;
|
||||
webui_settings = json_settings; // Deprecated: keep in sync
|
||||
} catch (const std::exception & e) {
|
||||
LOG_ERR("%s: failed to parse webui config: %s\n", __func__, e.what());
|
||||
LOG_ERR("%s: failed to parse UI config: %s\n", __func__, e.what());
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,8 @@ int main(int argc, char ** argv) {
|
|||
ctx_http.register_gcp_compat();
|
||||
|
||||
// CORS proxy (EXPERIMENTAL, only used by the Web UI for MCP)
|
||||
if (params.webui_mcp_proxy) {
|
||||
// Supports both new ui_mcp_proxy and deprecated webui_mcp_proxy fields
|
||||
if (params.ui_mcp_proxy || params.webui_mcp_proxy) {
|
||||
SRV_WRN("%s", "-----------------\n");
|
||||
SRV_WRN("%s", "CORS proxy is enabled, do not expose server to untrusted environments\n");
|
||||
SRV_WRN("%s", "This feature is EXPERIMENTAL and may be removed or changed in future versions\n");
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
rm -rf ../public/_app;
|
||||
rm ../public/favicon.svg;
|
||||
rm -f ../public/index.html.gz; # deprecated, but may still be generated by older versions of the build process
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export const ALWAYS_ALLOWED_TOOLS_LOCALSTORAGE_KEY = 'LlamaCppWebui.alwaysAllowedTools';
|
||||
export const CONFIG_LOCALSTORAGE_KEY = 'LlamaCppWebui.config';
|
||||
export const DISABLED_TOOLS_LOCALSTORAGE_KEY = 'LlamaCppWebui.disabledTools';
|
||||
export const FAVORITE_MODELS_LOCALSTORAGE_KEY = 'LlamaCppWebui.favoriteModels';
|
||||
export const MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY = 'LlamaCppWebui.mcpDefaultEnabled';
|
||||
export const USER_OVERRIDES_LOCALSTORAGE_KEY = 'LlamaCppWebui.userOverrides';
|
||||
157
tools/ui/CMakeLists.txt
Normal file
157
tools/ui/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
set(TARGET llama-ui)
|
||||
|
||||
# Deprecated: use LLAMA_UI_HF_BUCKET instead
|
||||
set(LLAMA_WEBUI_HF_BUCKET "llama-ui" CACHE STRING "Hugging Face bucket name for prebuilt webui assets (deprecated: use LLAMA_UI_HF_BUCKET)")
|
||||
set(LLAMA_UI_HF_BUCKET "llama-ui" CACHE STRING "Hugging Face bucket name for prebuilt UI assets")
|
||||
|
||||
# Backward compat: forward old var to new one
|
||||
if(DEFINED LLAMA_WEBUI_HF_BUCKET AND NOT DEFINED LLAMA_UI_HF_BUCKET)
|
||||
set(LLAMA_UI_HF_BUCKET ${LLAMA_WEBUI_HF_BUCKET})
|
||||
elseif(DEFINED LLAMA_WEBUI_HF_BUCKET AND NOT "${LLAMA_WEBUI_HF_BUCKET}" STREQUAL "${LLAMA_UI_HF_BUCKET}")
|
||||
message(DEPRECATION "LLAMA_WEBUI_HF_BUCKET is deprecated, use LLAMA_UI_HF_BUCKET instead")
|
||||
endif()
|
||||
|
||||
set(TARGET_SRCS "")
|
||||
set(UI_COMPILE_DEFS "")
|
||||
|
||||
# Support both old (LLAMA_BUILD_WEBUI) and new (LLAMA_BUILD_UI) option names
|
||||
if(LLAMA_BUILD_WEBUI OR LLAMA_BUILD_UI)
|
||||
if(LLAMA_BUILD_WEBUI AND NOT LLAMA_BUILD_UI)
|
||||
message(DEPRECATION "LLAMA_BUILD_WEBUI is deprecated, use LLAMA_BUILD_UI instead")
|
||||
endif()
|
||||
|
||||
set(PUBLIC_ASSETS
|
||||
index.html
|
||||
bundle.js
|
||||
bundle.css
|
||||
loading.html
|
||||
)
|
||||
|
||||
# Determine source of UI assets (priority: local > HF Bucket)
|
||||
set(UI_SOURCE "")
|
||||
set(UI_SOURCE_DIR "")
|
||||
|
||||
# Priority 1: Check for local build output
|
||||
set(LOCAL_UI_DIR "${PROJECT_SOURCE_DIR}/build/tools/ui/dist")
|
||||
|
||||
# Verify all required assets exist before declaring local source valid
|
||||
set(ALL_ASSETS_PRESENT TRUE)
|
||||
foreach(asset ${PUBLIC_ASSETS})
|
||||
if(NOT EXISTS "${LOCAL_UI_DIR}/${asset}")
|
||||
set(ALL_ASSETS_PRESENT FALSE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(ALL_ASSETS_PRESENT)
|
||||
set(UI_SOURCE "local")
|
||||
set(UI_SOURCE_DIR "${LOCAL_UI_DIR}")
|
||||
message(STATUS "UI: using local build from ${UI_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
# Priority 2: Build-time asset provisioning (npm build → HF Bucket fallback)
|
||||
if(NOT UI_SOURCE_DIR)
|
||||
# Environment variable takes precedence (e.g., from CI workflows)
|
||||
# Deprecated: use HF_UI_VERSION instead
|
||||
if(DEFINED ENV{HF_WEBUI_VERSION})
|
||||
set(HF_UI_VERSION "$ENV{HF_WEBUI_VERSION}")
|
||||
message(DEPRECATION "HF_WEBUI_VERSION env var is deprecated, use HF_UI_VERSION instead")
|
||||
if(NOT HF_UI_VERSION MATCHES "^[A-Za-z0-9._-]+$")
|
||||
message(FATAL_ERROR "UI: invalid HF_WEBUI_VERSION='${HF_UI_VERSION}' - must match ^[A-Za-z0-9._-]+$")
|
||||
endif()
|
||||
elseif(DEFINED ENV{HF_UI_VERSION})
|
||||
set(HF_UI_VERSION "$ENV{HF_UI_VERSION}")
|
||||
if(NOT HF_UI_VERSION MATCHES "^[A-Za-z0-9._-]+$")
|
||||
message(FATAL_ERROR "UI: invalid HF_UI_VERSION='${HF_UI_VERSION}' - must match ^[A-Za-z0-9._-]+$")
|
||||
endif()
|
||||
elseif(DEFINED LLAMA_BUILD_NUMBER)
|
||||
set(HF_UI_VERSION "b${LLAMA_BUILD_NUMBER}")
|
||||
message(STATUS "UI: derived HF_UI_VERSION=b${LLAMA_BUILD_NUMBER}")
|
||||
else()
|
||||
set(HF_UI_VERSION "")
|
||||
message(STATUS "UI: version not specified (will use HF 'latest')")
|
||||
endif()
|
||||
|
||||
if("${HF_UI_VERSION}" STREQUAL "")
|
||||
set(UI_VERSION_TAG "provisioned")
|
||||
else()
|
||||
set(UI_VERSION_TAG "${HF_UI_VERSION}")
|
||||
endif()
|
||||
set(UI_STAMP "${CMAKE_CURRENT_BINARY_DIR}/.ui-${UI_VERSION_TAG}.stamp")
|
||||
|
||||
string(REPLACE ";" "+" PUBLIC_ASSETS_JOINED "${PUBLIC_ASSETS}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${UI_STAMP}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DSOURCE_DIR=${PROJECT_SOURCE_DIR}"
|
||||
"-DPUBLIC_DIR=${PROJECT_SOURCE_DIR}/build/tools/ui/dist"
|
||||
"-DHF_BUCKET=${LLAMA_UI_HF_BUCKET}"
|
||||
"-DHF_VERSION=${HF_UI_VERSION}"
|
||||
"-DHF_ENABLED=${LLAMA_USE_PREBUILT_UI}"
|
||||
"-DASSETS=${PUBLIC_ASSETS_JOINED}"
|
||||
"-DSTAMP_FILE=${UI_STAMP}"
|
||||
"-DNPM_DIR=${PROJECT_SOURCE_DIR}/tools/ui"
|
||||
-P ${PROJECT_SOURCE_DIR}/scripts/ui-download.cmake
|
||||
COMMENT "Building/provisioning UI assets (npm build -> HF Bucket fallback)"
|
||||
)
|
||||
|
||||
set(UI_SOURCE "provisioned")
|
||||
set(UI_SOURCE_DIR "${PROJECT_SOURCE_DIR}/build/tools/ui/dist")
|
||||
endif()
|
||||
|
||||
# Process assets from the determined source
|
||||
if(UI_SOURCE_DIR)
|
||||
foreach(asset ${PUBLIC_ASSETS})
|
||||
set(input "${UI_SOURCE_DIR}/${asset}")
|
||||
set(output "${CMAKE_CURRENT_BINARY_DIR}/${asset}.hpp")
|
||||
list(APPEND TARGET_SRCS ${output})
|
||||
|
||||
if(UI_SOURCE STREQUAL "local")
|
||||
if(NOT EXISTS "${input}")
|
||||
message(FATAL_ERROR "UI asset not found: ${input}")
|
||||
endif()
|
||||
set(dependency "${input}")
|
||||
else()
|
||||
set(dependency "${UI_STAMP}")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
DEPENDS ${dependency}
|
||||
OUTPUT "${output}"
|
||||
COMMAND "${CMAKE_COMMAND}" "-DINPUT=${input}" "-DOUTPUT=${output}" -P "${PROJECT_SOURCE_DIR}/scripts/xxd.cmake"
|
||||
)
|
||||
set_source_files_properties(${output} PROPERTIES GENERATED TRUE)
|
||||
endforeach()
|
||||
|
||||
list(APPEND UI_COMPILE_DEFS
|
||||
LLAMA_BUILD_WEBUI # Deprecated: use LLAMA_BUILD_UI
|
||||
LLAMA_BUILD_UI
|
||||
LLAMA_WEBUI_DEFAULT_ENABLED=1 # Deprecated: use LLAMA_UI_DEFAULT_ENABLED
|
||||
LLAMA_UI_DEFAULT_ENABLED=1
|
||||
)
|
||||
message(STATUS "UI: embedded with source: ${UI_SOURCE}")
|
||||
else()
|
||||
message(WARNING "UI: no source available. Neither local build (build/tools/ui/dist/) nor HF Bucket download succeeded.")
|
||||
message(WARNING "UI: building server without embedded UI. Set LLAMA_BUILD_UI=OFF to suppress this warning.")
|
||||
list(APPEND UI_COMPILE_DEFS LLAMA_WEBUI_DEFAULT_ENABLED=0 LLAMA_UI_DEFAULT_ENABLED=0)
|
||||
endif()
|
||||
else()
|
||||
list(APPEND UI_COMPILE_DEFS LLAMA_WEBUI_DEFAULT_ENABLED=0 LLAMA_UI_DEFAULT_ENABLED=0)
|
||||
endif()
|
||||
|
||||
# Build the static library
|
||||
add_library(${TARGET} STATIC ui.cpp)
|
||||
|
||||
target_include_directories(${TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(${TARGET} PUBLIC ${UI_COMPILE_DEFS})
|
||||
|
||||
if(TARGET_SRCS)
|
||||
# List generated .hpp files as sources so CMake tracks them as build dependencies
|
||||
target_sources(${TARGET} PRIVATE ${TARGET_SRCS})
|
||||
set_source_files_properties(${TARGET_SRCS} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
endif()
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
A modern, feature-rich web interface for llama-server built with SvelteKit. This UI provides an intuitive chat interface with advanced file handling, conversation management, and comprehensive model interaction capabilities.
|
||||
|
||||
The WebUI supports two server operation modes:
|
||||
Llama UI supports two server operation modes:
|
||||
|
||||
- **MODEL mode** - Single model operation (standard llama-server)
|
||||
- **ROUTER mode** - Multi-model operation with dynamic model loading/unloading
|
||||
|
|
@ -88,7 +88,7 @@ The WebUI supports two server operation modes:
|
|||
### 1. Install Dependencies
|
||||
|
||||
```bash
|
||||
cd tools/server/webui
|
||||
cd tools/ui
|
||||
npm install
|
||||
```
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ npm run dev
|
|||
|
||||
This starts:
|
||||
|
||||
- **Vite dev server** at `http://localhost:5173` - The main WebUI
|
||||
- **Vite dev server** at `http://localhost:5173` - The main UI frontend app
|
||||
- **Storybook** at `http://localhost:6006` - Component documentation
|
||||
|
||||
The Vite dev server proxies API requests to `http://localhost:8080` (default llama-server port):
|
||||
|
|
@ -186,7 +186,7 @@ npm run build
|
|||
The build process:
|
||||
|
||||
1. **Vite Build** - Bundles all TypeScript, Svelte, and CSS
|
||||
2. **Static Adapter** - Outputs to `../public` (llama-server's static file directory)
|
||||
2. **Static Adapter** - Outputs to `../../build/tools/ui/dist` (llama-server's static file directory)
|
||||
3. **Post-Build Script** - Cleans up intermediate files
|
||||
4. **Custom Plugin** - Creates `index.html` with:
|
||||
- Inlined favicon as base64
|
||||
|
|
@ -194,7 +194,7 @@ The build process:
|
|||
- Deterministic output (zeroed timestamps)
|
||||
|
||||
```text
|
||||
tools/server/webui/ → build → tools/server/public/
|
||||
tools/ui/ → build → build/tools/ui/dist/
|
||||
├── src/ ├── index.html (served by llama-server)
|
||||
├── static/ └── (favicon inlined)
|
||||
└── ...
|
||||
|
|
@ -205,8 +205,8 @@ tools/server/webui/ → build → tools/server/public/
|
|||
```javascript
|
||||
// svelte.config.js
|
||||
adapter: adapter({
|
||||
pages: '../public', // Output directory
|
||||
assets: '../public', // Static assets
|
||||
pages: '../../build/tools/ui/dist', // Output directory
|
||||
assets: '../../build/tools/ui/dist', // Static assets
|
||||
fallback: 'index.html', // SPA fallback
|
||||
strict: true
|
||||
}),
|
||||
|
|
@ -217,20 +217,19 @@ output: {
|
|||
|
||||
### Integration with llama-server
|
||||
|
||||
The WebUI is embedded directly into the llama-server binary:
|
||||
llama-ui is embedded directly into the llama-server binary:
|
||||
|
||||
1. `npm run build` outputs `index.html` to `tools/server/public/`
|
||||
1. `npm run build` outputs `index.html` to `build/tools/ui/dist/`
|
||||
2. llama-server compiles this into the binary at build time
|
||||
3. When accessing `/`, llama-server serves the gzipped HTML
|
||||
4. All assets are inlined (CSS, JS, fonts, favicon)
|
||||
3. When accessing `/`, llama-server serves the bundled HTML
|
||||
|
||||
This results in a **single portable binary** with the full WebUI included.
|
||||
This results in a **single portable binary** with the full Llama UI included.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
The WebUI follows a layered architecture with unidirectional data flow:
|
||||
Llama UI follows a layered architecture with unidirectional data flow:
|
||||
|
||||
```text
|
||||
Routes → Components → Hooks → Stores → Services → Storage/API
|
||||
|
|
@ -659,7 +658,7 @@ npm run check # TypeScript type checking
|
|||
## Project Structure
|
||||
|
||||
```text
|
||||
tools/server/webui/
|
||||
tools/ui/
|
||||
├── src/
|
||||
│ ├── lib/
|
||||
│ │ ├── components/ # UI components (app/, ui/)
|
||||
|
|
@ -58,8 +58,8 @@ sequenceDiagram
|
|||
end
|
||||
end
|
||||
|
||||
alt serverStore.props has webuiSettings
|
||||
settingsStore->>settingsStore: Apply webuiSettings from server
|
||||
alt serverStore.props has uiSettings
|
||||
settingsStore->>settingsStore: Apply uiSettings from server
|
||||
Note right of settingsStore: Server-provided UI settings<br/>(e.g. showRawOutputSwitch)
|
||||
end
|
||||
|
||||
|
|
@ -29,7 +29,9 @@ export default ts.config(
|
|||
'no-undef': 'off',
|
||||
'svelte/no-at-html-tags': 'off',
|
||||
// This app uses hash-based routing (#/) where resolve() from $app/paths does not apply
|
||||
'svelte/no-navigation-without-resolve': 'off'
|
||||
'svelte/no-navigation-without-resolve': 'off',
|
||||
// Enforce empty line at end of file
|
||||
'eol-last': 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bash scripts/dev.sh",
|
||||
"build": "vite build && ./scripts/post-build.sh",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync || echo ''",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
|
|
@ -2,7 +2,7 @@ import { defineConfig } from '@playwright/test';
|
|||
|
||||
export default defineConfig({
|
||||
webServer: {
|
||||
command: 'npm run build && http-server ../public -p 8181',
|
||||
command: 'npm run build && http-server ../../build/tools/ui/dist -p 8181',
|
||||
port: 8181,
|
||||
timeout: 120000,
|
||||
reuseExistingServer: false
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
# Development script for llama-ui
|
||||
#
|
||||
# This script starts the webui development servers (Storybook and Vite).
|
||||
# This script starts the llama-ui development servers (Storybook and Vite).
|
||||
# Note: You need to start llama-server separately.
|
||||
#
|
||||
# Usage:
|
||||
# bash scripts/dev.sh
|
||||
# npm run dev
|
||||
|
||||
cd ../../../
|
||||
cd ../../
|
||||
|
||||
# Check and install git hooks if missing
|
||||
check_and_install_hooks() {
|
||||
|
|
@ -22,13 +22,13 @@ check_and_install_hooks() {
|
|||
|
||||
if [ "$hooks_missing" = true ]; then
|
||||
echo "🔧 Git hooks missing, installing them..."
|
||||
cd tools/server/webui
|
||||
cd tools/ui
|
||||
if bash scripts/install-git-hooks.sh; then
|
||||
echo "✅ Git hooks installed successfully"
|
||||
else
|
||||
echo "⚠️ Failed to install git hooks, continuing anyway..."
|
||||
fi
|
||||
cd ../../../
|
||||
cd ../../
|
||||
else
|
||||
echo "✅ Git hooks already installed"
|
||||
fi
|
||||
|
|
@ -48,7 +48,7 @@ trap cleanup SIGINT SIGTERM
|
|||
|
||||
echo "🚀 Starting development servers..."
|
||||
echo "📝 Note: Make sure to start llama-server separately if needed"
|
||||
cd tools/server/webui
|
||||
cd tools/ui
|
||||
# Use --insecure-http-parser to handle malformed HTTP responses from llama-server
|
||||
# (some responses have both Content-Length and Transfer-Encoding headers)
|
||||
storybook dev -p 6006 --ci & NODE_OPTIONS="--insecure-http-parser" vite dev --host 0.0.0.0 &
|
||||
|
|
@ -1,29 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Script to install pre-commit hook for webui
|
||||
# Pre-commit: formats, checks, and builds webui
|
||||
# Script to install pre-commit hook for llama-ui
|
||||
# Pre-commit: formats, checks, and builds the UI app
|
||||
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
PRE_COMMIT_HOOK="$REPO_ROOT/.git/hooks/pre-commit"
|
||||
|
||||
echo "Installing pre-commit hook for webui..."
|
||||
echo "Installing pre-commit hook for llama-ui..."
|
||||
|
||||
# Create the pre-commit hook
|
||||
cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Check if there are any changes in the webui directory
|
||||
if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
||||
# Check if there are any changes in the tools/ui directory
|
||||
if git diff --cached --name-only | grep -q "^tools/ui/"; then
|
||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
cd "$REPO_ROOT/tools/server/webui"
|
||||
cd "$REPO_ROOT/tools/ui"
|
||||
|
||||
# Check if package.json exists
|
||||
if [ ! -f "package.json" ]; then
|
||||
echo "Error: package.json not found in tools/server/webui"
|
||||
echo "Error: package.json not found in tools/ui"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Formatting and checking webui code..."
|
||||
echo "Formatting and checking llama-ui code..."
|
||||
|
||||
# Run the format command
|
||||
npm run format
|
||||
|
|
@ -46,17 +46,17 @@ if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Webui code formatted and checked successfully"
|
||||
echo "✅ llama-ui code formatted and checked successfully"
|
||||
|
||||
# Build the webui
|
||||
echo "Building webui..."
|
||||
# Build the llama-ui
|
||||
echo "Building llama-ui..."
|
||||
npm run build
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ npm run build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Webui built successfully"
|
||||
echo "✅ llama-ui built successfully"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -70,8 +70,8 @@ if [ $? -eq 0 ]; then
|
|||
echo " Pre-commit: $PRE_COMMIT_HOOK"
|
||||
echo ""
|
||||
echo "The hook will automatically:"
|
||||
echo " • Format, lint and check webui code before commits"
|
||||
echo " • Build webui"
|
||||
echo " • Format, lint and check llama-ui code before commits"
|
||||
echo " • Build llama-ui"
|
||||
else
|
||||
echo "❌ Failed to make hook executable"
|
||||
exit 1
|
||||
|
|
@ -1,4 +1,12 @@
|
|||
import { readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from 'fs';
|
||||
import {
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
existsSync,
|
||||
readdirSync,
|
||||
copyFileSync,
|
||||
rmSync,
|
||||
unlinkSync
|
||||
} from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
|
|
@ -11,28 +19,28 @@ const GUIDE_FOR_FRONTEND = `
|
|||
-->
|
||||
`.trim();
|
||||
|
||||
const OUTPUT_DIR = '../../build/tools/ui/dist';
|
||||
|
||||
export function llamaCppBuildPlugin(): Plugin {
|
||||
return {
|
||||
name: 'llamacpp:build',
|
||||
apply: 'build',
|
||||
closeBundle() {
|
||||
// Ensure the SvelteKit adapter has finished writing to ../public
|
||||
setTimeout(() => {
|
||||
try {
|
||||
const indexPath = resolve('../public/index.html');
|
||||
const outDir = resolve(OUTPUT_DIR);
|
||||
const indexPath = resolve(outDir, 'index.html');
|
||||
if (!existsSync(indexPath)) return;
|
||||
|
||||
let content = readFileSync(indexPath, 'utf-8');
|
||||
|
||||
// Inline favicon as base64 data URL
|
||||
const faviconPath = resolve('static/favicon.svg');
|
||||
|
||||
if (existsSync(faviconPath)) {
|
||||
const faviconContent = readFileSync(faviconPath, 'utf-8');
|
||||
const faviconBase64 = Buffer.from(faviconContent).toString('base64');
|
||||
const faviconDataUrl = `data:image/svg+xml;base64,${faviconBase64}`;
|
||||
|
||||
content = content.replace(/href="[^"]*favicon\.svg"/g, `href="${faviconDataUrl}"`);
|
||||
|
||||
console.log('✓ Inlined favicon.svg as base64 data URL');
|
||||
}
|
||||
|
||||
|
|
@ -48,17 +56,16 @@ export function llamaCppBuildPlugin(): Plugin {
|
|||
writeFileSync(indexPath, content, 'utf-8');
|
||||
console.log('✓ Updated index.html');
|
||||
|
||||
// Copy bundle.*.js -> ../public/bundle.js
|
||||
const immutableDir = resolve('../public/_app/immutable');
|
||||
const bundleDir = resolve('../public/_app/immutable/assets');
|
||||
// Copy bundle.*.js -> bundle.js at output root
|
||||
const immutableDir = resolve(outDir, '_app/immutable');
|
||||
const bundleDir = resolve(outDir, '_app/immutable/assets');
|
||||
|
||||
if (existsSync(immutableDir)) {
|
||||
const jsFiles = readdirSync(immutableDir).filter((f) => f.match(/^bundle\..+\.js$/));
|
||||
|
||||
if (jsFiles.length > 0) {
|
||||
copyFileSync(resolve(immutableDir, jsFiles[0]), resolve('../public/bundle.js'));
|
||||
copyFileSync(resolve(immutableDir, jsFiles[0]), resolve(outDir, 'bundle.js'));
|
||||
// Normalize __sveltekit_<hash> to __sveltekit__ in bundle.js
|
||||
const bundleJsPath = resolve('../public/bundle.js');
|
||||
const bundleJsPath = resolve(outDir, 'bundle.js');
|
||||
let bundleJs = readFileSync(bundleJsPath, 'utf-8');
|
||||
bundleJs = bundleJs.replace(/__sveltekit_[a-z0-9]+/g, '__sveltekit__');
|
||||
writeFileSync(bundleJsPath, bundleJs, 'utf-8');
|
||||
|
|
@ -66,17 +73,29 @@ export function llamaCppBuildPlugin(): Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
// Copy bundle.*.css -> ../public/bundle.css
|
||||
// Copy bundle.*.css -> bundle.css at output root
|
||||
if (existsSync(bundleDir)) {
|
||||
const cssFiles = readdirSync(bundleDir).filter((f) => f.match(/^bundle\..+\.css$/));
|
||||
|
||||
if (cssFiles.length > 0) {
|
||||
copyFileSync(resolve(bundleDir, cssFiles[0]), resolve('../public/bundle.css'));
|
||||
copyFileSync(resolve(bundleDir, cssFiles[0]), resolve(outDir, 'bundle.css'));
|
||||
console.log(`✓ Copied ${cssFiles[0]} -> bundle.css`);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup: remove _app directory, favicon.svg, and legacy index.html.gz
|
||||
const appDir = resolve(outDir, '_app');
|
||||
if (existsSync(appDir)) {
|
||||
rmSync(appDir, { recursive: true, force: true });
|
||||
console.log('✓ Removed _app directory');
|
||||
}
|
||||
|
||||
const faviconOut = resolve(outDir, 'favicon.svg');
|
||||
if (existsSync(faviconOut)) {
|
||||
unlinkSync(faviconOut);
|
||||
console.log('✓ Removed favicon.svg');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to update index.html:', error);
|
||||
console.error('Failed to process build output:', error);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
|
@ -54,7 +54,12 @@
|
|||
}
|
||||
|
||||
const attachmentMenu = useAttachmentMenu(
|
||||
() => ({ hasVisionModality, hasAudioModality, hasMcpPromptsSupport, hasMcpResourcesSupport }),
|
||||
() => ({
|
||||
hasVisionModality,
|
||||
hasAudioModality,
|
||||
hasMcpPromptsSupport,
|
||||
hasMcpResourcesSupport
|
||||
}),
|
||||
() => ({ onFileUpload, onSystemPromptClick, onMcpPromptClick, onMcpResourcesClick }),
|
||||
() => {
|
||||
dropdownOpen = false;
|
||||
|
|
@ -46,7 +46,12 @@
|
|||
let sheetOpen = $state(false);
|
||||
|
||||
const attachmentMenu = useAttachmentMenu(
|
||||
() => ({ hasVisionModality, hasAudioModality, hasMcpPromptsSupport, hasMcpResourcesSupport }),
|
||||
() => ({
|
||||
hasVisionModality,
|
||||
hasAudioModality,
|
||||
hasMcpPromptsSupport,
|
||||
hasMcpResourcesSupport
|
||||
}),
|
||||
() => ({ onFileUpload, onSystemPromptClick, onMcpPromptClick, onMcpResourcesClick }),
|
||||
() => {
|
||||
sheetOpen = false;
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||
import { toolsStore } from '$lib/stores/tools.svelte';
|
||||
import { CLI_FLAGS } from '$lib/constants';
|
||||
import { mcpStore } from '$lib/stores/mcp.svelte';
|
||||
import { useToolsPanel } from '$lib/hooks/use-tools-panel.svelte';
|
||||
|
||||
|
|
@ -33,7 +34,7 @@
|
|||
<Info class="mt-0.5 h-4 w-4 shrink-0" />
|
||||
|
||||
<span>
|
||||
Run llama-server with <code>--tools</code> flag to enable
|
||||
Run llama-server with <code>{CLI_FLAGS.TOOLS}</code> flag to enable
|
||||
|
||||
<strong>Built-in Tools</strong>.
|
||||
</span>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue