Conversation
The weighted fusion counted a candidate that one channel did not retrieve as scoring 0.0 in that channel. A missing result means the channel never scored it, not that it scored worst, and the conflation made the sparse channel unable to contribute any unique result: with the default dense_weight=0.9 a sparse-only candidate could score at most 0.1, below the dense channel's mid-field, so exact FTS5 matches for rare tokens (e.g. case variants the embedding misses) fell out of the fused top-k entirely. Only weight channels that actually retrieved the candidate: the fused score is the weight-normalized average over the channels that scored it. Candidates retrieved by both channels keep their exact previous scores, and dense preference when both channels disagree is unchanged. Fixes AstrBotDevs#9868
With stream=True MiniMax returns a server-side ffmpeg streamed WAV whose RIFF and data chunk sizes are 0xFFFFFFFF placeholders, because the total length is unknowable while streaming. _audio_play concatenated the hex chunks and get_audio wrote the bytes verbatim, so every saved .wav had an invalid header. Browsers tolerate it, but strict decoders (Android WebView, system players) reject the file with no error anywhere in the AstrBot logs. Walk the chunk list after assembly and rebuild the RIFF and data sizes from the actual bytes; files whose header is already consistent, and non-WAV payloads, pass through unchanged. Fixes AstrBotDevs#9860
When a section inherits its heading-path prefix, the markdown chunker deducts the prefix length from the body's chunk_size budget but passed the caller's chunk_overlap through untouched. An externally valid pair like chunk_size=256 / chunk_overlap=100 therefore became overlap(100) >= effective_chunk_size(64) inside the recursive chunker and raised ValueError, failing the whole upload at the chunking stage; the same input chunks fine with include_heading_context=False. Clamp the overlap to the reduced budget (and floor the budget at 1) so legal external configurations keep working regardless of heading length. Fixes AstrBotDevs#9998
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="astrbot/core/provider/sources/minimax_tts_api_source.py" line_range="42-43" />
<code_context>
+ if csize > remaining:
+ break
+ pos = chunk_start + csize + (csize % 2)
+ if not fmt or not data_start or not data_size:
+ return audio
+ if (
+ struct.unpack_from("<I", audio, 4)[0] == len(audio) - 8
</code_context>
<issue_to_address>
**issue (bug_risk):** A valid zero-length WAV, or a truncated streamed WAV whose data chunk has no remaining payload, takes the early return and retains a stale `0xFFFFFFFF` data length instead of being repaired. `get_audio` accepts any nonempty returned bytes and writes that invalid header to disk.
**Triggers:** When the assembled stream has a `fmt ` chunk followed by a zero-byte `data` payload and an inconsistent data-size field.
**Suggested fix:** Distinguish absence of a `data` chunk from a present zero-length `data` chunk, and repair the latter even when its actual payload length is zero.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and the markdown change can produce different knowledge-base chunks and embeddings that remain stored after a revert, so correcting a wrong result may require reindexing, although the impact is bounded and repairable. The rank-fusion and WAV-header changes affect runtime retrieval or playback behavior and are otherwise reversible by reverting the PR.
Blocking findings: astrbot/core/provider/sources/minimax_tts_api_source.py:43
| if not fmt or not data_start or not data_size: | ||
| return audio |
There was a problem hiding this comment.
issue (bug_risk): A valid zero-length WAV, or a truncated streamed WAV whose data chunk has no remaining payload, takes the early return and retains a stale 0xFFFFFFFF data length instead of being repaired. get_audio accepts any nonempty returned bytes and writes that invalid header to disk.
Triggers: When the assembled stream has a fmt chunk followed by a zero-byte data payload and an inconsistent data-size field.
Suggested fix: Distinguish absence of a data chunk from a present zero-length data chunk, and repair the latter even when its actual payload length is zero.
Fixes #9998
What Changed
In
MarkdownChunker._sections_to_chunks(), when a section's heading-path prefix reduces the body's effectivechunk_size, the configuredchunk_overlapis now clamped to that reduced budget (max(0, min(chunk_overlap, effective_chunk_size - 1))), and the effective budget itself is floored at 1. Sections without heading context and sections that fit in one chunk are unaffected.Why
The chunker deducts the heading-prefix length from the body budget but passed the caller's
chunk_overlapthrough untouched. The overlap is validated externally against the originalchunk_size, so an externally legal pair — e.g.chunk_size=256, chunk_overlap=100with a 200-char parent heading — becameoverlap(100) >= effective_chunk_size(64)inside the recursive chunker, which raisesValueError: chunk_overlap must be less than chunk_sizeand fails the whole knowledge-base upload at the chunking stage. The exact same input chunks fine withinclude_heading_context=False, which made the failure look config-independent.Testing
tests/unit/test_markdown_chunker_overlap.py::test_long_heading_prefix_clamps_overlap_to_body_budgetreproduces the issue verbatim ("# " + "A"*200 + "\n\n## Child\n" + "B"*600, 256/100): it raises on unpatchedmaster(95e98b8) and produces body-bearing chunks with the fix.include_heading_context=False) is pinned by the second test.python -m pytest tests/unit/test_markdown_chunker_overlap.py -q→ 2 passed; ruff format/check clean on both files.Summary by Sourcery
Fix knowledge-base chunking and retrieval ranking edge cases, and produce valid streamed MiniMax WAV output.
New Features:
Bug Fixes:
Tests: