Workbenches Build on Each Other
Goal: Let one workbench call another's hosted mode, without hard-coding addresses.
A release-check workbench that needs your triage workbench's API shouldn't carry its URL in code. Declare the dependency, and OpenX hands it the address when it deploys.
Declare it
- Open the workbench that will do the calling, and its Consumes tab.
- Add dependency: pick the target workbench, the mode to use (it must be enabled), and optionally an alias.
- Save, then redeploy the calling workbench.
OpenX checks each dependency when you save, accept or deploy: a target that doesn't exist, or a mode that isn't enabled, is refused.
Each dependency is one row with three fields:
| Field | What it is |
|---|---|
| Target | The other workbench, by its APISlug. Only other workbenches that have an APISlug set are offered |
| Mode | The mode of that workbench to use. It has to be turned on |
| Alias | Optional. A name that is safe in an environment variable. Left blank, the target's APISlug is used |
You can list the same target more than once to use two of its modes, say API and MCP. Give those rows different aliases: two rows with the same alias share one variable name, and only one of them survives.
What gets refused
A save, or a deploy of the calling workbench, answers 400 with a list of what is wrong:
| Situation | Message |
|---|---|
| The target is not in the workspace | "Workbench '<lookup>' declares Consumes on '<target>' which does not exist in this workspace." |
| The target's mode is not turned on | "... declares Consumes on '<target>' mode '<mode>' which is not enabled on the target." |
A target removed after the calling workbench was deployed leaves the old address in place, and calls to it fail. Redeploy the calling workbench: the deploy checks again and stops with a message naming the missing target or mode. A target set to No public access (below) must itself be deployed before the workbench that consumes it.
Read it
At deploy, each of the calling workbench's containers, one per mode, gets two environment variables:
WB_CONSUMED_<alias>_URL the target mode's address (the alias defaults to the target's APISlug)
FATHYM_OX_CONSUMES_JSON every dependency as {"alias": "url"}
With no dependencies, FATHYM_OX_CONSUMES_JSON is {} and no WB_CONSUMED_..._URL is set. To go through every
dependency without knowing the aliases in advance, read the JSON one:
const consumes = JSON.parse(Deno.env.get('FATHYM_OX_CONSUMES_JSON') ?? '{}') as Record<
string,
string
>;
for (const [alias, url] of Object.entries(consumes)) {
// call each dependency
}
const triage = Deno.env.get('WB_CONSUMED_triage_URL');
const res = await fetch(`${triage}/classify/run`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${Deno.env.get('TRIAGE_TOKEN')}`,
},
body: JSON.stringify({ arg0: 'Checkout returns 500 for EU cards' }),
});
The call goes through the same address and the same access check as any outside caller: the calling workbench presents a key like anyone else and is not trusted because it runs in your workspace. Composition wires workbenches together; apart from the exception below, it bypasses nothing.
One exception, which you choose. A target set to No public access in its Hosting tab has no ox-api
address at all: it is reachable only by other workbenches and services in the same environment. A workbench that
consumes it is given the target's in-environment address (http://<app name>:<port>) instead, with no key check
in between.
The calling workbench needs its own key. OpenX issues none to it, so add a key from APIs -> API Keys to
the workbench's environment settings (TRIAGE_TOKEN above) and rotate it yourself.
Custom modes
MCP, API and Web are built in. A workbench package can also declare a mode of its own, such as a scheduled job, and the workbench offers it in its Modes tab like any other: there is nothing to register in the workspace. A custom mode has no web address; it runs in its own container and is kept running. How to write one is on Custom Modes.
Next steps
- Host another -> Host Your Own Workbench
- The addresses each mode answers on -> Reach a Hosted Workbench