Raise WebChat SSE timeout and non-benign error lifecycle logs to INFO while keeping routine client disconnects at DEBUG, preserving detach-based subscriber lifecycle semantics.
Use detach rather than complete for WebChat SSE disconnect callbacks, add an orphan-run grace policy for subscriberless active runs, and emergency-save partial assistant output when reclaimed.
Close WebChat subscriber SSE connections when the logical stream reaches done/error, make the emitter timeout configurable, and ensure stale-run eviction closes subscribers instead of leaving clients waiting.
Apply a Reactor inter-frame idle timeout at the streaming chat chokepoint so half-open provider body streams surface through the normal retry/failover path. Also keep the HTTP timeout documentation accurate and cover the behavior with focused tests.
The Dockerfile pre-copies module POMs for layer caching, but the list had
not been updated when mateclaw-plugin-mem0 was added to the root POM's
<modules>. Maven fails while constructing the reactor if a declared module
directory is missing, so `mvn -pl mateclaw-server -am dependency:go-offline`
aborted with "Child module /build/mateclaw-plugin-mem0 does not exist"
before it ever reached dependency resolution — every container build broke.
Copy the missing POM and note that this list must mirror the root POM's
<modules>, even for modules the image never builds. The module only makes
the reactor readable; it stays out of the `-pl mateclaw-server -am` build,
so the image is unchanged in size.
Fixes#566
load_skill returns SKILL.md in full by design — it is the model's behavioral
contract, and pagination by default would let the model silently miss later
mandatory sections. read_file / readSkillFile / load_skill are therefore on
the spill-exclusion list so their output is never replaced by a disk pointer.
The exclusion only covered half the path. In spillRawOrTruncate, an excluded
tool's result came back from persistIfOversized unchanged (no spill), failed
the SPILL_MARKER_PREFIX check, and fell through to truncateToolResult(8000) —
so an 8261-char SKILL.md was hard-cut through the middle and stamped with a
'[TRUNCATED: ... middle omitted]' marker. Weaker models ignore the attached
fidelity note and fabricate the removed span, inventing tool calls against
endpoints the skill never described.
- spillRawOrTruncate now returns retrieval-excluded results raw; the per-turn
aggregate budget stays the backstop.
- Outsized SKILL.md degrades to resumable pagination instead of an unbounded
inline dump. Never a lossy middle-cut.