Commit Graph
107 Commits
Author SHA1 Message Date
antirez abd4ed3885 cli: expose exact MTP sampling mode 2026-08-23 15:05:13 +02:00
antirez 8d683d6616 dspark: add opportunistic temperature sampling 2026-08-23 15:05:13 +02:00
antirez 769a8ba42d dspark: support exact stochastic speculative decoding 2026-08-23 15:05:13 +02:00
Salvatore Sanfilippo 0ad494e514 metal: make exact fast paths automatic and trim experiments 2026-08-09 17:48:01 +02:00
antirez fd2d5e05a1 Merge Ivan Fioravanti's exact Metal MXFP4 speedups 2026-08-09 16:57:08 +02:00
ivanfioravanti 319614935f server: canonicalize OpenAI tool schema JSON spelling
Render tool schemas with stable Python-style separators and escapes so
semantically identical client JSON tokenizes the same way in the prompt.
2026-08-09 11:38:02 +02:00
ivanfioravanti 0ead8a87b0 server: recover truncated DSML tool calls 2026-08-09 11:38:02 +02:00
Salvatore Sanfilippo 8a703b6707 server: test real client disconnects 2026-08-07 10:40:02 +02:00
Matteo Collina e9ded97afe Cancel server work when clients disconnect 2026-08-05 20:45:38 +00:00
Salvatore Sanfilippo 355da75342 Add focused regressions for critical parser fixes 2026-08-04 13:47:47 +02:00
Salvatore Sanfilippo 51a1c14f35 Recover complete tool calls from unclosed reasoning
Stop relying on the model to restart a call after an injected reasoning close. Wait for a complete call, keep the preceding prose as reasoning, return the call structurally, and keep its protocol text out of streaming output.

Closes #675
2026-08-04 13:40:20 +02:00
Salvatore Sanfilippo fe2d3b0c12 Keep repeated reasoning out of streamed answers
Stop asking tool-enabled models to open a reasoning block that the prompt already opened. Hold the tentative answer until a tool call, response end, or second close marker proves whether it is answer text or another reasoning pass, for both OpenAI and Anthropic streams.

Closes #678
2026-08-04 13:35:02 +02:00
Salvatore Sanfilippo 7694112475 Reuse repeated GLM prompts by rewinding live state
When an incoming GLM prompt exactly matches the beginning of the live session, rewind one token before its boundary and reevaluate that final prompt token. This restores the correct logits without rebuilding a long prompt.

Closes #668
2026-08-04 13:32:49 +02:00
Luigi Colluto a169cffa4e Validate tool histories in linear time
Build the nearest prior call lookup while scanning forward so large Responses and Anthropic histories do not trigger repeated full-history searches.

Closes #547
2026-08-04 13:26:28 +02:00
AAB 5c318ed804 Replace owned JSON fields only after successful parsing
Parse duplicate request fields into temporary storage before releasing the previous value, and cover malformed duplicates across OpenAI, Anthropic, Responses, and tool schemas.

Closes #433
2026-08-04 13:25:50 +02:00
Luigi Colluto 8340f351a6 Reject NaN before JSON integer conversion
Clamp non-numeric and negative values before converting request fields to int, avoiding undefined floating-point conversion behavior.

Closes #541
2026-08-04 13:25:17 +02:00
Kingsley Wong 9735ad8014 Route unterminated reasoning to reasoning_content
Keep truncated DeepSeek and GLM reasoning out of the final-answer field in non-streaming responses.

Closes #509

Closes #665
2026-08-04 13:24:22 +02:00
Luigi Colluto 8e49a5cc2f Fix double-free in JSON request parser
Clear string outputs before parsing so malformed duplicate fields cannot leave a freed pointer behind.

Closes #539
2026-08-04 13:23:48 +02:00
antirez 6537ba089b Account for batched GLM session memory during placement 2026-08-03 14:48:05 +02:00
antirez 8579ec82c0 Make batched server prefill quantum configurable 2026-08-03 10:07:30 +02:00
antirez 0a7ad776b9 Fix batched server session recovery race 2026-07-23 09:07:10 +00:00
antirez a185c36dc4 Stabilize CUDA and Metal session batching 2026-07-18 18:50:59 +02:00
antirez 66cbce5289 Unify distributed inference CLI and documentation 2026-07-18 18:50:24 +02:00
antirez 36ee8c1407 Add CUDA tensor parallelism and session batching 2026-07-18 18:50:03 +02:00
antirez 36cd0ca915 Add native Metal session batching 2026-07-18 18:49:00 +02:00
antirez 005afedcd9 Add GLM 5.2 inference and quality fixtures 2026-07-18 18:48:45 +02:00
antirez 519c4d8fe7 Fix PRO streaming and sampling correctness 2026-07-18 18:46:19 +02:00
antirez cafc134f78 Fix server const warning
Use a const pointer for stop-list substring matches so GCC/ROCm builds remain warning-clean.
2026-06-16 13:51:28 +02:00
antirez fd2d17395f Harden server JSON request parsing
Guard dynamic buffer growth against capacity wraparound, normalize malformed surrogate escapes to replacement characters without consuming unrelated escapes, and add a tool-heavy OpenCode-shaped parser stress test for issue #405.

