Skip to main content
If you have a working Truss model, either a model.py implementation or a custom server such as vLLM, you can add it to a Chain without rewriting it as a ChainletBase. Declare it as a TrussChainlet and it deploys as part of the chain. Other chainlets call it through a TrussHandle, which gives them the URL and headers to call it with their own HTTP or WebSocket client. A TrussChainlet only receives calls. It can’t be the chain’s entrypoint, and it can’t call other chainlets. If your model is already deployed on its own, outside the chain, call it with a stub instead.
TrussChainlet requires truss>=0.18.5.

Declare a TrussChainlet

In your chain file, subclass chains.TrussChainlet and point truss_dir at the Truss directory. A relative path is resolved from the file that declares the class:
chain.py
The Truss directory needs no changes to join a chain. It can be a standard Truss with a Model class in model/model.py, or a docker_server Truss that runs a custom server image such as vLLM and has no model/ directory at all. Deploy the chain as usual:

Call a TrussChainlet

When one chainlet depends on another ChainletBase, it calls it through a generated stub with typed methods. A TrussChainlet gets no stub, because the framework doesn’t know what endpoints your Truss serves. Instead, chains.depends() returns a TrussHandle. The handle doesn’t make calls itself. Its http_call_args() and ws_call_args() methods return a URL and headers, and you make the call with your own client, such as httpx, websockets, or openai. Requests and responses aren’t validated; their shapes are whatever your Truss serves. Import TrussHandle from its module:

Make HTTP calls

Depend on the TrussChainlet from a ChainletBase and call it with any HTTP client:
chain.py
http_call_args() accepts three optional keyword arguments:
  • prefer_internal: Call the model over Baseten’s internal network instead of its public URL. Internal calls skip a round trip through the public internet, so use this for chainlet-to-chainlet traffic.
  • sync_path: Route the call to a path your server exposes, instead of the predict endpoint. See Call custom server endpoints.
  • api_key: Authenticate with a different API key. By default, the handle uses the chain’s built-in key.

Make WebSocket calls

If the wrapped Truss serves WebSockets (runtime.transport.kind: websocket, see WebSockets), get connection arguments from ws_call_args():
The URL starts with wss:// and ends in /websocket. ws_call_args() accepts sync_path and api_key. There’s no prefer_internal because WebSocket clients don’t allow the header override that internal routing depends on.

Call custom server endpoints

A docker_server Truss serves its own API on its own paths. Pass sync_path to reach them. For example, wrap an OpenAI-compatible vLLM server and point the OpenAI client at it:
Authentication runs through default_headers; vLLM ignores the api_key value.

Test locally

run_local() skips TrussChainlet dependencies because there’s nothing local to run: they wrap Truss directories that only exist as deployments. Construct the entrypoint with a stand-in object that has the same call-args methods, such as Entry(stt=FakeSTT()). If you leave it out, run_local() raises a ChainsUsageError. For the full workflow, see local development.

Next steps