Skip to content

ci+server: aioc HT-compat probe + /v1/reranking Phase A & B coverage#39

Closed
marksverdhei wants to merge 228 commits into
htfrom
feat/ci-aioc-compat-probe
Closed

ci+server: aioc HT-compat probe + /v1/reranking Phase A & B coverage#39
marksverdhei wants to merge 228 commits into
htfrom
feat/ci-aioc-compat-probe

Conversation

@marksverdhei

@marksverdhei marksverdhei commented May 13, 2026

Copy link
Copy Markdown

Summary

  • New .github/workflows/aioc.yml runs the am-i-openai-compatible probe under --profile ht on every server PR (PR-only, no fork CI cost).
  • eb7bf385b lands /v1/reranking HT-compat Phase A compliance — the response now emits id and return_documents as the spec requires.
  • 70a6d76ee extends the workflow to Phase B by booting llama-server in router mode with two preset-INI models side-loaded:
    • ggml-org/test-model-stories260K (~1 MB) — chat-completions + embeddings, Phase B coverage preserved.
    • jimi0209/bge-reranker-base-Q5_K_M-GGUF (~228 MB) — rerank kind, flips /v1/reranking Phase B SKIP → PASS via aioc's name-substring classifier.

Closes #40.

Test plan

  • CI: aioc compat probe job passes, report shows /v1/reranking Phase A = PASS, Phase B = PASS, chat-completions Phase B retained.
  • Workflow runtime stays under ~8 min (reranker download dominates the budget; load-on-startup = 1 avoids cold-path latency in the probe phase).
  • Report artifact uploaded so regression triage doesn't depend on log scraping.

🤖 Generated with Claude Code

EmilAskerov and others added 30 commits April 28, 2026 12:19
…1918)

* ggml: improve SPIR-V headers detection with __has_include while preserving original _WIN32 logic

* Address review comments: fix fallback logic and add FreeBSD support

* Remove spirv_cross fallback as per review

* Remove redundant __has_include check
* wip: server_tools

* feat: Integrate with `/tools` endpoint

* feat: Builtin + MCP + JSON Schema Tools WIP

* refactor

* displayName -> display_name

* snake_case everywhere

* rm redundant field

* feat: Improvements

* chore: update webui build output

* refactor: Updates after server updates

* chore: update webui build output

* change arg to --tools all

* feat: UI improvements

* chore: update webui build output

* add readme mention

* llama-gen-docs

* chore: update webui build output

* chore: update webui build output

* chore: update webui build output

* feat: Reorganize settings sections

* feat: Separate dialogs for MCP Servers Settings and Import/Export

* feat: WIP

* feat: WIP

* feat: WIP

* feat: WIP

* feat: WIP

* feat: WIP

* WIP on allozaur/20677-webui-server-tools

* feat: UI improvements

* chore: Update package lock

* chore: Run `npm audit fix`

* feat: UI WIP

* feat: UI

* refactor: Desktop Icon Strip DRY

* feat: Cleaner rendering and transition for ChatScreen

* feat: UI improvements

* feat: UI improvement

* feat: Remove MCP Server "enable" switch from Tools submenu

* chore: Run `npm audit fix`

* feat: WIP

* feat: Logic improvements

* refactor: Cleanup

* refactor: DRY

* test: Fix Chat Sidebar UI Tests

* chore: Update package lock

* refactor: Cleanup

* feat: Chat Message Action Card with Continue and Permission flow implementations

* feat: Add agentic steering messages, draft messages and improve chat UX

* fix: Search results UI

* test: Fix unit test

* feat: UI/UX improvements

* refactor: Simplify `useToolsPanel` access in components

* feat: Implement Processing Info Context API

* feat: Implement 'Go back to chat' functionality for settings

* feat: Enhance MCP Server management in Chat Form Attachments

* style: Minor UI and branding adjustments

* chore: Update webui static build output

* chore: Formatting, linting & type checks

* feat: Draft messages logic

* feat: UI improvements

* feat: Steering Messages improvements

* refactor: Cleanup

* refactor: Cleanup

* feat: Improve UI

* refactor: Settings navigation hook

* refactor: DRY code

* refactor: DRY ChatMessageUser UI components

* refactor: Desktop Icon Strip DRY

* refactor: Tools & permissions

* fix: Navigation condition

* refactor: Cleanup

* refactor: Cleanup

* refactor: Cleanup