Closes #405.
2026-06-16 13:11:33 +02:00
Salvatore Sanfilippo 91bafb5acd server: recover tool calls started inside an unclosed <think>
The model sometimes opens a DSML stanza without closing its thinking
first. The generation loop deliberately ignores tool markers inside
<think>, so such turns ran to the token limit and the call was dropped
at parse time, stalling agent sessions (#318).

Recover forward instead of rewriting sampled context: when a complete
stanza opening appears inside an unclosed think block, force-feed
"</think>" plus a blank line and let the model continue. Measured on
the real model, that position predicts a fresh stanza opening strongly
enough that the call restarts cleanly on the executable side; the
dangling opening stays harmlessly inside reasoning. Re-emitting the
stanza opening ourselves was tried and rejected: the duplicated opening
reads as an already-made call and the model ends the turn.

Detection is on accumulated text, so marker tokenization does not
matter, and only a complete opening triggers: quoted fragments and a
lone "<" keep decoding untouched. DS4_SERVER_DISABLE_THINK_TOOL_RECOVERY
restores the old behavior.

The new think-tool-recovery test replays a teacher-forced malformed
prefix token by token, asserts the recovery triggers exactly when the
opening completes, and verifies the live model then emits a valid,
parseable call.
2026-06-10 08:34:36 +02:00
586abbfb62 Strix Halo ROCm support
Co-authored-by: Donato Capitella <donato.capitella@reversec.com>

Co-authored-by: alantsev <alantsev@users.noreply.github.com>

Co-authored-by: Salvatore Sanfilippo <antirez@gmail.com>
2026-06-07 23:32:11 +02:00
Salvatore Sanfilippo 9ba160ae82 Implement SSD streaming 2026-06-04 13:43:42 -07:00
antirez 592b93f1df help: improve command line help
Add shared help text across the CLI, server, agent, bench, and eval tools. Expand distributed-mode guidance, clean up endpoint naming, and use a TTY-only 256-color layout with clearer section titles, option arguments, separators, examples, and explanatory text.
2026-05-30 12:22:19 +02:00
Salvatore Sanfilippo 4844d55108 Add distributed KV checkpoint support 2026-05-29 17:53:57 +02:00
antirez e8e8779b26 Harden disk KV cache compatibility checks
Reject stale KVC graph payloads before loading them, bump the session payload ABI after recent runtime layout changes, and keep PR #253's prefill-failure recovery as a final safety net.

The server now discards the exact disk checkpoint that produced a restored-state prefill failure, resets the disk continuation marker, and logs unlink errors instead of silently ignoring them.

Tests cover stale payload ABI rejection.

Closes #251
2026-05-26 16:53:22 +02:00
antirez 9e6ec50e24 Merge branch 'pr-253' 2026-05-26 16:35:24 +02:00
antirezandunsaltedbutter-ai ec6a82aaa9 Improve KV cache pre-store eviction
Evict before writing a new KV checkpoint so the incoming entry cannot be selected as its own victim. Pass incoming-checkpoint context into eviction scoring and devalue compatible continued-prefix waypoints when making room for a longer checkpoint.

Inspired by the KV-cache observations in #174/#175 and #176/#177.

Co-authored-by: Salvatore Sanfilippo <antirez@gmail.com>

Co-authored-by: unsaltedbutter-ai <261676361+unsaltedbutter-ai@users.noreply.github.com>
2026-05-26 08:57:54 +02:00
Giovanni Montana 9450594d14 fix(server): evict disk KV entry that fails prefill
After an unclean shutdown the on-disk KV checkpoint can be intact
(header, hash, token count all valid) but leave Metal in a state
where prefill fails.  Since the file keeps passing load-time checks
it gets reloaded on every request, looping forever until the user
manually deletes the cache directory.

On prefill failure, if the prefix came from a disk entry, unlink it
and invalidate the session.  Next request gets a clean cache miss.

Closes #251
2026-05-25 18:08:13 +01:00
antirez 747cc949b8 Document PRO support and model downloads
Expose Flash and PRO model IDs as server compatibility aliases for the loaded GGUF. Add download targets for the mixed Flash q2/q4 quant and PRO GGUFs, update README guidance, and add the M3 Ultra PRO benchmark data.
2026-05-25 08:48:10 +02:00
user 04f151dc8a DeepSeek v4 PRO support
Add DeepSeek V4 Pro support on top of main.

- add Flash/Pro shape selection and Pro Metal inference support
- fix shared SwiGLU clamp and indexer QAT behavior for Flash and Pro
- update eval/context tooling and imatrix quantization for Pro
- tag KV caches/sessions with model ids so Flash and Pro state cannot cross-load
- remove misc/PRO.md from tracked files while leaving it as a local scratch log
2026-05-25 00:04:54 +02:00
antirez f91c12b50a Improve prefill progress callbacks 2026-05-24 19:33:30 +02:00
antirez 444afce822 Add GPU power throttling 2026-05-23 20:30:48 +02:00
user c956c83fae Handle malformed DSML with model retry 2026-05-23 11:22:34 +02:00
user 7bcc4e86fe Fix DSML repair edge cases 2026-05-23 10:59:33 +02:00
user 20df6c746f Merge PR #192 DSML repair 2026-05-23 10:54:37 +02:00
antirez 8d576642c3 Handle prefill errors after SSE keepalive 2026-05-21 13:32:43 +02:00
Allen091080andClaude Opus 4.7 f027269772 ds4-server: keep SSE connection alive during long prefill
Long prefills (large prompts, no cache hit) can take minutes on local
hardware. ds4-server was silent on the socket the whole time, so HTTP
and TCP idle timeouts on the client side would close the connection
before the first response byte was written -- see the "sse headers
failed" log line that appeared at the very end of a multi-minute
prefill in real agent runs.

Stream the SSE response headers from the prefill_chunk progress
callback, then emit a ":" comment line (ignored by SSE clients per the
spec) at most every five seconds while prefill is still running. The
keepalive is best-effort: a closed socket simply fails the writes and
the outer code discovers the dead connection when it tries to stream
a real event, matching the existing error path. The tool-checkpoint
rebuild path pre-arms headers_sent because it only runs after the
response stream is already in flight, so it never tries to re-send
the SSE header line.

Verified on macOS Metal, q2-imatrix GGUF, ctx=200000:

- ./ds4_test --server passes
- 35s fresh prefill: client receives ": prefill" lines at +6/+12/
  +18/+25/+31s, then SSE content events at +35s, no client disconnect
- 1s cached prompt: unchanged (sse_headers is still emitted from the
  request handler when prefill never fires)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 13:30:05 +02:00
antirez 599e49d253 Add native DS4 agent
Add ds4-agent as a native terminal coding agent with session KV storage, DSML tool execution, edit/read/search/write/list/bash tools, async bash jobs, compaction support, history replay, and a linenoise-based interactive UI.

The agent defaults to CRC-guarded edits, streams tool visualization, ignores tool calls emitted inside thinking, improves bash output observations for long-running commands, and styles prompts, spacing, and prefill progress for interactive use.
2026-05-19 22:40:07 +02:00
Rui Gu 0e504295e4 fix: try_repair_dsml ignores DSML tags inside thinking
try_repair_dsml scanned the full generated text for DSML tags. When the
model discusses DSML syntax in its reasoning (e.g. explaining the DSML
tags), those text mentions inflate the tag counts, causing false positive
repairs (appending unnecessary closing tags).

Fix: find the last </thinking> boundary and start counting only from
there. DSML mentioned inside reasoning is model text, not executable
tool calls — matches the same approach used by parse_generated_message_ex
(commit 037ee39).

Also updated the hallucinated strip path to copy the thinking section
verbatim and only strip from the post-thinking region.

Real-world validation: observed this exact false positive in production.
The model was explaining how try_repair_dsml works and quoted the DSML
tag syntax in its explanation. The parser mistook the quote for a real
tool call and the tag counting inflated, causing a failed repair.

Metrics from production use (after all fixes in this branch):
  Tool calls: 169 | Invalid: 2 | Repaired: 38 | Orphan: 3
Only 2 cases remain unrecoverable; the other 41 (38 repaired + 3 orphan)
are now gracefully handled instead of causing finish=error.

Signed-off-by: Rui Gu <jackygurui@gmail.com>
2026-05-18 23:37:56 +08:00
Rui Gu d9cb02613a log: stderr message when thinking never closes
When parse_generated_message_ex is called with require_thinking_closed=true
and the model never outputs </thinking>, the entire generation is treated
as reasoning and any DSML inside is silently ignored. This stderr log
makes the gate visible for debugging.

Refs: #167, commit 037ee39 (Ignore tool calls emitted inside thinking)
Signed-off-by: Rui Gu <jackygurui@gmail.com>
2026-05-18 23:22:52 +08:00