Skip to content

Preserve structured outcomes for nested tool dispatch - #123

Open
Brian Krabach (bkrabach) wants to merge 2 commits into
mainfrom
fix/structured-nested-tool-receipts
Open

Brian Krabach (bkrabach) wants to merge 2 commits into
mainfrom
fix/structured-nested-tool-receipts

Conversation

@bkrabach

Copy link
Copy Markdown
Collaborator

Summary

The truncation hook currently serializes and middle-truncates an attributed nested tool's ToolResult before tool_exec can select its fields. A successful mutation can therefore appear unknown to its caller, while a failed result loses its explicit failure status. Preserve structured results on matching host-attributed child events; apply the existing text limits when the outer tool delivers its selected output to the model.

The attribution check requires the host's session/run/parent/call/tool identity, including agreement with the event envelope. Ordinary calls and incomplete attribution retain existing truncation. Other hooks, approvals, redaction, nested-result limits and selected-output limits remain active. Cancellation remains unknown and does not undo or replay committed effects.

specs/EXTENSIONS.md §49 records this as an additive host integration on a spec-silent API surface. The pinned coding-agent loop spec §5.1 requires truncation before LLM delivery, while §§5.2–5.3 specify limits and ordering; surrounding full-event evidence requirements are preserved. No graph-engine behavior or frozen conformance row changes.

Verification

  • Before the fix, three real nested-dispatch regressions failed: two successful mutations lost their structured receipts, a failed call became unknown, and selected-output overflow lost confirmed child outcomes.
  • All 48 hook tests pass with locked Core 1.6.1 and with the built hook wheel on Core 2.0.2. Eight integration cases use real Core/Live/Streaming dispatch and the actual QuickJS tool_exec worker with synthetic file effects, covering success, failure, denial, redaction, cancellation and both output limits. Six malformed attribution controls preserve ordinary truncation.
  • Ruff check and format check pass in the touched module.
  • A separate synthetic Unified acceptance probe runs two canonical outputs.attach calls through the same real nested tool chain and verifies each persisted effect once. No model, live provider or live application state was used.

The dev-only dependency additions pin the actual integration components; runtime dependencies and existing lock versions are unchanged. Adoption requires normal shared-repository review. An independent Unified receipt-projection improvement can ship separately; the general nested-result correction requires this hook change to be adopted.

Checklist

  • nlspec evidence: cited section(s) + holistic-context note (spec silence → documented extension)
  • Tests pass in the touched module
  • ruff check / ruff format --check clean
  • Diff scope matches the description above
  • Deliberate specs/EXTENSIONS.md addition described above

@bkrabach

Copy link
Copy Markdown
Collaborator Author

CI triage for exact head 864d3b766f37269758158eb91c1870deb796fae8: both hooks-tool-truncation test jobs pass, but the root-package lane and aggregate CI Gate remain failed.

The current root job completes package installation and dot-runner --help, then fails the mandatory create_agent initialization smoke with AgentError: The installed execution dependencies could not be initialized. Its resolved graph is public Agent 0.24.0 binding 9bed1c7d, engine 8541fce1, Core 2.0.1, and Foundation 21ad50fa.

This failure predates this hook change. The October 19 root job on #122 reports the same initialization error with Agent 0.23.0/Core 2.0.1. That PR changes only modules/loop-amplifier-agent/uv.lock, which the fresh root uv --no-config pip install --no-sources lane does not consume. The last actual main CI run, October 8, passed with Agent 0.22.0. No fresh main reproduction is claimed here.

This PR leaves the root workflow, root metadata and adapter dependency declarations unchanged. The changed hook is absent from the root installation graph. The public Agent binding floats on main and selects its declared versioned engine, so the older green main run does not qualify today's dependency graph.

The retained CI log does not expose the underlying exception: engine assembly wraps initialization failures and the public binding suppresses the cause chain. The useful next diagnostic belongs to the root-package/Amplifier Agent owner: reproduce unchanged main's exact installed graph in isolation and capture a sanitized exception chain from the pinned engine factory without executing a model. Then qualify any narrowly scoped compatibility repair and rerun the existing root lane. Do not skip the smoke check or silently override Core/Foundation to manufacture a pass.

No candidate-specific hook cause was found, but this remains an unresolved shared-repository CI check. It is not a new Amplifier Unified runtime dependency or a gate for unrelated Unified releases. This triage does not claim overall CI green or authorize merging past the failed gate.

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