* fix: preserve reasoning_content in agentic flow

---------

Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
…ogic (ggml-org#22456)

* Refactor buffer aliasing to be part of shader lib decisions

* cleanup

* formatting
Some SPIR-V compilers (notably mesa) don't handle the current
vulkan Q4_K/Q5_K scale load pattern in mul_mat particularly well.
While reading three `u8`s from the 12-byte scale array should (at
least on some hardware) result in loading the full 12 bytes in a
single LOAD followed by whatever extraction is needed, at least
the ANV Intel driver really can't practically perform this
optimization.

`mesa`'s unsigned upper bound logic doesn't handle tracking bounds
through ternary, resulting in the `(is < 4) ? ... : is - 4` having
an infinite upper bound (as it cannot prove `is - 4` doesn't
underflow). While this could still be rectified if mesa looked at
the array bounds, it currently doesn't and `glslc` currently emits
SPIR-V that doesn't allow for this optimization anyway (though
maybe it will at some point, see
KhronosGroup/glslang#4206).

In mul_mat_vecq we took a different approach to loading the same
fields. We read the first two bytes we needed from `scale` then
took a branch before deciding whether we needed to read a third
byte. In mesa this did, indeed, lead to a top-level branch with
conditional loads. As such these loads ended up not being
coalesced either (at least in the ANV driver) resulting in
additional instructions in our hot loop.

Instead, here, we go ahead and force loading the full 12 bytes and
extract the bits we need from the packed-u32s instead. In mul_mat
there's a few less ternaries and only one extra shift, so even on
drivers that did optimize the previous loads properly the only
material change should be pulling a few extra bytes into registers
(which on most hardware won't cost anything anyway, though
ironically on Intel it theoretically could). In mul_mat_vecq this
requires a bit of extra math and may read bytes from the u32 that
weren't needed, but it seems likely avoiding the branch is a win
on most platforms.

On Intel Xe2/mesa 26.0.4 with the optimizations from
https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15162,

for shader matmul_id_subgroup_q4_k_f32_f16acc_aligned_l:
 * Instruction Count: 2753 -> 2688
 * SEND Count: 269 -> 261
 * Cycle Count: 273976 -> 266138
 * Max live registers: 248 -> 246
 * Non SSA regs after NIR: 381 -> 382

for shader matmul_id_subgroup_q5_k_f32_f16acc_aligned_l:
 * Instruction Count: 2767 -> 2702
 * SEND Count: 271 -> 263
 * Cycle Count: 274140 -> 268144
 * Max live registers: 248 -> 246
 * Non SSA regs after NIR: 381 -> 382

for shader mul_mat_vec_id_q4_k_q8_1_f32:
 * Instruction Count: 1930 -> 1646
 * SEND Count: 116 -> 71
 * Cycle Count: 1348306 -> 843350
 * Max live registers: 78 -> 84
 * Non SSA regs after NIR: 300 -> 135

for shader mul_mat_vec_id_q5_k_q8_1_f32:
 * Instruction Count: 2207 -> 1922
 * SEND Count: 131 -> 86
 * Cycle Count: 1392012 -> 1037836
 * Max live registers: 90 -> 90
 * Non SSA regs after NIR: 300 -> 135

for shader mul_mat_vec_q4_k_q8_1_f32:
 * Instruction Count: 2029 -> 1749
 * SEND Count: 111 -> 66
 * Cycle Count: 1347278 -> 840118
 * Max live registers: 74 -> 80
 * Non SSA regs after NIR: 299 -> 134

for shader mul_mat_vec_q5_k_q8_1_f32:
 * Instruction Count: 2307 -> 2022
 * SEND Count: 126 -> 81
 * Cycle Count: 1379820 -> 954042
 * Max live registers: 86 -> 86
 * Non SSA regs after NIR: 299 -> 134

On one Arc Pro B60, unsloth/Qwen3.5-35B-A3B-GGUF:UD-Q4_K_XL:
 * pp512: 907.34 ± 9.28 -> 941.94 ± 10.53 (+4%)
 * pp2048: 897.95 ± 1.82 -> 931.55 ± 1.79 (+4%)
 * tg128: 49.49 ± 0.02 -> 49.86 ± 0.05 (+ <1%)

On one Arc Pro B60, unsloth/Qwen3.5-27B-GGUF:Q4_K_S:
 * pp512: 324.13 ± 10.52 -> 354.33 ± 6.81 (+9%)
 * pp2048: 329.80 ± 0.25 -> 357.10 ± 0.06 (+8%)
 * tg128: 17.11 ± 0.01 -> 18.11 ± 0.01 (+6%)

On four Arc Pro B60s, unsloth/Qwen3.5-122B-A10B-GGUF:Q5_K_S with
-sm layer (note that -sm tensor improvements will naturally be
less):
 * pp512: 264.55 ± 2.81 -> 280.45 ± 3.94 (+6%)
 * pp2048: 319.32 ± 2.72 -> 335.70 ± 3.48 (+5%)
 * tg128: 26.39 ± 0.01 -> 26.67 ± 0.01 (+1%)
…22323)

