test(claude): lock first-text-block (not concatenation) for the ThinkingBlock helper (#2697)

Adds the multiple-text-block test the deep-dive flagged: the helper must return
the FIRST text block (graphify's claude calls carry a single JSON payload, so
concatenating would corrupt it). Adds the CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
safishamsi
2026-08-18 22:20:19 +01:00
co-authored by Claude Opus 4.8
parent 55822b0399
commit 7047411678
2 changed files with 13 additions and 0 deletions
+1
View File
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
## 0.9.47 (unreleased)
- Fix: the `claude` backend no longer crashes with `AttributeError: 'ThinkingBlock'` when an extended-thinking response leads with a thinking block; the first text block is read instead (#2697, thanks @mdshzb04).
- Fix: `graphify update` / `save_manifest` no longer rewrites `manifest.json` timestamps on a no-op run, so `graphify-out/` stops showing as dirty (and stops producing a trailing graph commit) when nothing changed; a genuine change still updates and persists (#2838, thanks @hopstreax).
- Fix: a C# 12 primary constructor's parameters are now walked, so `class Svc(IRepo repo)` emits the `references` edge to `IRepo` and calls through `repo` resolve — previously the class silently dropped its dependency; built-in and type-parameter types are not fabricated (#2829, thanks @brobl2008).
- Fix: AST-derived INFERRED edges now carry a rubric `confidence_score` keyed to the relation (`uses` 0.95, `indirect_call`/unresolved cross-file `calls` 0.85) instead of landing at the rubric-forbidden 0.5 or a flat 0.8; the INFERRED default moves 0.5→0.55 so every score-less INFERRED edge is on the discrete rubric set (#2813, thanks @abhay-codes07).
+12
View File
@@ -424,6 +424,18 @@ def test_anthropic_response_text_falls_back_without_text():
assert llm._anthropic_response_text(content, default="SENTINEL") == "SENTINEL"
def test_anthropic_response_text_returns_first_text_block_not_concatenation():
"""Locks the first-wins semantics: graphify's claude calls return a single
JSON payload, so the helper must return the FIRST text block, never
concatenate multiple (which would corrupt the JSON)."""
content = [
SimpleNamespace(type="thinking", thinking="planning"),
SimpleNamespace(type="text", text=_NODE_JSON),
SimpleNamespace(type="text", text='{"nodes": [], "edges": []}'),
]
assert llm._anthropic_response_text(content) == _NODE_JSON
def test_call_claude_parses_thinking_model_response(tmp_path, monkeypatch):
"""Extended-thinking models must not crash on content[0] being ThinkingBlock."""
img, _, _ = _make_corpus(tmp_path)