feat: finish shared runtime extraction - #21
Merged
Merged
Conversation
Review fixes for the modules this branch extracted, plus four provider defects the review surfaced in code the extraction depends on. Extracted-module fixes: - tool_call_repair: stop whitespace-stripping literal content args. Every string arg was stripped, so file_editor_str_replace lost the indentation and trailing newline of old_string/new_string (breaking exact matching) and write_file dropped trailing newlines. Adds LITERAL_CONTENT_KEYS. - tool_call_repair: honour an explicitly empty key_aliases/type_coercions as an opt-out instead of falling back to the default table. - summary: classify permanent 4xx as non-retryable. A bad API key burned max_retries attempts per candidate (8 requests, 12s of sleep); now 2 requests and no backoff. Injectable via `retryable`. - summary: measure the context-length retry ladder against the original content, not the already-shortened text, which abandoned a candidate one truncation step early. - guardrails: read total_tokens, the key providers and UsageMetadata actually emit. "total" appears nowhere else in agent_core, so the budget-exhausted hint never fired. Both keys are now accepted. - guardrails: coerce untyped budget config instead of raising ValueError out of an advisory check. - guardrails: tolerate non-JSON tool args when fingerprinting, and pass usedforsecurity=False so md5 imports on FIPS builds. - fallback: skip the backoff sleep after the final attempt, which only delayed the degrade and emitted a retry event no retry followed. - fallback: stop replaying already-yielded stream deltas to the consumer; set replay_partial_stream=True for the historical behavior. - usage_meter: serialize wire counters as ints rather than floats. - protocols: document the tool-call veto contract. GuardrailsMiddleware only marks metadata["blocked"], and nothing in AgentCore dispatches tools, so an unchecked flag meant silent non-enforcement. Adds BLOCKED_KEY/BLOCK_REASON_KEY and ctx.block()/is_blocked/block_reason. - export the new classes from the providers/runtime/runtime.loop package roots, matching the existing re-export convention. Provider fixes (behavior changes — see below): - finish_reason: new shared normalizer. _runaway matches the literal "length" and deliberately has no token-count fallback once visible text is present, but Anthropic sends stop_reason="max_tokens" and the Responses API sends status="incomplete" plus incomplete_details.reason="max_output_tokens". Truncation recovery was dead for both protocols. Only truncation markers are rewritten; tool_use/end_turn/stop pass through unchanged. - openai_responses: also emit a finish_reason on response.incomplete, which the streaming path ignored while hardcoding "stop". - openai_chat: compute session affinity on every call. A scoped client withholds default_query from the SDK because cached clients outlive their task, making the per-call path the only source of affinity and the only staleness check — but it was gated on extra_headers, so chat(messages) pinned no replica at all. - _streaming: keep the visible answer when a streamed block list carries no text block. A text block is only recorded on a content_block_start of type text, so a gateway omitting that event returned thinking-only blocks and silently dropped the answer. Three of these change observable behavior rather than only fixing a latent bug, and matter to downstream repos pinning this commit: truncation continuation now fires for anthropic/bedrock and responses; scoped clients now send an affinity query on every request; and CooldownFallbackLLM.stream no longer duplicates partial output. test_cooldown_fallback's `assert sleeps == [0.5]` pinned the wasted post-final-attempt sleep and is updated to the corrected contract. Validation: Ruff clean, Pyright 0 errors, 1108 passed (was 1074). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Validation:
Downstream adoption PRs will pin this immutable commit and retain only product catalog, credentials, session headers, billing/tracing hooks, and composition.