DONE state absorbs all tokens including a new start tag, causing any think blocks after the first to run unbudgeted. Observed on unsloth/Qwen3.6-27B-GGUF which interleaves multiple <think> blocks per response.

Fixed by advancing start_matcher in DONE branch and re-arming to COUNTING with a fresh budget on match. Adds regression test (test-reasoning-budget: test 6).
This commit adds support for NVIDIA Nemotron Nano 3 Omni model enabling
this model to be converted to GGUF.
ggml-org#22286)

* ggml-cuda: add flash-attn support for DKQ=320/DV=256 with ncols2=32 (GQA=32)

Adds MMA-f16 and tile kernel configs, dispatch logic, template instances,
and tile .cu file for Mistral Small 4 (head sizes 320/256), restricting to
ncols2=32 to support GQA ratio 32 only.

* Adding check to return BEST_FATTN_KERNEL_NONE in case GQA!=32

* Apply suggestions from code review

Address review comments

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>

* Address review comments and making kernel config default to DQK=512, DV=512 instead of DQK=256,DV=256

* Fixed bug with sinks=1, with ncols=32, there are two warp-groups created but sinks index is same(0,...,15) for both the groups hence with sinks=1, output is not matching with CPU output. Added sink_base which will be base index for each warp_group (threadIdx.y / np)

* Apply suggestions from code review

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>

* Update ggml/src/ggml-cuda/template-instances/generate_cu_files.py

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>

---------

Co-authored-by: Johannes Gäßler <johannesg@5d6.de>
…1916)

* Added sve tuned code for gemm_q8_0_4x8_q8_0() kernel

* Change arrays to static const in repack.cpp

---------

Co-authored-by: Vithulep <prashant.vithule@fujitsu.com>
…gml-org#22273)

* Changed to leak logger singleton to prevent hanging on Windows

* Fix comment

* Stopped using static vector

Using std::vector will cause g_col to be released before the logger thread exits, causing the logger thread to touch freed memory causing a crash

* Change so all logs are output before exit

* Added debug logging

* added more logging

* Added logging

* Explicitly free logger to avoid hanging on Win

* Reverted to leak logger instance again

* Removed debug log and fixed comment

* Fixed comment

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
* Fix flashattention support check for devices that don't support subgroups

* set path to none if kv_tile doesn't fit
…2317)

* ggml-cpu: cmake: append xsmtvdotii march for SpacemiT IME

When GGML_CPU_RISCV64_SPACEMIT=ON is set, ime1_kernels.cpp contains
inline asm for the vmadot family which requires the xsmtvdotii custom
extension.(problem can see in some blogs and make sure in K3 platform)
The current CMakeLists does not include xsmtvdotii, so any toolchain
that honours the explicit -march (tested with SpacemiT GCC 15.2) fails
at the assembler stage:

  Error: unrecognized opcode `vmadot v16,v14,v0',
         extension `xsmtvdotii' required

Append _xsmtvdotii to MARCH_STR when GGML_CPU_RISCV64_SPACEMIT is
enabled so the IME path can actually build with a capable toolchain.
No effect on builds that leave GGML_CPU_RISCV64_SPACEMIT off.

toolchain from https://www.spacemit.com/community/resources-download/Tools

* Update ggml/src/ggml-cpu/CMakeLists.txt

Co-authored-by: alex-spacemit <jinghui.huang@spacemit.com>

---------

Co-authored-by: alex-spacemit <jinghui.huang@spacemit.com>
* ggml-cuda: refactor fusion code

* apply formatting + make env variable truthy
…gml-org#22293)

* ggml-cpu : disable tiled matmul on AIX to fix page boundary segfault

