Skip to content

Accept universal format#253

Open
Alex Z (CLowbrow) wants to merge 9 commits into
mainfrom
alex/accept-universal-format
Open

Accept universal format#253
Alex Z (CLowbrow) wants to merge 9 commits into
mainfrom
alex/accept-universal-format

Conversation

@CLowbrow
Copy link
Copy Markdown
Contributor

Universal format should be something lingua can accept as a peer to the other ones.

@CLowbrow Alex Z (CLowbrow) marked this pull request as ready for review May 22, 2026 17:21
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47198f94eb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".

Comment on lines +146 to +147
fn detect_request(&self, payload: &Value) -> bool {
serde_json::from_value::<UniversalRequest>(payload.clone()).is_ok()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply Responses upgrade after universal request conversion

With UniversalAdapter now matching requests first, universal payloads reach transform_request without top-level reasoning_effort/tools, so the existing ChatCompletions→Responses upgrade check never triggers. For requests that carry these fields in params (the universal shape), the router can send a Chat Completions payload containing reasoning + tools that certain OpenAI reasoning models reject, while the semantically equivalent OpenAI-format input would be upgraded. Re-run the upgrade decision on the transformed OpenAI payload (or inspect universal params) to keep behavior consistent.

Useful? React with 👍 / 👎.

"mistral" => Ok(ProviderFormat::Mistral),
"converse" | "bedrock" => Ok(ProviderFormat::Converse),
"responses" => Ok(ProviderFormat::Responses),
"universal" => Ok(ProviderFormat::Universal),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not accept universal as a public format string yet

ProviderFormat::from_str now accepts "universal", but the newly added adapter still returns UnsupportedTargetFormat(Universal) for response conversion, so requests that select universal as output format fail at runtime instead of being rejected at parse/validation time. Until universal response transforms are implemented, exposing this parse path makes the API advertise a format it cannot serve end-to-end.

Useful? React with 👍 / 👎.

Comment on lines +276 to +279
ProviderFormat::ChatCompletions
| ProviderFormat::Mistral
| ProviderFormat::Universal
| ProviderFormat::Unknown => "chatcmpl-",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we make the universal format have streaming chunks or ids, etc. that look different than `chatcmpl-

ProviderFormat::Mistral => "mistral",
ProviderFormat::Converse => "bedrock",
ProviderFormat::Responses => "openai", // Responses API uses OpenAI provider
ProviderFormat::Universal => "universal",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder what this looks like in practice. i'd like to see more testing with transforms or full on gateway PR before we merge.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SG I won't merge until I get it running end to end with a UI form.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0e218f442

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".

Comment on lines +37 to +40
transformed: true;
data: TData;
sourceFormat: ProviderFormat;
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Return actual target format from transformRequest

The new TypeScript transformRequest API returns only sourceFormat, so callers cannot tell when the Rust transform upgraded the request to a different wire format (for example Chat Completions → Responses for reasoning+tools requests). In that case, SDK consumers will typically keep using the originally requested endpoint and can send a Responses-shaped payload to /v1/chat/completions, causing request failures despite a “successful” transform result.

Useful? React with 👍 / 👎.

Comment on lines +159 to +166
fn detect_response(&self, _payload: &Value) -> bool {
false
}

fn response_to_universal(&self, _payload: Value) -> Result<UniversalResponse, TransformError> {
Err(TransformError::UnsupportedSourceFormat(
ProviderFormat::Universal,
))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect universal responses as transform sources

Although this commit exposes universal as a first-class format, the universal adapter explicitly disables response detection and always rejects response_to_universal, so transformResponse cannot accept universal-response JSON as input. Any attempt to convert a universal response into another format will fail with format detection/unsupported-source errors, which breaks the expected peer-format behavior for response transforms.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04ef0db0bf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".

Comment on lines +502 to 503
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)]
#[ts(export)]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept canonical lowercase universal enum values

Now that UniversalAdapter deserializes incoming universal requests (detect_request/request_to_universal), ToolChoiceMode and ResponseFormatType only deserialize Rust variant names ("Auto", "JsonSchema") because they use default Serde enum casing. Inputs using the canonical lowercase strings already implied by this module (from_str accepts "auto", "json_schema", etc.) will fail universal detection and return UnableToDetectFormat during transform_request. Add Serde renames/aliases (or custom deserialization) so wire values match the documented lowercase forms.

Useful? React with 👍 / 👎.

ProviderFormat::Mistral => "mistral",
ProviderFormat::Converse => "bedrock",
ProviderFormat::Responses => "openai", // Responses API uses OpenAI provider
ProviderFormat::Universal => "universal",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not default universal models to a non-existent provider alias

Mapping ProviderFormat::Universal to the alias string "universal" makes resolver fallback route selection produce an alias that is not registered by default, so catalog entries with format: universal and no explicit available_providers will fail later with NoProvider(...) instead of resolving to an executable provider path. This effectively makes universal-format models unroutable unless callers add a custom provider alias named universal.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f172aad5ab

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "Codex (@codex) address that feedback".

Comment thread crates/lingua/src/processing/adapters.rs
Comment thread crates/lingua/src/processing/adapters.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants