What are you trying to accomplish?
We are looking to run request-level optimizations such as pxpipe (converting large text blocks into images for vision-capable models to optimize token consumption) and headroom (context compression) in front of model routing.
Today, OpenCodeX acts as the universal routing layer to multiple providers (OpenAI, Anthropic, Google Antigravity, etc.). Having a way to plug in pre-adapter request transforms directly on the normalized request would allow these optimizations to work seamlessly across any provider.
What prevents this today?
Attempting to chain external proxy tools via baseUrl works for OpenAI-compatible wires, but completely breaks when routing to other providers—most notably Google / Gemini Antigravity (adapters/google.ts).
By the time an upstream HTTP request leaves OpenCodeX, adapter.buildRequest(parsed, ...) has already translated the request into that provider's proprietary wire format. An external proxy sitting on baseUrl would need to deconstruct, re-parse, and re-serialize Google's wire protocol, Anthropic's wire protocol, and Responses format separately.
In contrast, before buildRequest is invoked in server/responses/core.ts, OpenCodeX has already parsed the incoming turn into a single, provider-agnostic representation: OcxParsedRequest.
What should OpenCodex do?
Expose a clean pre-adapter request transform hook (or custom handler interface) that operates on OcxParsedRequest before adapter.buildRequest is called.
Key requirements:
- Single normalized format: Operates on
OcxParsedRequest so transforms don't need to know anything about vendor wire formats.
- Applied once per turn: Executed once for the turn rather than re-running on every internal retry/continuation/replay in
server/responses/core.ts that re-invokes buildRequest.
- Model & Provider Awareness: The transform receives context (
providerName, modelId, providerConfig). This allows tools like pxpipe to inspect whether the target model accepts image input (reusing modelAcceptsImageInput from vision/eligibility.ts).
Example usage or interface
A lightweight transform handler signature:
export type RequestTransform = (
parsed: OcxParsedRequest,
ctx: {
providerName: string;
modelId: string;
providerConfig: OcxProviderConfig;
}
) => OcxParsedRequest | Promise<OcxParsedRequest>;
Configurable via ~/.opencodex/config.json by pointing to a custom TS/JS handler script (either globally or scoped per provider / model):
{
"requestTransforms": [
"./transforms/pxpipe-vision.ts"
],
"providers": {
"google-antigravity": {
"requestTransforms": ["./transforms/custom-handler.ts"]
}
}
}
Alternatives or workarounds
- Chaining standalone proxies before/after ocx: Fails due to disparate downstream wire formats (e.g. Google's format).
- Private fork: Feasible but introduces ongoing merge maintenance for what could be a general-purpose extension point.
Additional context
This is functionally the inverse of OpenCodeX's existing vision/ sidecar (which converts images to text for non-vision models): here, text transforms into images for vision models or is compressed before routing.
Would you be open to a PR introducing this pre-adapter transform hook? If so, what architecture/interface would you prefer for registering custom handlers?
What are you trying to accomplish?
We are looking to run request-level optimizations such as pxpipe (converting large text blocks into images for vision-capable models to optimize token consumption) and headroom (context compression) in front of model routing.
Today, OpenCodeX acts as the universal routing layer to multiple providers (OpenAI, Anthropic, Google Antigravity, etc.). Having a way to plug in pre-adapter request transforms directly on the normalized request would allow these optimizations to work seamlessly across any provider.
What prevents this today?
Attempting to chain external proxy tools via
baseUrlworks for OpenAI-compatible wires, but completely breaks when routing to other providers—most notably Google / Gemini Antigravity (adapters/google.ts).By the time an upstream HTTP request leaves OpenCodeX,
adapter.buildRequest(parsed, ...)has already translated the request into that provider's proprietary wire format. An external proxy sitting onbaseUrlwould need to deconstruct, re-parse, and re-serialize Google's wire protocol, Anthropic's wire protocol, and Responses format separately.In contrast, before
buildRequestis invoked inserver/responses/core.ts, OpenCodeX has already parsed the incoming turn into a single, provider-agnostic representation:OcxParsedRequest.What should OpenCodex do?
Expose a clean pre-adapter request transform hook (or custom handler interface) that operates on
OcxParsedRequestbeforeadapter.buildRequestis called.Key requirements:
OcxParsedRequestso transforms don't need to know anything about vendor wire formats.server/responses/core.tsthat re-invokesbuildRequest.providerName,modelId,providerConfig). This allows tools likepxpipeto inspect whether the target model accepts image input (reusingmodelAcceptsImageInputfromvision/eligibility.ts).Example usage or interface
A lightweight transform handler signature:
Configurable via
~/.opencodex/config.jsonby pointing to a custom TS/JS handler script (either globally or scoped per provider / model):{ "requestTransforms": [ "./transforms/pxpipe-vision.ts" ], "providers": { "google-antigravity": { "requestTransforms": ["./transforms/custom-handler.ts"] } } }Alternatives or workarounds
Additional context
This is functionally the inverse of OpenCodeX's existing
vision/sidecar (which converts images to text for non-vision models): here, text transforms into images for vision models or is compressed before routing.Would you be open to a PR introducing this pre-adapter transform hook? If so, what architecture/interface would you prefer for registering custom handlers?