Private
Public Access
0
0

refactor(ai_client): migrate _anthropic_history call sites to provider_state.get_history('anthropic')

TIER-2 READ conductor/code_styleguides/error_handling.md before Phase 1 (anthropic migration).

Phase 1 of code_path_audit_phase_3_provider_state_20260624. 13 call sites in _send_anthropic (lines 1430-1575) migrated from the module-level _anthropic_history alias to a local capture history = provider_state.get_history('anthropic'). The local capture pattern is used (instead of repeated provider_state.get_history() calls) to minimize lock acquisitions and improve readability.

The migration preserves behavior: ProviderHistory is the same singleton that _anthropic_history aliased to, so the migration is a pure refactor. The lock acquisition pattern is unchanged (this function does not acquire _anthropic_history_lock; thread-safety comes from _send_anthropic being called per-thread).

Verified: 37 tests pass across test_provider_state_migration.py + 6 ai_client test files.

Conventions: 1-space indentation, CRLF preserved, no comments added.
This commit is contained in:
2026-06-25 12:07:36 -04:00
parent 283569d883
commit 2323b529ee
+14 -13
View File
@@ -1427,16 +1427,17 @@ def _send_anthropic(
try:
_ensure_anthropic_client()
mcp_client.configure(file_items or [], [base_dir])
history = provider_state.get_history("anthropic")
stable_prompt = _get_combined_system_prompt()
stable_blocks: list[Metadata] = [{"type": "text", "text": stable_prompt, "cache_control": {"type": "ephemeral"}}]
context_text = f"\n\n<context>\n{md_content}\n</context>"
context_blocks = _build_chunked_context_blocks(context_text)
system_blocks = stable_blocks + context_blocks
if discussion_history and not _anthropic_history:
if discussion_history and not history:
user_content: list[Metadata] = [{"type": "text", "text": f"[DISCUSSION HISTORY]\n\n{discussion_history}\n\n---\n\n{user_message}"}]
else:
user_content = [{"type": "text", "text": user_message}]
for msg in _anthropic_history:
for msg in history:
if msg.get("role") == "user" and isinstance(msg.get("content"), list):
modified = False
for block in cast(List[dict[str, Any]], msg["content"]):
@@ -1446,10 +1447,10 @@ def _send_anthropic(
block["content"] = t_content[:_history_trunc_limit] + "\n\n... [TRUNCATED BY SYSTEM TO SAVE TOKENS. Original output was too large.]"
modified = True
if modified: _invalidate_token_estimate(msg)
_strip_cache_controls(_anthropic_history)
_repair_anthropic_history(_anthropic_history)
_anthropic_history.append({"role": "user", "content": user_content})
_add_history_cache_breakpoint(_anthropic_history)
_strip_cache_controls(history)
_repair_anthropic_history(history)
history.append({"role": "user", "content": user_content})
_add_history_cache_breakpoint(history)
all_text_parts: list[str] = []
_cumulative_tool_bytes = 0
@@ -1458,13 +1459,13 @@ def _send_anthropic(
for round_idx in range(MAX_TOOL_ROUNDS + 2):
response: Any = None
dropped = _trim_anthropic_history(system_blocks, _anthropic_history)
dropped = _trim_anthropic_history(system_blocks, history)
if dropped > 0:
est_tokens = _estimate_prompt_tokens(system_blocks, _anthropic_history)
est_tokens = _estimate_prompt_tokens(system_blocks, history)
_append_comms("OUT", "request", {
"message": (
f"[HISTORY TRIMMED: dropped {dropped} old messages to fit token budget. "
f"Estimated {est_tokens} tokens remaining. {len(_anthropic_history)} messages in history.]"
f"Estimated {est_tokens} tokens remaining. {len(history)} messages in history.]"
),
})
@@ -1478,7 +1479,7 @@ def _send_anthropic(
top_p = _top_p,
system = cast(Iterable[anthropic.types.TextBlockParam], system_blocks),
tools = cast(Iterable[anthropic.types.ToolParam], _get_anthropic_tools()),
messages = cast(Iterable[anthropic.types.MessageParam], _strip_private_keys(_anthropic_history)),
messages = cast(Iterable[anthropic.types.MessageParam], _strip_private_keys(history)),
) as stream:
for event in stream:
if isinstance(event, anthropic.types.ContentBlockDeltaEvent) and event.delta.type == "text_delta":
@@ -1492,10 +1493,10 @@ def _send_anthropic(
top_p = _top_p,
system = cast(Iterable[anthropic.types.TextBlockParam], system_blocks),
tools = cast(Iterable[anthropic.types.ToolParam], _get_anthropic_tools()),
messages = cast(Iterable[anthropic.types.MessageParam], _strip_private_keys(_anthropic_history)),
messages = cast(Iterable[anthropic.types.MessageParam], _strip_private_keys(history)),
)
serialised_content = [_content_block_to_dict(b) for b in response.content]
_anthropic_history.append({
history.append({
"role": "assistant",
"content": serialised_content,
})
@@ -1571,7 +1572,7 @@ def _send_anthropic(
"type": "text",
"text": "SYSTEM WARNING: MAX TOOL ROUNDS REACHED. YOU MUST PROVIDE YOUR FINAL ANSWER NOW WITHOUT CALLING ANY MORE TOOLS."
})
_anthropic_history.append({
history.append({
"role": "user",
"content": tool_results,
})