vec_xst operations in the tiled path crash on AIX when writing
near 4KB page boundaries due to strict memory protection. Fall
back to mnpack implementation on AIX for stable execution.

Signed-off-by: Shalini Salomi Bodapati <Shalini.Salomi.Bodapati@ibm.com>

* Update ggml/src/ggml-cpu/llamafile/sgemm.cpp

Co-authored-by: Aaron Teo <taronaeo@gmail.com>

* Update sgemm.cpp

* Update sgemm.cpp

---------

Signed-off-by: Shalini Salomi Bodapati <Shalini.Salomi.Bodapati@ibm.com>
Co-authored-by: Aaron Teo <taronaeo@gmail.com>
* webui: instant mic stop, race-free recorder restart

* webui: faster WAV PCM encode via hoisted channels and Int16Array

* chore: update webui build output

* webui: drop setTimeout(0) hack and harden cancelRecording

* chore: update webui build output
* hexagon: allow host to set max vmem size

We use a sane default but it's helpful to allow for an override if needed.

* hexagon: add support for measuring vmem space and move pinned mmaping management to host

* hexagon: update vmem checks to use uint64

* hexagon: bump op buffers to 16 (matches max mmaps)

* hexagon: bump default vmem to 3.2GB

* hexagon: add support for autodetecting vmem space and some logging cleanup in that area

* hexagon: fix whitespace warnings

* Update scripts/snapdragon/adb/run-cli.sh

Co-authored-by: Pascal <admin@serveurperso.com>

* hex-adb: fix run-completion script

---------

Co-authored-by: Pascal <admin@serveurperso.com>
* port ggml-org#22358 PR to examples/speculative/speculative.cpp
* use vocab_[tgt,dft] instead of ctx_[tgt,dft] when logging on draft
  model / target model vocabulary mismatch

Co-authored-by: Petros Sideris <petros.sideris@nokia.com>
* spec : fix draft model checkpoints

* cont : clean-up

* cont : gate the ngram-mod reset warning behind verbose flag
…22513)

* scripts : add wc2wt.sh - create worktree from current HEAD

Add a script to create a git worktree on a new branch from the current
HEAD. Similar to pr2wt.sh but for local development branches instead of
PRs.

Usage:
  ./scripts/wc2wt.sh gg/new-feature
  ./scripts/wc2wt.sh gg/new-feature "bash -l"

Assisted-by: llama.cpp:local pi

* cont : no need to try to delete the branch
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
* bump ty to 0.0.33

* update typings
pwilkin and others added 15 commits May 15, 2026 15:18
* move conversion code to a dedicated conversion directory and split the files akin to the src/models architecture

---------

Co-authored-by: Sigbjørn Skjæret <sigbjorn.skjaeret@scala.com>
* mtmd: add chunks and fix preproc for qwen3a

* add attn_mask

* limit mtmd_chunk size (avoid blow up memory)

* correct audio tokens

* re-order the set_input case

* remove attn_mask
)

* docs: document `usage` object in server timings response

Co-Authored-By: julien-agent <Agents+cyolo@huggingface.co>

* Apply suggestion from @julien-c

---------

Co-authored-by: julien-agent <Agents+cyolo@huggingface.co>
…g#22689)

The MUL_MAT test loop iterates over base_types[] to generate non-contig
permutation cases (3 standard permutations across n in {1, 8, 16}).
BF16 is absent from base_types[], so these 9 cases were never generated
for BF16 even though every other type covered by base_types[] tests them.

Add the missing 9 cases explicitly: BF16 x F32, m=16, k=256, bs=[2,3],
permutations {0,2,1,3}, {0,1,3,2}, {0,3,2,1}, with n in {1, 8, 16}.

