chore(generation): track CTX_DIAG per attempt not per round
Retry attempts were previously conflated with the initial call, making prompt_tokens and headroom look cumulative and useless for diagnosing the silent-round behavior. Move start-of-attempt captures inside the retry loop and emit attempt_start / attempt_end lines so each attempt's numbers stand alone. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -410,18 +410,20 @@ async def run_generation(
|
||||
buf.append_event("status", {"status": "Generating response..." if _round == 0 else "Composing response..."})
|
||||
t_stream = time.monotonic()
|
||||
|
||||
round_content_start = len(buf.content_so_far)
|
||||
round_tokens_start = timing.get("output_tokens") or 0
|
||||
round_prompt_tokens_start = timing.get("prompt_tokens") or 0
|
||||
approx_msg_chars = sum(len(str(m.get("content", ""))) for m in messages)
|
||||
effective_think = think
|
||||
retried_with_think = False
|
||||
logger.info(
|
||||
"CTX_DIAG round_start conv=%d round=%d num_ctx=%d msgs=%d approx_chars=%d think=%s",
|
||||
conv_id, _round, num_ctx, len(messages), approx_msg_chars, effective_think,
|
||||
)
|
||||
attempt = 0
|
||||
|
||||
while True:
|
||||
attempt_content_start = len(buf.content_so_far)
|
||||
attempt_output_tokens_start = timing.get("output_tokens") or 0
|
||||
attempt_prompt_tokens_start = timing.get("prompt_tokens") or 0
|
||||
attempt_tool_calls_start = len(round_tool_calls)
|
||||
logger.info(
|
||||
"CTX_DIAG attempt_start conv=%d round=%d attempt=%d num_ctx=%d msgs=%d approx_chars=%d think=%s",
|
||||
conv_id, _round, attempt, num_ctx, len(messages), approx_msg_chars, effective_think,
|
||||
)
|
||||
async for chunk in _stream_with_retry(messages, model, tools, effective_think, num_ctx=num_ctx):
|
||||
if buf.cancel_event.is_set():
|
||||
cancelled = True
|
||||
@@ -523,24 +525,23 @@ async def run_generation(
|
||||
if cancelled:
|
||||
break
|
||||
|
||||
round_content_added = len(buf.content_so_far) - round_content_start
|
||||
round_tokens_added = (timing.get("output_tokens") or 0) - round_tokens_start
|
||||
round_prompt_tokens = (timing.get("prompt_tokens") or 0) - round_prompt_tokens_start
|
||||
headroom = num_ctx - round_prompt_tokens if round_prompt_tokens else None
|
||||
attempt_content_added = len(buf.content_so_far) - attempt_content_start
|
||||
attempt_tokens_added = (timing.get("output_tokens") or 0) - attempt_output_tokens_start
|
||||
attempt_prompt_tokens = (timing.get("prompt_tokens") or 0) - attempt_prompt_tokens_start
|
||||
attempt_tool_calls_added = len(round_tool_calls) - attempt_tool_calls_start
|
||||
headroom = num_ctx - attempt_prompt_tokens if attempt_prompt_tokens else None
|
||||
is_silent = (
|
||||
not round_tool_calls
|
||||
and round_content_added == 0
|
||||
and round_tokens_added > 0
|
||||
attempt_tool_calls_added == 0
|
||||
and attempt_content_added == 0
|
||||
and attempt_tokens_added > 0
|
||||
)
|
||||
logger.info(
|
||||
"CTX_DIAG round_end conv=%d round=%d think=%s prompt_tokens=%d output_tokens=%d headroom=%s content_added=%d tool_calls=%d silent=%s",
|
||||
conv_id, _round, effective_think, round_prompt_tokens, round_tokens_added,
|
||||
headroom, round_content_added, len(round_tool_calls), is_silent,
|
||||
"CTX_DIAG attempt_end conv=%d round=%d attempt=%d think=%s prompt_tokens=%d output_tokens=%d headroom=%s content_added=%d tool_calls=%d silent=%s",
|
||||
conv_id, _round, attempt, effective_think, attempt_prompt_tokens, attempt_tokens_added,
|
||||
headroom, attempt_content_added, attempt_tool_calls_added, is_silent,
|
||||
)
|
||||
if (
|
||||
not round_tool_calls
|
||||
and round_content_added == 0
|
||||
and round_tokens_added > 0
|
||||
is_silent
|
||||
and not effective_think
|
||||
and not retried_with_think
|
||||
):
|
||||
@@ -549,11 +550,12 @@ async def run_generation(
|
||||
# think=True — reasoning mode produces more reliable output.
|
||||
logger.warning(
|
||||
"Silent round %d for conv %d (tokens=%d); retrying with think=True",
|
||||
_round, conv_id, round_tokens_added,
|
||||
_round, conv_id, attempt_tokens_added,
|
||||
)
|
||||
buf.append_event("status", {"status": "Retrying with reasoning enabled..."})
|
||||
effective_think = True
|
||||
retried_with_think = True
|
||||
attempt += 1
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user