Build1 publisher2 min readPublished
Whoever implements the server half of Responses picks your retrieval and veto defaults
The Responses and Messages dialects specify tool declarations, streaming and reasoning knobs. A Java 21 library published to Maven Central at 0.18.0 argues the unspecified half is where retrieval, injection and veto actually live, and offers to host it in your own process.
The Engineer · Build desk

What happened
- The author has shipped Franca, a Java 21 library on Maven Central that terminates both dialects inside your own service and treats the server half as an ordinary development surface.
- Three configuration blocks make the host a standard OpenAI-compatible server, with clients pointing base_url at your service and changing nothing else on their side.
- Both boundaries are SPI plug points: a new dialect is a new adapter implementation, and a backend that is not plain OpenAI-compatible chat is a new driver.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Putting tool execution on the vendor's platform turns a governance question into a data-residency question first, because internal sources have to reach a hosted tool before any policy line gets written.
- decision Teams that standardise on a gateway for routing and key management still have to choose somewhere else to run a retrieval pass, since the gateway swaps upstreams and nothing more.
- capability Terminating the dialect inside your own service makes a retrieval-before-answer step or a veto an ordinary code path you own, instead of a feature request filed with a model vendor.
Read the configuration and the boundary is visible in three keys. `adapters` names which dialects your service terminates, `drivers` names how it talks to a backend, and `routes` maps an alias to a driver, an address, a model and a key read from `${BACKEND_API_KEY}` [12][13]. Set those three blocks and the service answers as a standard OpenAI-compatible server, with clients pointing `base_url` at you and changing nothing else [14]. The example alias is `gpt-5.6`. An alias is just a string [13].
The blocks do not cover the list the post says the protocol leaves open: which function answers a declared tool type, where that function runs, whether a retrieval pass happens before the answer, and what the server may inject, observe or veto [3]. In this library the bottom boundary is any inference backend, currently an OpenAI-compatible chat driver. The top boundary is your `/v1/responses` and `/v1/messages` endpoints, and the post describes the middle as "The middle is yours." [16]
On the vendor's platform you get built-in tools and hosted execution, which the post calls fine until your data cannot leave the building [6]. A conversion gateway such as one-api or LiteLLM handles routing, key management and protocol translation, and the post's verdict is that you can swap upstreams but cannot add capabilities [7]. Self-hosted servers including vLLM now speak `/v1/responses`, but as a raw text-in/text-out endpoint; the author wrote that they "say the words of the dialect without the agent semantics behind them" [8]. All three leave the path between the client and the model closed to an application developer who wants to insert a capability on it [18].
The author put the governance consequence plainly. "The protocol is silent on all of it. And silence has a consequence: whoever implements the server owns your application layer," the post said [4].
The cost of taking the argument up is a JVM one. You need Java 21, a Spring Boot 3 host, and the `io.github.franca-protocol` BOM at 0.18.0 alongside `franca-spring-boot` and `franca-spring-tools-local` [10][11]. That version is pre-1.0, so the API surface you write your retrieval and policy code against is not yet frozen [20]. The post is written by the library's author and does not report adoption counts or performance numbers [17][19].
Two things have to hold for the claim to transfer to your stack: your clients speak Responses or Messages, and your backend is OpenAI-compatible chat. Otherwise the driver is yours to write [15][16]. Both boundaries are pluggable by design, a new dialect being a new adapter and an unusual backend a new driver, as ordinary SPI implementations [15].
What to watch
- Whether OpenAI or Anthropic add server-side semantics to the dialects: which function answers a declared tool, and whether a retrieval pass is specified.
- A 1.0.0 release of franca-bom, which would tell you whether the adapter and driver SPIs are stable enough to write policy code against.
- Whether gateways such as one-api or LiteLLM add capability hooks and close the development-surface gap the post describes.