Suggested-by: @jeffbolznv
…a-ui` / `LLAMA_UI` naming (ggml-org#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>
…ith Spring Cleaning Refactor reconciliation

Linear single-commit form of merge commit 40cbfa7d7 (branch ht-merged-2026-05-12) for fork-sync workflow compatibility. Tree byte-identical to that merge commit.

Audit baseline: 10/10 subsystems at parity vs deployed origin/ht @ 5be5481 (source-only, generated artifacts excluded).
Type check: 0 errors.
Three runtime-verify items deferred to titan smoke per #38: TTS autoplay, regenerate handler, user message content rendering.
Three ESLint rules scoped-disabled for this commit with tighten-up tracked in #38.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The 2026-05-12 ht->upstream merge silently overwrote 4 files with
upstream/master's versions, dropping HT intent that was caught only
by the audit gate's TurboQuant identifier regex:

- ggml/src/ggml-cpu/arch-fallback.h:
    16 ggml_vec_dot_tbq{3,4}_0_q8_K_generic fallback macros across 8
    arch sections + 2 q1_0 fallbacks. Runtime impact: non-x86 archs
    lost tbq3_0/tbq4_0 SIMD dispatch.
- tools/cli/README.md, tools/completion/README.md, tools/server/README.md:
    tbq3_0/tbq4_0 entries in --cache-type-k/v allowed-values tables
    + other HT-specific README additions (81/28/128 lines respectively).

Restored by `git checkout origin/ht -- <files>`. Verified safe by
diff against upstream/master: arch-fallback.h additions are pure
(no upstream-side deletions in HT-modified regions); README diffs
are HT prose additions that upstream did not concurrently modify
in the relevant tables.

Audit-gate after restore: 10/10 PASS (TurboQuant 265=265).

Follow-up filed in #38: diff upstream/master vs origin/ht for the
3 README files to identify any upstream prose additions worth
backporting (low-priority polish).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… lambda

Yesterday's ht->upstream merge reconciled origin/ht's inline stop-timeout
setter (originally a plain for-loop inside load_models) into upstream's
new `apply_stop_timeout = [&]() { ... }` lambda structure but silently
dropped the close-brace for the catch block:

    } catch (...) {
        SRV_WRN("invalid stop-timeout value '%s' for model '%s', using default %d seconds\n",
            val.c_str(), name.c_str(), DEFAULT_STOP_TIMEOUT);
        inst.meta.stop_timeout = DEFAULT_STOP_TIMEOUT;
+   }       <-- missing
    }
}
};

Effect: the lambda body never closed; every subsequent definition
(member-function and free-function alike) was parsed inside the lambda.
The compiler produced ~200 errors of the form "qualified-id in
declaration before '(' token" cascading from line 546 onward and
ultimately "expected '}' at end of input" matching the unclosed brace
at the top of load_models().

Why this wasn't caught before:
- audit-gate: counts identifier occurrences (LoRA/TBQ/etc); a missing
  brace doesn't change identifier counts. 01_LoRA reads 41=41 PASS.
- npm run check / npm run lint: webui-only (TypeScript/Svelte). C++
  was never exercised.
- The C++ build never ran on ht-linear before today; the rebase was
  evaluated entirely through webui gates.

The fix is one line. Build now produces a 10.4MB llama-server binary
that lists `tbq3_0, tbq4_0` in `--cache-type-{k,v}` allowed values (end-
to-end TBQ wiring + arch-fallback.h restoration verified against a
built-from-ht-linear binary).

Filed as drift-pattern #9 in #38: drift-zero verification must cover
ALL surfaces of the fork (C++ build included), not only the layer that
produced the most surfaced errors in a given session.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
After replaying HT-only commits onto master @ 253ba11, two webui sites
needed reconciliation with upstream's autoscroll rework (320a6a4 +
dded58b) and the missing pending-steering-message wiring:

- ChatScreen.svelte: drop the .chat-scroll-container CSS + flex-col-reverse
  remnant. Upstream's new auto-scroll controller no longer takes
  isColumnReverse, so the column-reverse hack is moot.
- ChatMessages.svelte: revert the conflict-resolution that pulled in
  upstream's pending-steering-message block — the supporting modules
  (agenticPendingSteeringMessageContent, chatStore.abortCurrentFlow, etc.)
  are not yet wired up on the HT side. Leaving the UI to a follow-up
  port when we land continue-on-reasoning support.

Also flushes `prettier --write .` across the working tree to settle the
formatting drift the rebase introduced (eslint.config.js + a handful of
HT-only test fixtures and utils). Pure formatting changes elsewhere.

Note: b9df5c0 ("fix(webui): real drift-zero — revert eslint waivers
+ strategy-(b) refactors") was skipped during the rebase. That commit
was a transitional cleanup of strategy-(b) duplicates from the 2026-05-12
rebase, but upstream has since adopted the nested ChatMessage/ structure
and several of its file deletions would now strand active upstream
components. The three eslint waivers it removed remain in place — they
no longer mask 89 errors after the post-rebase state, and the lint is
clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…loses #38)

The May 12 rebase landed with ChatMessageActions aliased to
ChatMessageActionCard (the thin 33-line card with {icon, message,
actions} Props) instead of ChatMessageActionIcons (the 215-line rich
icon-row that is the actual toolbar). Every message variant lost its
copy/edit/regenerate/speak buttons; the bug was silent because the
card component renders without error, it just renders the wrong thing.

The fix is the one-line alias swap. Its cost is visibility of the
Props mismatch: the two components have different Props shapes, so
the ~20 caller sites that pass {icon, message, actions} now type-fail
against ChatMessageActionIcons. b9df5c0 had the full surgery to
narrow Props back to upstream's shape, but skipping that commit on
the post-ggml-org#22937 rebase was deliberate (much of its body would strand
active upstream components). Re-derivation against the current
upstream surface is tracked as the strategy-(b) follow-up — see the
107-lint-error visible-debt commit on the same branch.

Visible debt after this commit:

  svelte-check          13 errors  (Props shape mismatches)
  eslint                107 errors (from prior waiver revert)
  ────────────────────────────────────────────────────
  total                 120

Both numbers feed the same goalpost. Pre-commit + CI will fail until
the cleanup lands — bypassed locally via --no-verify per the
fork-manager visible-debt directive.

Closes #38

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The gemma-4 PEG grammar was missing the p.end() terminator that every
other tool-calling grammar in chat.cpp uses. Without it, the lazy
grammar's tool_call repeat (max = -1 when parallel_tool_calls=true)
accepts arbitrarily-long output: the model can emit tool calls,
reasoning, content, more tool calls — indefinitely — until it happens
to sample <end_of_turn> on its own.

IQ4_XS in particular degrades the model's ability to emit
<end_of_turn> after <tool_call|>, producing runaway streams that the
client sees as indefinite "executing..." spinners while tokens keep
flowing (observed on gemma-4 31B IQ4_XS at 14,547 output tokens in a
single turn before manual cancellation).

Adds p.end() to the two grammar-constrained paths (with-tools and
response-format), forcing the model to terminate at the structurally
correct point. The no-tools path is intentionally left without
p.end() — it is the parser-only path (no grammar constrains
generation), and the existing tests verify it must tolerate gemma-4's
normal trailing <channel|> tokens.

Verified with the IQ4_XS quant locally: parallel fetch_image +
generate_video tool call now terminates in ~6s with finish_reason
"tool_calls" and 177 completion tokens (was unbounded). test-chat
and test-chat-peg-parser both clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
marksverdhei and others added 5 commits May 16, 2026 16:33
Drops in the canonical aioc workflow per
heiervang-technologies/am-i-openai-compatible/examples/ci/llama-cpp.yml,
adapted for this fork. Builds llama-server from the PR, boots it on
ggml-org/test-model-stories260K with --embeddings, and probes the
OpenAI API surface via the aioc action (v0.1.1-pre1).

Triggers only on PRs that touch tools/server/** or this workflow.
fail-on: FAIL — WARN rows (capability-gated audio/image endpoints
without the ComfyUI proxy, /v1/models/{id} on vanilla llama-server,
etc.) are reported but don't fail the job. v0.1.1-pre1 is not on PyPI
yet, so both the action and aioc-version are pinned to the git ref.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v0.2.0 adds the HT-compat profile (--profile ht) which probes five
new model-class endpoints beyond OpenAI's surface: /v1/reranking,
/v1/segmentations, /v1/audio/segmentations, /v1/chat/completions[omni],
/v1/images/decompositions. See spec at:
  heiervang-technologies/am-i-openai-compatible @ docs/spec/ht-compat.md

ht-llama.cpp currently implements 0/5 HT endpoints (per the matrix),
so all five will report 404 → FAIL under the ht profile. `fail-on: WARN`
keeps the build green while making the missing-rows visible in the
GitHub step summary. Flip to `fail-on: FAIL` once the first HT
endpoint lands (most likely candidate: /v1/reranking — llama.cpp has
the rerank pipeline).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
openai-compat-expert flagged the recipe was wrong:
- fail-on: WARN means STRICTER (fail on WARN or worse), not lenient
- For a fork that ships 0/5 HT endpoints today, the right setting is
  fail-on: none — report-only, never gate the build on row counts
- Flip to fail-on: FAIL (the action's default) once the first HT
  endpoint lands and we want regression gating

Also adds report-path so the JSON report is uploaded as an artifact.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
v0.2.0-pre2 incorporates the spec review I sent for v0.2.0-pre1:

- reranking: Cohere v2 results[].document.text shape pinned for
  return_documents=true; id prefixes called out as illustrative
- segmentations: normalized [0,1] coords as deliberate divergence
  with rationale; SAM all-prompts-collapse convention documented;
  COCO-RLE pinned to compressed counts-string form
- audio segmentations: sources[].format echo required; ms throughout
- omni (chat/completions[omni]): voice is impl-defined
  (discoverable via /v1/audio/voices) — ht-llama.cpp's ref-audio-
  clone TTS is in-spec; input_audio.format extended to wav/mp3/flac/
  ogg/m4a; 400 for unsupported_audio_format vs 501 for unsupported
  modalities; v1.0 = base64-per-turn; streaming chunk framing
  impl-defined
- decompositions: composite + layers[] share {index, label,
  b64_json, bbox} shape; label-stability non-required

Matrix scope-per-fork now explicit that ht-llama.cpp's plausible
HT-compat surface is reranking + omni-via-proxy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The existing /v1/reranking endpoint (server.cpp:197, format_response_rerank)
already returns Cohere-shaped results in non-TEI mode but was missing
two HT-compat-1.0 deliverables:

1. Top-level `id` field. HT-compat spec example uses `rerank-...`
   prefix (illustrative per pre2 revision). Adds gen_rerankid()
   returning "rerank-" + random_string(), mirroring the existing
   gen_chatcmplid() pattern.
2. `return_documents: true` request handling. TEI shape already
   honors `return_text` for items; Cohere/HT-compat uses
   `return_documents` and expects results[].document.text. Adds
   parallel branch so callers picking the Cohere/HT-compat path
   get the document text echoed inline. TEI path unchanged.

Test surface: aioc compat probe under --profile ht should flip the
/v1/reranking row for ht-llama.cpp from FAIL (404 was wrong; the
endpoint exists but shape didn't match) to PASS once the server
boots with --reranking.

Spec: heiervang-technologies/am-i-openai-compatible @ v0.2.0-pre2
      docs/spec/ht-compat.md § /v1/reranking
Matrix entry: ht-llama.cpp /v1/reranking ❌ → ✅ expected next run.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@marksverdhei
marksverdhei force-pushed the feat/ci-aioc-compat-probe branch from eb7bf38 to 8ced820 Compare May 16, 2026 14:33
)

Extends the aioc compat probe workflow to flip /v1/reranking from
Phase B SKIP → PASS by side-loading a tiny rerank-named model.

Implementation: llama-server now boots in **router mode** with a
preset INI defining two models:

  1. ggml-org/test-model-stories260K (~1 MB) — chat/completions,
     embeddings. Phase B coverage preserved.
  2. jimi0209/bge-reranker-base-Q5_K_M-GGUF (~228 MB) — rerank kind.
     aioc's _classify_kind tags by name substring, so the "rerank"
     substring in the repo id is what triggers Phase B for
     /v1/reranking. Boots with reranking = true (sets embedding=true
     + pooling_type=LLAMA_POOLING_TYPE_RANK as required by
     server-context.cpp:4129).

Both presets use load-on-startup = 1 so the probe doesn't trip the
autoload cold path on its first request. Readiness check waits for
both models to appear in /v1/models (3-min budget for the reranker
download on a clean runner).

Adds an upload-artifact step so the JSON report is retained even on
FAIL/WARN runs — makes regression triage faster.

Note: --models-preset is already the preset-INI entrypoint
(server-models.cpp:280 path), and `embeddings` / `reranking` are
both valid INI keys (they map to --embeddings / --rerank in
common/arg.cpp).
@marksverdhei marksverdhei changed the title ci+server: aioc HT-compat probe workflow + first HT endpoint (/v1/reranking) ci+server: aioc HT-compat probe + /v1/reranking Phase A & B coverage May 16, 2026
@marksverdhei

Copy link
Copy Markdown
Author

Cherry-picked onto rolled-back ht by feature-parity restoration after the 2026-05-12 rebase rollback.

@marksverdhei
marksverdhei deleted the feat/ci-aioc-compat-probe branch May 17, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci(aioc): extend workflow for /v1/reranking Phase B coverage