Why architecture matters here
Tool failures are architectural. A tool without argument validation crashes on hallucinated types. A tool without idempotency corrupts on retry. A tool without governance runs when it shouldn't. Getting the contract right is what separates a demo from a product.
With the pieces mapped, tools become predictable, safe, and evolvable.
The architecture: every piece explained
The top strip is the declaration + invocation. Tool declaration uses annotations (or manifest files) that describe name, description, and JSON schema for arguments. Tool registry exposes tools per session. Model invokes a tool via the runtime's tool_use event. Executor validates arguments, then calls the actual Java method.
The middle row is the safety machinery. Timeout + retry handles slow or flaky tools. Error contract returns typed errors that the model can reason about. Idempotency keys prevent duplicate side effects. Streaming result lets the model see partial output on long-running tools.
The lower rows are ops. Governance applies policy + approval per tool call. Observability tracks tool invoke counts, latencies, and errors. Ops handles evolution (schema changes with deprecations) and drills.
End-to-end flow
End-to-end: an agent runtime hosts a Java tool @Tool List