Repository navigation
The dropped-block diagnostic is computed, carried through the adapter result, and never persisted — no artifact carries the per-kind counts #697
Description
PR #660 (#625) added the per-kind dropped-block counter so an operator can
reconcile a thinking-enabled request's usage against the blocks that survived
translation. At abd1dcf4 the counter is produced and carried on the in-memory
result and read by nothing outside the test suite — no step report, no scan
aggregate, no results field, no Go consumer.
Mechanism (at abd1dcf4)
libs/openant-core/utilities/llm/adapter.py:226— the field:
dropped_block_kinds: dict | None = field(default=None, repr=False)libs/openant-core/utilities/llm/providers/anthropic.py:378— init{}libs/openant-core/utilities/llm/providers/anthropic.py:401-402— increment
per dropped block kindlibs/openant-core/utilities/llm/providers/anthropic.py:474— passed onto
theCompletionResult
All five sites are producer-side. Nothing consumes the value.
Executed repro (re-run at abd1dcf4)
$ git grep dropped_block_kinds abd1dcf4 -- libs/openant-core ':!libs/openant-core/tests/'
abd1dcf4:libs/openant-core/utilities/llm/adapter.py:226: dropped_block_kinds: dict | None = field(default=None, repr=False)
abd1dcf4:libs/openant-core/utilities/llm/providers/anthropic.py:378: dropped_block_kinds: dict[str, int] = {}
abd1dcf4:libs/openant-core/utilities/llm/providers/anthropic.py:401: dropped_block_kinds[str(kind)] = (
abd1dcf4:libs/openant-core/utilities/llm/providers/anthropic.py:402: dropped_block_kinds.get(str(kind), 0) + 1)
abd1dcf4:libs/openant-core/utilities/llm/providers/anthropic.py:474: dropped_block_kinds=dropped_block_kinds or None,
$ git grep -n "\.dropped_block_kinds" abd1dcf4
abd1dcf4:libs/openant-core/tests/test_issue625_thinking_control.py:23: ``CompletionResult.dropped_block_kinds`` (a COUNT, never a token split —
abd1dcf4:libs/openant-core/tests/test_issue625_thinking_control.py:175: assert result.dropped_block_kinds == {"thinking": 2, "redacted_thinking": 1}
abd1dcf4:libs/openant-core/tests/test_issue625_thinking_control.py:181: assert result.dropped_block_kinds is None
$ git grep -n "dropped_block\|DroppedBlock" abd1dcf4 -- apps | wc -l
0
5 producer-side hits in production, 3 reader hits (all in one test file), 0 Go
consumers. #660's body claim that the counter "gives the reconciliation" is
broken at HEAD: the number never reaches an operator.
Falsifier
"any step report / scan aggregate / results field carrying the per-kind dropped-block counts."
One-line sibling (same surface, not a separate issue)
The declared SDK floor anthropic[bedrock]>=0.40.0
(libs/openant-core/pyproject.toml:11) predates the thinking kwarg — absent
at 0.40.0/0.46.0, present at 0.47.0 (wheel diff: 0 vs 20 occurrences).
libs/openant-core/requirements.txt:2 pins anthropic[bedrock]==1.7.0, so
there is no reachable consumer today; the floor is only wrong for an
installer that resolves the declared minimum.
Dedup anchors
Searched the live issue set for dropped_block_kinds (0 hits),
accounting_errors (0 hits), cost_incomplete, _summary.json.
- No request-side thinking control, and the response translation discards unsupported thinking blocks while forwarding their usage (an enhancement: expose the policy, keep the default) #625 (closed) asked for the diagnostic — delivered by feat(llm): request-side thinking control, effective-policy records, dropped-block diagnostic (#625) #660. This issue is
about the persistence, not the design. - registry: cache multipliers exist only for the anthropic family — openai/google/openrouter/bedrock cached usage reads cost_incomplete (bedrock under-reports) #690 / Registry census follow-up: the 4.5-generation Claude families (opus-4-5, sonnet-4-5 + dated forms) have no record under any provider; the claude-opus-4-6 status looks stale #648 are the registry/cache-pricing surface; no overlap with the
dropped-block counter. - No zero-reader duplicate exists.
Fix direction
Thread the counter into the same channel the other per-call diagnostics use:
the step report's token_usage block (libs/openant-core/core/step_report.py)
and from there the scan aggregate — present-only, so a healthy run's artifacts
stay byte-identical, matching the #605 counter's own convention.
Activity
gadievron commentedon Sep 25, 2026
Anchor correction (2026-09-24): the 09-23/24 merge batch moved this issue's cited lines. The defect is intact (re-verified at master 6240682); only the pointers shifted.
OLD → CURRENT: anthropic.py:378/401/474
at master: anthropic.py:385/408/481 (+ the pin is now 1.8.0)
Re-derivation: the batch's #716/#670/#675/#676 added lines ahead of the anchor. The next fixer should cite the current lines.
gadievron commentedon Oct 12, 2026
Intake: handoff
Comment on #697 — a freshness update on the masking pin, in the spirit of this issue's own anchor-correction comment ("the next fixer should cite the current lines").
The anchor correction (2026-09-24) recorded the pin at
1.8.0; it has since been proposed to move again: #758 (open) bumpsanthropicto1.13.0— but the sibling is pin-independent: no bump touches the floor. The declared flooranthropic[bedrock]>=0.40.0(libs/openant-core/pyproject.toml:11) still predates thethinkingkwarg (present from 0.47.0), so — per this issue's own body — an installer that resolves the declared minimum rather than the pinned requirements gets an SDK where every thinking-configured call TypeErrors.One caveat for the fixer on the prior art: #428's guard (with its fix #468, and #774 currently rewriting it) is one-directional — its own test asserts every pyproject floor is
<=its requirements pin, i.e. it catches a floor ABOVE the pin (the drift class), and structurally cannot catch a floor that is too LOW (this issue's class — a too-low floor is invisible to afloor <= pininvariant). The capability shape already staged once (the #658-era branch's floor + capability test) remains the right ask: the floor itself at>=0.47.0with the import-time capability check, so no pin movement can re-mask it and no one-directional guard needs to learn a second direction.Fix-direction: neither (a freshness note on the existing tracker; no new finding).
CODE-TRACED, NOT EXECUTED — the pin states read from the live threads + the requirements file at the master pin.