Skip to content
Packages Examples Agents Blog Get started

Protocol-neutral conversion engine for the Oridecon AI relay — OpenAI Chat, Responses, Anthropic, and Gemini


Protocol-neutral conversion engine for the Oridecon AI relay. Converts between OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, and Gemini generateContent wire formats through one canonical intermediate representation.

The engine is synchronous and side-effect free: it never performs HTTP, channel selection, billing, or model selection. Host capabilities (Claude default max_tokens, Gemini safety thresholds, media resolution, model suffixes) are supplied as typed callbacks through RelayConversionContext from oridecon-contracts.

Full documentation: docs.oridecon.dev

Terminal window
uv add oridecon-ai-relay
from oridecon import Application
from oridecon.ai.relay import RelayModule
async def main() -> None:
async with Application.boot(modules=[RelayModule.configure()]) as app:
# ... conversion engine available via the registry ...
...
if __name__ == "__main__":
import asyncio
asyncio.run(main())

Convert a payload directly with the built-in registry:

from oridecon.ai.relay import RelayConverterRegistry, convert_request_by_id
from oridecon.contracts.ai.relay import (
OpenAIChatMessage,
OpenAIChatRequest,
RelayFormat,
)
from oridecon.contracts.ai.relay.context import RelayConversionContext
registry = RelayConverterRegistry.with_defaults()
context = RelayConversionContext(default_max_tokens=lambda model: 8192)
result = convert_request_by_id(
registry,
payload=OpenAIChatRequest(
model="gpt-4o",
messages=[OpenAIChatMessage(role="user", content="hi")],
),
converter_id="openai_chat_to_claude",
context=context,
)
# Result[RelayConvertResult[RelayRequestPayload], RelayError]

RelayConversionContext supplies host capabilities (Claude needs default_max_tokens); see the host-context reference below.

Zero-config usage: Call RelayModule.configure() with no arguments. The engine needs no configuration; host capabilities are optional.

from oridecon.contracts.ai.relay.context import RelayConversionContext
context = RelayConversionContext(
default_max_tokens=lambda model: 8192,
upstream_model="claude-3-5-sonnet",
request_id="req_123",
)
FieldDefaultDescription
optionsRelayOptions()Cross-protocol adaptation options
default_max_tokensNoneClaude max_tokens fallback per model
safety_settingNoneGemini safety-threshold lookup per category
supports_image_generationNoneGemini image-generation capability lookup per model
preserve_thinking_suffixNoneThinking-suffix bypass policy lookup
media_resolverNoneURL media resolution (data URIs decode locally)
upstream_model""Model name substituted when the payload carries none
losses[]Per-conversion loss records appended by mappers
request_id""Caller-supplied request id stamped on losses and errors
channel_name""Selected relay channel name for channel-aware adaptation

All callbacks are nil-safe: mappers never guard against None.

MethodDescription
RelayModule.configure()Conversion engine with the built-in converter routes
RelayModule.stub()Same in-memory engine, suitable for unit tests
  • Four wire formats: OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, Gemini generateContent
  • Canonical IR: every conversion goes source → IR → target with route-quality reporting
  • Synchronous and side-effect free: no HTTP, channel selection, billing, or model selection
  • Typed host callbacks: RelayConversionContext supplies Claude, Gemini, and media capabilities
  • Result-typed conversions: Result[RelayConvertResult, RelayError] with full error translation
  • Media handling: local data-URI decoding and host-supplied URL resolution
  • Stream scaffolding: per-format stream session state (stateful conversion not yet enabled)
async with Application.boot(modules=[RelayModule.stub()]) as app:
# your test code
...
FileWhat it contains
src/oridecon/ai/relay/module.pyRelayModule.configure() and RelayModule.stub()
src/oridecon/ai/relay/engine.pyRelayConverterEngine and convert_*_via / convert_*_by_id helpers
src/oridecon/ai/relay/context.pyNil-safe ConversionContext over RelayConversionContext
src/oridecon/ai/relay/mappers/FormatMapper base plus openai_chat, openai_responses, claude, gemini
src/oridecon/ai/relay/stream/Per-format stream session scaffolds and state
src/oridecon/ai/relay/registry.pyRelayConverterRegistry, Route, RouteSpec
src/oridecon/ai/relay/quality.pyConversion route-quality computation
src/oridecon/ai/relay/media.pyData-URI decoding and URL media resolution
src/oridecon/ai/relay/errors.pyError translation helpers