Commit Graph

689 Commits

Author SHA1 Message Date
Georgi Gerganov
992c325323 server : add trace logging for slot similarity checking (#26271)
Adds trace logging in server-context.cpp for slot similarity checking
during prompt cache slot selection, including skip reasons and similarity
calculation details.

Assisted-by: llama.cpp:Qwen3.6-27B
2026-07-29 14:59:44 +03:00
Xuan-Son Nguyen
ee3d1b54c1 server: abstract llama_memory calls to common_memory (#26221) 2026-07-28 16:35:20 +02:00
王金旭
84075273c8 spec: add DSpark speculative decoding (#25173)
* spec: add DSpark speculative decoding

DSpark (DeepSpec, 2026) on top of the merged DFlash drafter. It reuses the
DFlash encoder/decoder graph, target feature extraction and KV-cache injection,
and the verify/accept path unchanged; the draft model is a new "dspark" arch
adding a low-rank Markov head (markov_w1/w2) and an optional (unused here)
confidence head. No new public APIs.

The proposal is the only change: the block is anchor-first (position 0 already
predicts the first draft) and the decoder graph applies a semi-autoregressive,
previous-token conditioned logit bias in-graph, chained per block position:

  logits'(i) = logits(i) + markov_w2 . markov_w1[prev(i)]
  prev(0)    = the block's anchor token, prev(i>0) = argmax(logits'(i-1))

vectorized across all blocks in the batch; the anchors are fed through a
dedicated graph input (token 0 of every block). Greedy stays lossless
(verify unchanged, same as DFlash).

- new arch "dspark" (llama_model_dspark : llama_model_dflash, reuses the graph,
  loads the markov/confidence tensors; shares the target's embed/lm_head).
- Qwen3DSparkModel converter.
- new spec type "draft-dspark" (common_speculative_impl_draft_dspark :
  common_speculative_impl_draft_dflash, overrides draft() only: submits whole
  anchor-first blocks and greedily reads back the biased logits).

* spec: read draft block size in the dflash impl

* docs: add DSpark section to speculative.md

* spec: keep dspark block size read in the dspark impl

* dspark : add TODOs for incomplete parts

- confidence head is loaded but not used yet
- confidence-scheduled prefix pruning is not implemented
- the in-graph Markov chain is greedy-only
- only Qwen3 backbones are supported for now (also noted in docs)

* spec: fold DSpark into the DFlash arch

Address review: drop LLM_ARCH_DSPARK and the dspark.block_size /
markov_rank GGUF keys. A DSpark draft now converts to a DFlash GGUF;
the Markov head tensors are detected by presence (like eagle3 d2t),
block_size is read from the existing dflash.block_size key, and the
block anchors are taken as a strided view of the decoder's token
input instead of a separate graph input.

* spec: add confidence-based draft pruning for DSpark

The DSpark confidence head predicts per-position acceptance of the
drafted block. --spec-draft-conf-min truncates the block at the first
position below the threshold (default 0 = disabled).

* fold the dspark impl into dflash, selected by spec type

* address review comments

* dspark: clean up and improve naming

* update readme

* remove trailing whitespace

* dflash: draft full n_max blocks, defer dp.n_max to the central truncation

The DSpark markov head views the draft batch as a uniform [n_seqs x block]
grid, but the per-seq dp.n_max clamp could produce blocks of different
sizes, silently corrupting the strided views and the resulting logits.

Drop the clamp and always draft the full n_max block for every sequence:
dp.n_max is already enforced by the central truncation in
common_speculative_draft(), the same way eagle3 handles it.

Co-authored-by: Zaire404 <3147879462@qq.com>

* dflash: assert the markov head block-uniformity invariant, require the conf head

With the draft batch always submitting equal-size n_max blocks, a
non-divisible token count can only mean the batch was split across
ubatches or a caller broke the layout - fail loudly instead of silently
dropping the markov bias. The block_drafts > block_size early return
stays: worst-case graph reserve passes legitimately build with
n_seq_tokens > block_size.

Also make conf_proj required when the markov head is present: the
confidence head is part of the DSpark checkpoint format, and a missing
head would otherwise leave --spec-draft-conf-min silently reading stale
embeddings instead of confidences.

Co-authored-by: Zaire404 <3147879462@qq.com>

* dspark: fold conf_min into p_min

p_min and conf_min express the same thing - the minimum predicted
survival probability for a drafted position - differing only in how the
estimate is obtained: token probability for regular drafters, the
trained confidence head for DSpark. The DSpark readback never used
p_min, so reuse it for the confidence threshold and drop the separate
--spec-draft-conf-min flag. Both defaulted to 0 (disabled), so behavior
is unchanged.

Co-authored-by: Zaire404 <3147879462@qq.com>

* dflash: note the confidence broadcast workaround

Requested in review: the ggml_repeat only adapts the [1, n_tok]
confidences to the n_embd-wide embd_nextn transport so that
llama_get_embeddings_nextn can be reused - not a placeholder.

Co-authored-by: Zaire404 <3147879462@qq.com>

* cont : clarify

[no ci]

---------

Co-authored-by: Ruixiang Wang <wangruixiang07@outlook.com>
Co-authored-by: Zaire404 <3147879462@qq.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
2026-07-28 14:43:27 +03:00
Georgi Gerganov
9a3bf2b849 server : add extra trace log for prompt similarity (#26218) 2026-07-28 11:05:16 +03:00
Aaron Teo
ad256ded30 args: add -lm mlock where it mlocks but doesnt mmap (#26135)
* arg: add `-lm mlock` where it mlocks but doesnt mmap

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: rm unwanted docs changes

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: revert auto-formatting

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* bench: fix automated review point 3

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: revert the meaning of --mlock to non-mmap'ed mlock

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: update docs

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: remove extra changes from `llama-gen-docs`

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

---------

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>
2026-07-27 16:44:08 +08:00
Pascal
d73c1d6b22 server + ui: fix stream routes for model names containing a slash (#26137)
* server + ui: refactor resumable stream routes to query string conv_id

The conversation id can embed a model name containing slashes
(ggml-org/...) in router mode, which the decoded path splits before the
:conv_id param is captured, so stop and resume never matched the
session. Move the id to the conv_id query string on the public routes
and on the internal router -> child hop, where slashes survive
encoding. Handlers are unchanged since query and path params land in
the same map. Add a regression test with a slashed model name.

* server: move stream route docs to server-stream.h

Address review: ngxson wants the main server.cpp registration code kept
clean and simple, with route-level explanations living in the header.
Move the query string rationale and the lookup ownership note next to
the handler declarations in server-stream.h, and shorten the wiring
comment to a pointer.

* server: cancel a pending request when its stream is stopped during model load

The conversation was registered in the conv map only after the blocking
autoload wait, so a stop issued while the model loaded found nothing to
cancel and the request went on to generate an orphan once the load
ended. Register the conversation before the wait and give the entry a
ticket: a stop erases the entry, and the parked request checks its
ticket after the wait and aborts with 400 instead of starting. A newer
request on the same conversation replaces the entry, so only the
stopped request is cancelled. Add a regression test that stops during
the load window.

* server + ui: resume a stream after a page reload during model load

A pending request died with the client socket when the page was
reloaded while its model was loading, so no session ever existed and
the conversation had nothing to recover. A session request that waited
for a load now detaches from the client socket and reaches the child
regardless, the session buffer receives the generation, and the resume
route answers 503 while the owner is loading so the client retries
instead of dropping its state. The WebUI persists the pending stream at
send time, quietly polls on 503, and attaches once the session exists.
Add a regression test that drops the client during the load window.

* ui: show the model load progress again after a page refresh

The resume wait was invisible, so a conversation refreshed while its
model was loading showed nothing until the first byte. On a 503 from
the resume probe, mark the conversation as loading again so the
assistant row persisted at send time renders the processing info, and
target the model frozen in the persisted stream state for the
progress, since the row has no model yet and the dropdown may not be
restored.

* fix CI

* fix CI bis
2026-07-27 07:34:47 +02:00
Xuan-Son Nguyen
d2a818231e common: add subproc.h wrapper, disabled on android/ios (#26102)
* add common/subproc.h|cpp

* add compile flag LLAMA_SUBPROCESS

* disabled by default on android and ios

* test-jinja: use common subproc

* mtmd: disable video if subproc is not set

* disable subproc on wasm

* make is_created atomic

* migrate server-mcp
2026-07-26 20:54:25 +02:00
Xuan-Son Nguyen
20455a4ad3 server: support MCP stdio (#26062)
* move server_pipe to common

* init impl

* vendor: update subprocess.h

* add server_mcp_stdio

* stderr drain

* server_mcp_transport

* server_mcp_stdio is now framing-only, no json

* internal/mcp-stdio: integration + tests + fixes (#26075)

* server-mcp: harden transport and wire up the tool integration

Builds on the transport/manager architecture (server_mcp_transport + server_pipe)
with the hardening and integration the draft did not yet have.

Hardening:
* Reader and stderr pumps are polled (running-aware) instead of blocking on a read
  that only ends at EOF. subprocess_terminate() SIGKILLs only the direct child, so a
  grandchild the MCP server spawned that inherited the pipe would otherwise keep the
  write end open and hang teardown (both warmup shutdown at startup and process
  shutdown). The writer is likewise non-blocking + polled.
* Windows: resolve the command through PATHEXT so "npx" (npm ships npx.cmd, never
  npx.exe) spawns, matching POSIX's PATH search; and enumerate the parent environment
  as UTF-8 (GetEnvironmentStringsW) instead of the active code page.
* server_pipe gains an opt-in max_size (default unbounded, so the router's streaming
  use is unchanged); the MCP reply queue uses it so a server that streams unsolicited
  notifications between requests cannot grow it without bound.

Integration:
* --mcp-servers-config / --mcp-servers-json flags; enabling MCP restricts default CORS
  to localhost, same as --tools.
* MCP tools are exposed through /tools (and chat-completions) as <server>_<tool>,
  skipping names that collide with a built-in or another MCP tool.
* Manager lifecycle wired into llama_server(): warmup at start, shutdown() from the
  signal handler before the HTTP server drains, blocking teardown in clean_up().
* SIGPIPE ignored so a child dying mid-write yields EPIPE rather than killing us.

Assisted-By: Claude Opus 4.8 <noreply@anthropic.com>

* server-mcp: add MCP test suite with grandchild deadlock regression test

21 tests over the /tools endpoint: tool discovery/invocation, timeouts, crash
recovery and respawn cooldown, warmup partial failure, malformed and batched
notification+response output, tool-definition shape, and prompt shutdown during a
slow call.

The last test spawns an MCP server that leaves a grandchild inheriting its
stdout/stderr and asserts the server both starts and stops promptly. Verified it
fails (5s SIGKILL fallback on a deadlocked reader-join) when the pump is made to
ignore the running flag, and passes with the polled reader.

Assisted-By: Claude Opus 4.8 <noreply@anthropic.com>

* clean up

* clean up 2

* even stricter life cycle

* nits

* nits 2

---------

Co-authored-by: Xuan Son Nguyen <son@huggingface.co>

* fix some edge cases

* fix last_error data race

* fix response schema + docs

* server: fix MCP zombie leak and timeout-induced transport teardown

join_pumps() never reaped the child, leaking one zombie per spawn:
call subprocess_join() before subprocess_destroy().

A per-call timeout permanently closed from_server and got a healthy
transport evicted: add close_on_stop to server_pipe::read() and pass
false from send_rpc(), where should_stop is a per-request deadline
and a late reply is already skipped on id mismatch.

Also drop the unreachable disconnect cancellation in
server_mcp_tool::invoke(): support_stream is false, st is always null.

(cherry picked from commit e6de1ec043174fd0570b1e60d47f06c7c19d620d)

Assisted-by: Claude Opus 4.8

* server: make MCP test fixtures JSON-RPC 2.0 compliant

Add the missing notification guard to mcp_malformed_server.py and
mcp_burst_server.py (the latter treated id 0 as a notification and
replied to unknown ones; its notification table is now unused).

Return -32602 instead of -32601 for unknown tools: tools/call is a
valid method, the tool name is the invalid parameter.

Also fix the test module docstring: tools are named <server>_<tool>.

(cherry picked from commit 74a08e8c311dabf3b49d06cc6d754b0097ae7a38)

Assisted-by: Claude Opus 4.8

---------

Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
Co-authored-by: Pascal <admin@serveurperso.com>
2026-07-26 01:08:49 +02:00
Xuan-Son Nguyen
abc348790e server: add format arg to datetime tool (#26117) 2026-07-25 21:15:15 +02:00
Tekin Ertekin
2cfc7670ed server : add missing task parameters(adaptive_target, adaptive_decay) in generation_settings (#25830)
These two parameters were overlooked when task parameters were being JSONized
within `generation_settings` and have been added. A regression test has been
added to prevent the problem from recurring and it passes.

Fixes #25803
2026-07-25 20:53:08 +02:00
Aldehir Rojas
910196f6b3 common : add support for multiple end sequences in the reasoning budget sampler (#25544)
* common : extract trie/ac to a separate file

* common : support multiple token sequences in the reasoning budget sampler

* common/trie : return matched word index

* common/trie : rename "word" to "pattern"

* common/reasoning-budget : expose matched end sequence

* common/sampling : replay end sequence when reasoning budget is done

* cont : update to use multiple end sequences

* cont : clean up
2026-07-25 11:58:09 +02:00
Nigel Bosch
27209a598d server: support "reasoning_effort": "none" in OAI API (#26045)
* support "reasoning_effort": "none" in OAI API

* handle reasoning.effort: "none" in OAI responses API

* clarify non-"none" values of reasoning_effort have no effect

* use json_value instead of body.at
2026-07-24 19:19:10 +02:00
Xuan-Son Nguyen
0cea36222f vendor: update subprocess.h (#26061) 2026-07-24 08:02:23 +02:00
Aaron Teo
e6dd0e29a6 args: refactor mlock/mmap/directio into load-mode (#20834)
* args: overhaul mmap/mlock/dio into single arg

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: update docs with llama-gen-docs

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* chore: satisfy code quality

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* args: make the `+` sign an actual modifier now

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* chore: general code clean up + comments

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: fix deprecated flags support

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: quick sanity check

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* bench: sync llama-bench argument parsing

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* fix: bugfix variable behaviour + llama-bench lm column size

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: inverse commands should do the opposite instead of doing nothing

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* bench: fix incorrect dash

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* bench: fix missing modifiers for deprecated flags

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* llama: switch back to thread_local

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: switch back to single enum

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: update arg docs

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* chore: fix missing `mlock` from llama_load_mode_from_str + cleanup llama-bench

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* llama: fix mlock not activating

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: add deprecation warning when old and new flags are combined

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* arg: cont add comment for todo in the future

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: sync with upstream

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

* docs: re-sync with upstream again

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>

---------

Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>
2026-07-23 20:32:56 +08:00
Pascal
fd41bf65a2 server: return 400 instead of 500 on validation error with X-Conversation-Id (#25760)
* server: return 400 instead of 500 on validation error with X-Conversation-Id

set_req() attaches the spipe as soon as the header is present, before the request
body is parsed. When params validation throws, set_next() never runs and next_orig
stays empty, so on_complete() called it and crashed with std::bad_function_call,
turning the prepared 400 JSON into a generic 500.

on_complete() now treats an empty next_orig as "streaming never started" and evicts
the session installed by set_req(), so a failed request leaves nothing behind for
discovery or replay. This also covers valid requests that carry the header but do
not stream, which previously left an empty finalized session in the map until the
GC TTL.

* ui: do not send the backend_sampling placeholder

On a fresh profile the syncable settings hold the empty string placeholder meaning
"let the server decide". Every neighbor field goes through the hasValue() guard
that filters it, except backend_sampling, which sent the placeholder verbatim and
made every default settings completion fail validation.

Guard the field with hasValue() like its neighbors. hasValue(false) is true, so an
explicit false still reaches the server and the intent of #18781 (send both true
and false) is preserved. Only the placeholder is filtered.
2026-07-21 17:47:54 +02:00
fairydreaming
40b740ad05 server : properly handle null llama_context (#25868)
Co-authored-by: Stanisław Szymczyk <sszymczy@gmail.com>
2026-07-21 17:47:17 +02:00
Georgi Gerganov
635cdd5fcc common : auto-download dflash- and eagle3- HF sidecars (#25811)
* common: auto-download dflash- and eagle3- HF sidecars

Mirror the existing mtp- sidecar logic to support auto-discovery and
download of DFlash (dflash-) and Eagle3 (eagle3-) speculative decoding
sidecars from Hugging Face repos.

Changes:
- Add --dflash and --eagle3 CLI flags to trigger sidecar download
- Add find_best_dflash() and find_best_eagle3() using find_best_sibling
- Exclude dflash- and eagle3- filenames from primary model selection
- Filter dflash- and eagle3- from cached model listings
- Wire download tasks that set speculative.draft.mparams as fallback

Assisted-by: pi:llama.cpp/Qwen3.6-27B

* docs : regen
2026-07-17 12:15:30 +03:00
Chipmunk
a8dc0e3269 server : allow text-only slot save/restore with mtmd (#25076) 2026-07-16 15:26:44 +03:00
Sebastian Dröge
8ee54c8b32 server: Ignore empty / non-existing Origin headers (#25756)
Otherwise this gives lots of unnecessary warnings:

  W srv    operator(): (CORS) skip non-localhost origin:
2026-07-16 12:26:51 +03:00
Gaurav Garg
956973c764 Fix crash with draft-simple (#25720)
* Fix crash with draft-simple

* Fix tests for spec decoding
2026-07-15 19:51:34 +05:30
Pascal
a582222290 server: fix read_file append_loc space breaking edit_file match (#25705)
read_file with append_loc emits "{n}\u2192 {line}". The space after the
arrow is meant as a separator, but it is indistinguishable from real
indentation. Models strip "{n}\u2192" yet keep the space, so the old_text
passed to edit_file carries a phantom leading space and never matches
(normalize_for_fuzzy_match trims trailing whitespace only, never leading).

Drop the separator space so the arrow abuts content: stripping "{n}\u2192"
now yields the exact line with its real indentation preserved, and the
failure mode cannot occur by construction. Update the description example
to match the new format.
2026-07-15 13:46:46 +02:00
Georgi Gerganov
bf2c86ddc0 server : refactor prompt cache state ownership (#25649)
* server : clear checkpoints upon prompt clear

* server : move the prompt state data to the server_prompt_cache

Assisted-by: pi:llama.cpp/Qwen3.6-27B

* server : handle batched slot being cleared
2026-07-14 18:25:52 +03:00
Xuan-Son Nguyen
6e52db5b72 server: add --cors-* options (#25655)
* server: add --cors-* options

* add special "localhost" value

* add tests

* fix test

* add link to PR
2026-07-14 17:23:44 +02:00
Bernard Ladenthin
99f3dc3229 server: honour per-request reasoning_budget_tokens in chat completions (#23116)
* server: honour per-request reasoning_budget_tokens in chat completions

The reasoning-budget block in oaicompat_chat_params_parse read only the
server-level default (opt.reasoning_budget, typically -1) and the
Anthropic-style alias thinking_budget_tokens, but never the canonical
reasoning_budget_tokens field from the request body.  Because the key
was then written into llama_params before the generic body-copy loop
ran, the copy loop found the key already present and silently skipped
the caller-supplied value.  Any per-request override (e.g. 0 to
suppress thinking entirely) was therefore discarded.

Fix: read reasoning_budget_tokens from the request body first, so the
value that reaches the sampling layer is the one the caller intended.

Add a unit test in test-chat.cpp that exercises this path via
oaicompat_chat_params_parse with a Qwen3 template (which the autoparser
detects as a thinking-capable model) and asserts the returned
llama_params carries reasoning_budget_tokens == 0.

* server: honour per-request reasoning_budget_message in chat completions

The reasoning-budget block in oaicompat_chat_params_parse wrote
reasoning_budget_message into llama_params straight from the server-level
default (opt.reasoning_budget_message) and never read the canonical
reasoning_budget_message field from the request body. Because the key
was written before the generic body-copy loop ran, that loop found the
key already present and silently skipped the caller-supplied value. Any
per-request override of the message injected before the end tag when the
budget is exhausted was therefore discarded, even though server-task.cpp
already reads reasoning_budget_message from that data.

This mirrors the reasoning_budget_tokens bug fixed in the previous commit.

Fix: read reasoning_budget_message from the request body first, falling
back to the server default, so the value that reaches the sampling layer
is the one the caller intended.

While here, collapse the adjacent reasoning_budget_tokens override to a
single json_value() call; json_value already falls back to the default on
a missing/null/wrong-type key, so the explicit body.contains() guard was
redundant. No behavioral change.

Add a unit test in test-chat.cpp that exercises this path via
oaicompat_chat_params_parse with a Qwen3 template (which the autoparser
detects as a thinking-capable model) and asserts the returned
llama_params carries the per-request reasoning_budget_message rather than
the server default.

* cleanup

---------

Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
2026-07-13 01:58:44 +02:00
Sebastian Dröge
8014d2cf97 server: Don't consider models with --no-mmproj-auto as multimodal (#25590)
If mmproj is explicitly disabled via the model preset or command-line
parameters then the model won't be able to handle image/audio inputs and
this shouldn't be declared as supported input modality on the /v1/models
endpoint.
2026-07-13 00:48:13 +02:00
Pascal
4114ba18b2 mtmd: fix silent prompt truncation on embedded NUL (#25548)
* mtmd: fix silent prompt truncation on embedded NUL

mtmd_input_text carried the prompt as a bare const char* with no
length, so a NUL byte in message content cut the prompt at the
tokenizer boundary and dropped every later message plus the assistant
marker, with no log. Add an explicit text_len and thread it through,
matching llama_tokenize and the text only path.

* cleanup

---------

Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
2026-07-13 00:47:25 +02:00
Aldehir Rojas
0c4fa7a989 server : evict checkpoints within min-step of each other (#25472) 2026-07-12 15:59:14 -05:00
quei
6b4dc2116a server : fix image blocks in tool_result being dropped during Anthropic OpenAI conversion (#22536)
* server : fix image blocks in tool_result being dropped during Anthropic→OpenAI conversion

server_chat_convert_anthropic_to_oai() silently discarded image blocks

inside Anthropic tool_result content. This broke multimodal tool outputs

(e.g. a tool that returns an image) because the model never received the

image.

When tool_result contains image blocks, convert them to OpenAI

multimodal content parts (text + image_url array). Plain-text results

remain simple strings for backwards compatibility.

* server : add test for image blocks in Anthropic tool_result conversion
2026-07-12 17:43:51 +02:00
Xuan-Son Nguyen
c92e806d1c server: allow stream for exec_shell_command (#25526)
* init stream

* add stream for shell tool

* add test

* nits

* update docs
2026-07-11 12:42:55 +02:00
Xuan-Son Nguyen
ea1f7bbb5d server: refactor server_stream (#25541)
* server: refactoring, remove spipe from server_http_res

* wip

* remove non-thread-safe rd.stop() call

* move server_res_spipe

* nits

* improve server_stream_create_spipe

* server-stream: update dev docs for the improved API

---------

Co-authored-by: Pascal <admin@serveurperso.com>
2026-07-11 12:41:47 +02:00
Pascal
4f37f51972 server: accept null sampling params (#25538)
* server: accept null sampling params

Extend the schema validation to treat a null value as absent, so
clients can send null on nullable params (temperature, top_p, ...)
to request the server default. This matches the OpenAI spec and the
json_value convention used elsewhere.

Add has_field() to skip null in the field eval guards.

* has_field -> has_value​
2026-07-10 22:07:29 +02:00
Xuan-Son Nguyen
a935fbffe1 server: remove loading.html (#25500)
* server: remove loading.html

* apply ui changes
2026-07-10 14:42:17 +02:00
Xuan-Son Nguyen
c4ae9a88f8 server: improve tools, remove apply_diff (#25498)
* server: improve tools, remove apply_diff

* improve edit tool

* add tools_io abstraction

* add tools_io_basic

* fix build

* move utils to class member

* add const
2026-07-10 11:52:59 +02:00
Jesse LaRose
82fce65d8b server : move chat-template thinking probe inside the init try/catch (#24093)
A model whose chat template parses at init but fails parser generation
at apply time (e.g. uses {% call %}) throws std::invalid_argument from
common_chat_templates_support_enable_thinking(), which ran outside the
try/catch guarding common_chat_templates_init(). The throw was uncaught
and llama-cli aborted (SIGABRT) instead of failing to load. Moved the
probe inside that try/catch so an apply-time error fails load the same
way an init parse error does.

Signed-off-by: Jesse LaRose <jesse@taey.ai>
2026-07-09 18:37:39 +02:00
Aldehir Rojas
64c8b7db72 server : respect min-step when splitting prompt batches (#25420) 2026-07-09 01:23:30 -05:00
Xuan-Son Nguyen
c264f65ff9 cli : move to HTTP-based implementation (#24948)
* cli: move to HTTP-based implementation

* wip

* working

* remote server ok

* cli support router mode

Co-authored-by: Piotr Wilkin <ilintar@gmail.com>

* case: router with only one model

* Apply suggestions from code review

Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>

* remove outdated comment

* use destructor instead

* add ftype

* cli-view --> cli-ui

* pimpl

* no more json in header

* nits fixes

* also show model aliases

---------

Co-authored-by: Piotr Wilkin <ilintar@gmail.com>
Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
2026-07-08 14:52:43 +02:00
Pascal
bbebeec4a8 server-stream: follow-up on SSE Replay Buffer (#23226) (#25047)
* server-stream : pimpl

* server-stream: prefix free functions with server_stream_

address review from ggerganov: scope the public stream functions under the
server_stream_ prefix, matching server_stream_session_manager_start/stop.

* server-stream: guard session and manager state with the mutex

address review from ggerganov: make done, completed_ts and the GC running flag plain members under their
mutex and set the condvar predicates under the lock. keep cancelled atomic for
the lock-free should_stop poll.

* server-stream: trim comments to the non-obvious

address review from ggerganov: drop comments that restate the code, keep the
concurrency, lifetime and ordering rationale. de-stale a few comments left by the
pimpl: g_stream_sessions is now internal and the /v1/streams listing is gone.

* server-stream: update dev docs for the pimpl and prefix

reflect server_stream_session_manager_start/stop and the server_stream_ prefix,
note the manager is now a file-static singleton hidden in the .cpp

* server-stream: move stream traces to debug level

keep the bring-up traces for diagnostics but off the default log: skip
drain, draining, drain ended, DELETE evict, attach_pipe, and the router
stream resume proxy.

* server-stream: align router stream resume proxy trace with upstream

the child-side bring-up traces are already SRV_TRC on master, move the
router stream resume proxy trace to the same level.

* server-stream: move stream_read_status enum to the cpp

it is only used by the hidden session and consumer types, so it belongs
with them behind the pimpl boundary, not on the public header surface.

---------

Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
2026-07-08 12:02:50 +03:00
rankaiyx
f296fdfbed common: auto-create prompts-log-dir at argument parsing, so all tools using the flag benefit (#25322) 2026-07-08 09:45:28 +02:00
Georgi Gerganov
c198af4dc2 spec : fix naming, spacing (#25410) 2026-07-07 18:52:30 +03:00
Alex
f5525f7e7a server : fix draft model fit vs load inconsistency (#25056)
* fix: draft model fit vs load inconsistency

* refactor(server): unify draft/mtp parameter initialization, model, and context load
- moves speculative init to speculative.cpp
- changes server_context_impl model_dft and ctx_dft to use raw pointers

- fix: don't throttle progress callback when loading draft model
- refactor: rename draft model/ctx load method

* fix: valign
2026-07-07 17:20:42 +03:00
Thomas LECONTE
5eca4e3cab server : add timings and progress to /responses API stream (#25348) 2026-07-07 16:13:03 +02:00
Thiago Padilha
6c487e2f79 server: enforce prompt cache RAM limit (#25070)
Before this commit, --cache-ram was not a hard limit:

- The cache always kept at least one entry, even if that entry exceeded the
  RAM/token limits.
- Old entries were only evicted for the RAM/token limits after saving the new
  one, which could cause the cache to temporarily exceed the RAM/token limits
  even if individual entries were below the limit.

Now, ensure that the RAM limit is strict with these changes:

- Skip saving state to cache if by itself it exceeds the RAM limit.
- Evict old entries as necessary to make the new entry fit.

Additionally, token-limit cleanup may now evict the last remaining cache entry
instead of always preserving one.
2026-07-07 15:24:35 +02:00
Pascal
9abce7473a server: fix deadlock in load_models() when erasing a finished download (#25358)
* server: fix deadlock in load_models() when erasing a finished download

The download monitoring thread acquires the models mutex on its way out,
but load_models() joined it from the erase loop while holding that mutex.
Join it outside the lock via threads_to_join like the other monitoring
threads.

* server: add default timeout to test requests

A hung server now fails the test after 10 minutes instead of stalling
the CI job for hours. Explicit timeouts are unchanged.
2026-07-06 19:26:06 +02:00
Xuan-Son Nguyen
bfdf581b8b server: temporary skip model downloading API test (#25355) 2026-07-06 16:10:04 +02:00
Pascal
b5315e16e0 server + ui: ping silent SSE streams every 1s and kick only after 3s so slow prefill never drops healthy connections (#25241)
* server + ui: ping silent SSE streams every 1s and kick only after 3s so slow prefill never drops healthy connections

* server + ui: sse_ping_interval becomes a per-request body field

Address review from ngxson: the global default returns to 30 so API
clients see no behavior change, and the WebUI sends sse_ping_interval: 1
in the request body since it owns the 3s visibility-kick contract and
declares the cadence it needs. Positive values keep the existing > 0
gate, -1 keeps its disabled semantics.

* server: move sse_ping_interval into the request schema

Address review from ngxson: the field is now a typed field_num with
hard limits (-1, INT32_MAX) bound to task_params, seeded from the CLI
default alongside the other inherited parameters. The raw json_value
read and its redundant comment are gone, and schema evaluation brings
type and range validation for free.
2026-07-03 12:47:04 +02:00
Adrien Gallouët
fdb1db877c llama : add llama_model_ftype_name() (#25134)
* llama : add llama_model_ftype_name()

Expose the model file type (quantization) name, e.g. "Q8_0" or
"Q4_K - Medium", through a new public C API. The returned pointer is
valid for the lifetime of the model and nullptr when the model is
invalid or the file type is unknown.

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

* Export enum

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

* s/llama_model_ftype_name/llama_ftype_name/

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

* Move "(guessed)" to the front in llama_ftype_name

Prepend the "(guessed)" label instead of appending it. This allows removing
the non-thread-safe static std::string, making the function allocation-free.

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

* Add LLAMA_FTYPE_PREFIX

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

* Dont check for model

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

---------

Signed-off-by: Adrien Gallouët <angt@huggingface.co>
2026-07-02 17:26:47 +02:00
Pascal
799fcc04a5 common,server: handle bracketed IPv6 literals in URL authority (#25140)
* common,server: handle bracketed IPv6 literals in URL authority

Parse the [host]:port form (RFC 3986) and bracket IPv6 hosts when
formatting a URL authority: listening log, proxy Host header, proxy
log, client rebuild. The per-request remote_addr stays bare.

* common: restore unsupported scheme throw in url parser

Address @ngxson review: keep the explicit reject in port resolution so
the block stays self-contained. Non-http(s) schemes still throw (also
gated at the top of common_http_parse_url).
2026-06-30 16:16:44 +02:00
Xuan-Son Nguyen
b3fed31b99 jinja, chat: add --reasoning-preserve flag (#25105)
* jinja, chat: add --reasoning-preserve flag

* correct help message
2026-06-28 23:33:51 +02:00
Pascal
7cb8576e7c ui: fix stop and reasoning skip in single-model mode (#25084) 2026-06-28 21:06:43 +02:00
Georgi Gerganov
27c8bb4f63 logs : reduce v2 (#25078)
* server : reduce logs

* cont : common

* cont : spec

* cont : CMN_ -> COM_
2026-06-28 08:52:15 +03:00