mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-11 04:00:38 +00:00
fix(code-runtime-python): size the output-budget/address-space gate by worst-case Unicode and gate both budgets
The load-time addressSpaceMb gate used a 1/8 fraction derived for ASCII, but the child ledgers trigger on character count against a serialized-byte budget: an astral character is one character yet ~4 bytes stored and ~4 encoded, live at once, so the true worst-case peak is ~8x the budget, not ~2x. Replace the fraction with an explicit OUTPUT_BUDGET_WORST_CASE_ADDRESS_SPACE_MULTIPLE (8) and a strict `>`, and gate maxValueBytes the same way as maxLogBytes — the value path builds and encodes a near-budget completion under the same RLIMIT_AS, so the incompatible pair was previously admitted there too. Slice the newline branch's unterminated tail to a budget-sized prefix: it buffered the whole text[pos:] before the flush trigger could bound it, so an early newline plus a huge tail made a second full copy of the model's string — an RLIMIT_AS death the config gate cannot cover since the tail can far exceed maxLogBytes. Disclose the cross-field constraint in the maxLogBytes/maxValueBytes/addressSpaceMb JSDoc (regenerating config-catalog); refresh the note's stale Buffer.byteLength(JSON.stringify) reference; reconcile the arrival-order rebuttal with the seam's "in order" logs JSDoc (within-stream, cross-stream best-effort). Extend the load-rejection test to both budgets and add a tail-copy regression; sync the zh pair.
This commit is contained in:
@@ -248,7 +248,17 @@ class _LogStream(io.TextIOBase):
|
||||
pos = newline + 1
|
||||
if pos < length:
|
||||
if self._logs.remaining > 0:
|
||||
tail = text[pos:]
|
||||
# Buffer only a budget-sized PREFIX of the tail, not the whole
|
||||
# `text[pos:]`: an early newline followed by a huge unterminated
|
||||
# tail (`"\n" + "A" * 30 MiB`) would otherwise copy the entire
|
||||
# tail into `_pending` here — a second full copy of the model's
|
||||
# own string, the RLIMIT_AS death this path exists to avoid —
|
||||
# before the newline-free trigger below could bound it. Anything
|
||||
# past `remaining` characters cannot be admitted (the char count
|
||||
# is a lower bound on the serialized cost), so a
|
||||
# `remaining + 4`-character prefix is all that can ever survive;
|
||||
# the flush trigger below rejects it and emits the marker.
|
||||
tail = text[pos:pos + self._logs.remaining + 4]
|
||||
self._pending.append(tail)
|
||||
self._pending_chars = len(tail)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user