Skip to content

Relay tools — declaration-only

Java · package io.github.muthuishere:toolnexus · SPEC §10

Declare a tool the host executes, not the library: the call rides out on the suspension.

A relay tool declares a schema with no host-side behavior: the model calls it, the call rides out as a §10 suspension carrying data.calls, the host executes it, and the host’s output is fed back as the tool result — nothing runs inside toolnexus. That lets a Go service act as a pure OpenAI-function-calling proxy. Java has no equivalent constructor, but the same outcome — declare tools to a provider without toolnexus ever executing them — is available today through Translate.translate (SPEC §11): hand it a Toolkit (or a raw OpenAI tools array) and it declares everything to the provider and hands back the tool calls the model asked for, verbatim, executing nothing. The difference is posture, not capability for the common case: relay keeps toolnexus owning the conversation loop and surfaces calls as a suspension mid-loop; translate is a single stateless call where the caller already owns the conversation and will execute the tools itself. ADR-0011 (linked from SPEC.md) is the fuller argument for why translation, not relay, is the right mechanism for a pure pass-through posture outside Go.

  • ToolResult.pending — Return a Pending from a tool to park the run until someone answers.
  • ToolResult.authRequired — The auth-shaped suspension: hand back a URL, resume once the user has granted access.
  • LlmClient.waitFor — The single hook where the host resolves a suspension — in-process prompt or durable queue, same contract.
  • ToolResult.pendingOf — Detect that a RunResult is parked rather than finished, and get the Request that parked it.
  • Translate.translate — The pure declare-and-translate mechanism Java offers instead, for the pass-through posture.