Skip to content

Implement the high-priority backlog (items 7-12) - #13

Merged
achildress83 merged 1 commit into
mainfrom
feature/high-priority
Oct 19, 2026
Merged

achildress83 merged 1 commit into
mainfrom
feature/high-priority

Conversation

@achildress83

Copy link
Copy Markdown
Contributor

What

Implements items 7-12 of the High priority section of BACKLOG.md.

Why

  • A truncated tool call could re-bill a full turn up to max_iterations, and a budget above the ceiling was lowered.
  • An empty turn cut off by max_tokens was retried verbatim as a transient error.
  • Model-invented tool names reached summaries, metrics and span attribute keys, breaking the content-free and low-cardinality invariants.
  • A hung tool handler hung the whole loop despite deadline_seconds.
  • OTelObserver captured content with no redaction, unlike EventTraceObserver.
  • Several docs pages still described 0.1 behaviour.

Changes

  • Truncation: the budget is never lowered. When it cannot grow, the run raises LoopBudgetExceeded(kind="max_tokens") with the new ConversationStatus.TOKEN_LIMIT.
  • Empty turns: ModelResponse.content may be empty only when stop_reason is MAX_TOKENS. The loop treats it as a truncation and raises the budget. Any other empty turn is still ResponseInvalid.
  • Tool names: unregistered names are reported as <unregistered> to observers, summaries, metrics, spans and the event trace. The model still gets the real name back.
  • Timeouts: new ToolSpec.timeout_seconds and @tool(timeout_seconds=...). A timed-out handler's daemon thread is abandoned, not killed.
  • Redaction: OTelObserver(redact=, allow_unredacted=). Capture without either raises ConfigurationError. Text is redacted and then clipped, a redactor that raises drops the attribute, and exceptions are recorded without a stack trace. Agent(trace=True) still never captures.
  • Docs: refreshed the stale API pages, added docs/guides/hosted-tools.md and the Responses and Origin sections, and updated the changelog and backlog.

Breaking: OTelObserver(capture_content=True) now needs a redactor. The agentloop-tools examples in the hosted-tools guide were written from the backlog and not run. ruff and mypy are clean and 575 tests pass; the coverage gate was not run.

🤖 Generated with Claude Code

- Truncated tool calls never lower max_tokens, and stop with
  LoopBudgetExceeded(kind="max_tokens") / TOKEN_LIMIT once the budget
  cannot grow, instead of re-billing the same cut-off.
- An empty turn cut off by max_tokens is a truncation the loop answers
  with a bigger budget, not a retryable ResponseInvalid.
- Unregistered (model-invented) tool names are reported as
  "<unregistered>" to summaries, metrics, spans and the event trace.
- ToolSpec.timeout_seconds bounds a single tool call.
- OTelObserver takes redact / allow_unredacted like EventTraceObserver.
- Refresh stale docs and add the hosted-tools guide.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@achildress83
achildress83 merged commit 453f72c into main Oct 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant