Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ The translated path currently supports:
- string input and ordered text messages;
- ordered mixed text and image user input using remote URLs or base64 data URLs;
- system prompts and supported assistant history;
- raw reasoning across all three protocols, and reasoning summaries on supported translations between Responses and Messages;
- raw reasoning across all three protocols, reasoning summaries between Responses and Messages, and unsigned summary output through Chat;
- client-defined function tools, selection, parallel-call control, calls, successful results, history, and streamed argument deltas;
- basic [hosted web search](web-search.md), URL attribution between Responses and Messages, and mandatory search with text output for downstream Chat when reasoning is absent or unsigned; signed or encrypted reasoning is rejected;
- model, output-token limit, reasoning effort, temperature, and `top_p`;
Expand All @@ -230,9 +230,9 @@ The normalized representation distinguishes raw reasoning from reasoning summari

Responses events label those representations explicitly and must agree with the configured provider capability. Chat Completions `reasoning_content` and Messages `thinking_delta` are ambiguous, so the capability profile classifies them before normalization.

A Responses reasoning lifecycle must contain raw reasoning without a summary or signature, a summary accompanied by a signature without raw reasoning, or a signature without reasoning text. A Messages thinking lifecycle follows the same pairing rule. A completely empty start may be deferred until its representation is known, and a lifecycle must not switch representations.
A Responses reasoning output lifecycle contains raw reasoning without a summary or signature, a summary with an optional signature and no raw reasoning, or a signature without reasoning text. A Messages thinking output lifecycle follows the same rule. A completely empty start may be deferred until its representation is known, and a lifecycle must not switch representations.

Although a provider profile can classify Chat `reasoning_content` as a summary, Chat has no signature field. Current translated routes through Chat therefore support only unsigned raw reasoning. Summary translation through Chat fails at the Responses or Messages signature boundary rather than silently discarding required continuation state.
Output processing preserves unsigned summaries rather than rejecting a response because its signature is missing. Chat can carry unsigned raw reasoning or summaries according to the provider profile, but rejects present signatures because it has no signature field. Request translation remains strict: replaying summary history through Responses or Messages requires its original signature. Receiving unsigned reasoning output does not establish usable continuation state.

### Opaque continuation state

Expand Down
8 changes: 4 additions & 4 deletions docs/protocols/anthropic-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,13 @@ When the application speaks Messages, an inbound thinking block is normalized as

Adaptive requests always use summarized display and an explicit effort. A manual `budget_tokens` value must be less than `max_tokens`; Molto rejects the request before transport when the budget is invalid. Reasoning history enables thinking when the current request omits reasoning configuration, using high effort for adaptive models or the default 10,000-token manual budget.

Inbound `thinking_delta` classification is a separate concern from the outbound adaptive-versus-manual model policy. A valid Messages thinking lifecycle contains one of:
Inbound `thinking_delta` classification is a separate concern from the outbound adaptive-versus-manual model policy. A Messages thinking output lifecycle contains one of:

- raw reasoning without a signature;
- a reasoning summary with a signature; or
- a reasoning summary with an optional signature; or
- a signature without reasoning text.

It must not mix or switch representations within one block. Official Anthropic continuation requires the original Anthropic-issued signature. Molto's local request model also permits an absent signature for compatible providers such as vLLM; this does not make unsigned thinking history valid against Anthropic's official API.
It must not mix or switch representations within one block. Output processing accepts a missing summary signature and projects it as an empty Messages signature without inventing continuation state. Request translation still rejects unsigned summary history before transport. Official Anthropic continuation requires the original Anthropic-issued signature. Molto's local request model also permits an absent signature for compatible providers such as vLLM; this does not make unsigned thinking history valid against Anthropic's official API.

### Opaque thinking state

Expand Down Expand Up @@ -368,7 +368,7 @@ When Messages is the translated upstream and the provider is Anthropic, missing,

Cross-protocol Messages support includes streaming and non-streaming requests for the explicitly mapped text, portable image input, thinking, custom function tools, direct tool calls, successful tool results, limited failed-result paths, conversation history, lifecycle metadata, termination, and usage semantics described above.

A route targeting Messages must supply a downstream output-token limit because Messages requires `max_tokens`. Reasoning summaries are not currently portable through Chat Completions in either direction because Chat has no signature slot. Molto also does not enforce the same-provider requirement for opaque continuation state; callers must keep signatures with their issuing provider.
A route targeting Messages must supply a downstream output-token limit because Messages requires `max_tokens`. Unsigned reasoning summary output can pass through Chat Completions, but present signatures cannot because Chat has no signature slot. Translated summary-history requests still require signatures. Molto also does not enforce the same-provider requirement for opaque continuation state; callers must keep signatures with their issuing provider.

The normalized path does not currently implement image output, non-web citations, refusals as content blocks, redacted thinking, hosted tools other than basic web search, structured output, or multiple candidates. Request fields accepted by the local Messages wrapper are not cross-protocol features unless the adapter and client map them explicitly.

Expand Down
4 changes: 2 additions & 2 deletions docs/protocols/openai-chat-completions.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ The provider or model renderer can still merge, move, or reinterpret accepted wi

### Reasoning and continuation state

Chat's single `reasoning_content` extension can be classified as either the normalized raw reasoning field or summary field according to the provider profile. Chat has no reasoning signature or encrypted continuation slot. In the current implementation, only unsigned raw reasoning is portable through Chat on a translated route. A Chat summary has no signature and therefore cannot satisfy the completed-summary contract required by Responses or Messages; in the reverse direction, a Responses or Messages summary carries a signature that Chat projection rejects rather than silently discarding. Opaque continuation state and summarized reasoning are therefore not currently portable through Chat.
Chat's single `reasoning_content` extension can be classified as either the normalized raw reasoning field or summary field according to the provider profile. Chat has no reasoning signature or encrypted continuation slot. Translated output supports unsigned raw reasoning and summaries. Responses and Messages output projection accepts a Chat summary without inventing a signature; in the reverse direction, Chat projection rejects any present signature rather than silently discarding it. Request translation still rejects unsigned summary history when normalizing or constructing a Responses or Messages request, so receiving summary text does not establish replayable continuation state.

### Tools and tool results

Expand Down Expand Up @@ -307,7 +307,7 @@ For representable output, translated Chat retains answer text and inline links w
These are implementation gaps rather than inherent claims about the Chat protocol:

- An upstream Chat stream silently uses `choices[0]`; additional choices are not rejected and are lost. Requests with `n > 1` should not use translation.
- Translated reasoning through Chat currently supports only unsigned raw reasoning, such as the `vllm` provider profile. Summary profiles fail at the target protocol's signature boundary in either direction.
- Chat cannot carry signed reasoning output. Unsigned summary output is supported, but translated Responses and Messages requests still require signatures when replaying summary history.
- Refusals, hosted tools other than basic web search, moderation, non-web annotations, audio, prediction output, and log probabilities are not carried through the normalized path. Hosted-search structured annotations are deliberately omitted from translated Chat output.
- Chat text chunks therefore use `logprobs=None`, even when another protocol could theoretically represent compatible token log probabilities.
- Chat has no normalized per-part status. Target lifecycle and status fields are synthesized where required, and pauses map to `finish_reason="length"`; other terminal reasons without an exact Chat mapping become `finish_reason="stop"`.
Expand Down
10 changes: 5 additions & 5 deletions docs/protocols/openai-responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,15 @@ Responses is explicit where Chat Completions and Messages are ambiguous:

Every explicit Responses event must agree with the selected provider capability profile. OpenAI is classified as summarized reasoning and vLLM as raw reasoning. A base URL never chooses this behavior.

A Responses reasoning lifecycle must use exactly one valid representation:
A Responses reasoning output lifecycle must use exactly one representation:

- raw reasoning content with no summary or encrypted state;
- a reasoning summary accompanied by encrypted state and no raw content; or
- a reasoning summary with optional encrypted state and no raw content; or
- encrypted state with neither summary nor raw content.

The item must not combine or switch representations between its added, delta, and done states. A completely empty start may remain deferred until its representation becomes known. When Responses is the downstream target, summary providers require a signature for a completed reasoning summary.
The item must not combine or switch representations between its added, delta, and done states. A completely empty start may remain deferred until its representation becomes known. Output processing accepts completed summaries without encrypted state. Request translation still rejects unsigned summary history before transport.

Chat Completions has one `reasoning_content` extension and no signature. Messages has one `thinking_delta` field plus signature lifecycle. Their configured provider capability decides whether their text is classified as Responses raw reasoning or summary. Only unsigned raw Chat reasoning is currently portable into Responses: a Chat summary cannot supply the signature required at Responses part completion. Responses-to-Chat summary translation also fails because Chat rejects the source signature instead of dropping it. Supported delta boundaries remain observable and are preserved by matched parity coverage.
Chat Completions has one `reasoning_content` extension and no signature. Messages has one `thinking_delta` field plus signature lifecycle. Their configured provider capability decides whether their text is classified as Responses raw reasoning or summary. Unsigned Chat reasoning output can project into Responses as raw reasoning or a summary according to that capability. Responses-to-Chat output rejects any present signature instead of dropping it; unsigned summary output is representable. Supported delta boundaries remain observable and are preserved by matched parity coverage.

### Opaque continuation state

Expand Down Expand Up @@ -390,7 +390,7 @@ A Responses stream can fail after HTTP `200`: the SDK raises `APIError` on the c
The following are implementation gaps, not general claims that the source data cannot exist:

- multiple Chat Completions choices; the current translated client reads only `choices[0]`;
- summarized reasoning through Chat Completions; Chat has no signature slot, so current translation fails in either direction rather than discarding required continuation state;
- signed reasoning output through Chat Completions and unsigned summary history on translated requests; Chat has no signature slot, while Responses and Messages request translation requires summary signatures;
- refusals as content, hosted tools other than basic search, failed client-function result semantics, redacted thinking, non-web annotations, moderation, and other multimodal output;
- log probability transport across the normalized representation;
- Chat audio and accepted or rejected prediction-token details;
Expand Down
6 changes: 3 additions & 3 deletions python/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Three upstream endpoints are implemented:
- `chat/completions`: native Chat Completions passthrough or cross-protocol translation through Chat Completions;
- `messages`: native Anthropic Messages passthrough or translated through the normalized representation.

Native same-protocol and cross-protocol routes support streaming and non-streaming requests. Cross-protocol routes cover text, portable image input, raw reasoning, reasoning summaries between Responses and Messages, function tools, tool calls and results, conversation history, prompt-cache intent, lifecycle metadata, and token usage. Because Chat Completions has no signature field, translated routes through Chat currently support only unsigned raw reasoning.
Native same-protocol and cross-protocol routes support streaming and non-streaming requests. Cross-protocol routes cover text, portable image input, raw reasoning, reasoning summaries between Responses and Messages, function tools, tool calls and results, conversation history, prompt-cache intent, lifecycle metadata, and token usage. Translated output through Chat supports unsigned raw reasoning and summaries; present signatures remain unsupported because Chat has no signature field. Translated summary-history requests still require signatures.

## Route configuration

Expand Down Expand Up @@ -256,7 +256,7 @@ OpenAIChatCompletionsAdapter.project_events()
ChatCompletionChunk SDK stream
```

`reasoning_content` is a provider extension to the OpenAI Chat schema, but the field itself does not distinguish raw reasoning from a reasoning summary. Molto models the extension only on assistant messages and uses `ProviderCapabilities.thinking` to classify it. OpenAI classifies it as a summary and vLLM as raw reasoning. Responses events already distinguish `response.reasoning_text.*` from `response.reasoning_summary_*`; their explicit event types remain authoritative. Classification does not make summaries portable through Chat: Responses and Messages require a signature for completed summaries, while Chat has no signature field.
`reasoning_content` is a provider extension to the OpenAI Chat schema, but the field itself does not distinguish raw reasoning from a reasoning summary. Molto models the extension only on assistant messages and uses `ProviderCapabilities.thinking` to classify it. OpenAI classifies it as a summary and vLLM as raw reasoning. Responses events already distinguish `response.reasoning_text.*` from `response.reasoning_summary_*`; their explicit event types remain authoritative. Output normalization and projection tolerate unsigned summaries, including those received through Chat. Present signatures remain unrepresentable in Chat, and translated Responses and Messages request construction still requires signatures for summary history.

## Normalized request model

Expand Down Expand Up @@ -500,7 +500,7 @@ Parity differs by path:

## Current limitations and extension path

The current public paths support native and translated streaming and non-streaming responses for text, portable image input, raw reasoning, reasoning summaries between Responses and Messages, and client-defined function tools. Routes through Chat Completions currently support only unsigned raw reasoning. Function-tool support includes definitions, selection, parallel-call control, successful results, conversation history, and streamed JSON arguments. Native routes preserve hosted web search. Basic hosted search translation is supported through Responses and Messages upstreams, with text-only projection for downstream Chat when reasoning is absent or unsigned; signed or encrypted reasoning raises an error; translated Chat upstreams reject normalized search declarations and history, while opaque `extra_body.web_search_options` is forwarded and returned annotations are dropped. Other hosted tools, failed client-function result semantics outside Messages, other multimodal content, and additional provider capabilities are not complete yet. The matched Responses/Messages fixtures also map the reconstructible opaque reasoning snapshots under the assumption that OpenAI serves both endpoints; opaque state is not portable across providers, the implementation does not enforce its issuer, and the separately recorded terminal Responses ciphertext is not byte-reconstructible through Messages.
The current public paths support native and translated streaming and non-streaming responses for text, portable image input, raw reasoning, reasoning summaries between Responses and Messages, and client-defined function tools. Output through Chat Completions supports unsigned raw reasoning and summaries, but rejects present signatures. Translated summary-history requests still require signatures. Function-tool support includes definitions, selection, parallel-call control, successful results, conversation history, and streamed JSON arguments. Native routes preserve hosted web search. Basic hosted search translation is supported through Responses and Messages upstreams, with text-only projection for downstream Chat when reasoning is absent or unsigned; signed or encrypted reasoning raises an error; translated Chat upstreams reject normalized search declarations and history, while opaque `extra_body.web_search_options` is forwarded and returned annotations are dropped. Other hosted tools, failed client-function result semantics outside Messages, other multimodal content, and additional provider capabilities are not complete yet. The matched Responses/Messages fixtures also map the reconstructible opaque reasoning snapshots under the assumption that OpenAI serves both endpoints; opaque state is not portable across providers, the implementation does not enforce its issuer, and the separately recorded terminal Responses ciphertext is not byte-reconstructible through Messages.

Function and hosted-search definitions and tool selection use provider-neutral normalized types. Protocol-specific function schemas and tool-choice shapes remain at their adapters and clients.

Expand Down
Loading
Loading