Skip to content

[Python] Support the OpenAI Responses API #518

Closed

Description

@robgruen

Goal

Add a backward-compatible Python model integration for the OpenAI Responses API, alongside the existing Chat Completions path.

This is an owner-requested tracking item. It is separate from the Python authentication/client-injection work in #516 and the TypeScript authentication parity PR. No Python Responses API implementation is included in those changes.

Scope and acceptance criteria

  • Provide an explicit, documented way to select the Responses API. Preserve existing Chat Completions defaults, factory arguments, and environment-variable behavior. Document endpoint inference if it is offered.
  • Construct Responses requests with input and the appropriate model/deployment parameters, rather than sending Chat-Completions-only request fields.
  • Parse supported Responses text outputs and explicitly report missing, malformed, refused, or blocked output. Do not return success-shaped fallback text or bypass TypeChat schema validation/repair.
  • Support both the built-in HTTP model path and reuse of a configured client's responses.create API. Chat-only clients must remain usable without requiring a Responses client member.
  • Preserve existing API-key and token-provider authentication. Define supported OpenAI-compatible/Azure endpoint formats and model/deployment behavior without imposing new environment-variable names on configured-client callers.
  • Retain the HTTP model's retry, timeout, and response-size safeguards. Preserve caller ownership and document which controls are delegated to SDK-backed clients.
  • Add no required SDK or Azure Identity dependencies; use the existing transport and structural client contracts.
  • Add deterministic offline tests for request/output shapes, mode selection, legacy Chat Completions behavior, token providers across retries, SDK-client reuse, malformed/refused/blocked output, and translator validation/repair.
  • Update the Python API documentation and add a minimal Responses example.

Boundaries

This item covers non-streaming text completions through the Responses API, not tool execution, streaming, or agent orchestration. Multimodal prompt support is tracked separately and is not a prerequisite for text-only Responses support. Add combined-path regression coverage when both capabilities are available.

Context

Activity

  1. added
    SuggestionNew feature or request
    Language: PythonPertains to the Python implementation of TypeChat.
    on Nov 3, 2026
  2. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    /typechat propose

  3. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Work proposal P1

    Proposal for community discussion, not accepted work or permission to build.

    Recommendation

    I recommend adding an explicit Python Responses mode to the existing model factories and configured-client adapter, rather than replacing Chat Completions or introducing an SDK dependency. The inspected Python model still sends messages, reads choices, and calls chat.completions.create for configured clients. This should extend robgruen's merged authentication and client-reuse work in PR 516. Merged TypeScript PR 305 provides prior art for keeping the two API formats separate; open PR 519 is TypeScript-only and does not implement this Python capability.

    My recommendation is a keyword-only use_responses_api=False option across the factories and adapter, with no endpoint-based inference initially. Requiring explicit selection and a complete Responses request endpoint for HTTP calls is less automatic than the TypeScript approach, but preserves existing Python routing and avoids guessing what a custom endpoint supports. Responses requests would use input instead of messages and omit n. Keep the existing HTTP transport loop, and add a separate ResponsesClient protocol, a description of the client methods TypeChat needs, so chat-only clients remain valid without a responses member.

    Both paths should accept completed Responses text output through the same parsing rules, preserve the order of supported assistant text parts, and report missing, malformed, refused, filtered, or incomplete output explicitly, even when partial text accompanies a failure. The extracted text must still pass through the existing JSON translator's validation and repair. Keep API-key behavior, per-attempt Azure token providers, and HTTP limits intact; configured clients retain their own authentication, retries, timeouts, response-size controls, and lifecycle. Streaming, tool execution, and image support stay outside this proposal.

    For Azure HTTP calls, I recommend an initial contract of a full /openai/v1/responses endpoint plus an explicit deployment name in model, with the supplied endpoint and query preserved. The current Azure factory has no model argument, so this needs an additive keyword-only argument and pass-through from the environment-based factory. Is that initial Azure contract sufficient, or must the first version also support a deployment-scoped route with api-version? If the older route is required, which path format and API version are needed, and can you provide a public request/response fixture with private data removed?

    Changes since the previous proposal

    • This is the initial recommendation; the complete frozen conversation contains no preceding proposal or community comments. It recommends explicit mode selection, reuse of the merged Python authentication/client foundation, shared Responses parsing rules, and a concrete v1 Azure baseline to preserve compatibility while exposing the remaining endpoint/version question.

    Direction and readiness

    The frozen GOALS.md supports this bounded extension under G1 for type-driven interfaces, G2 for explicit errors and validated output, G3 for compatible Python APIs, G4 for dependency-free integration, and G5 for documentation and deterministic tests. It extends an existing optional provider integration without tying the core to a vendor, consistent with N3. Keeping validation intact respects N4, and excluding tool execution and orchestration respects N1. The recommendation itself does not establish approval under N5.

    The frozen issue does not identify which Azure Responses endpoint formats or API versions the first release must support. The proposal recommends a concrete v1 baseline with an explicit deployment-name model value, but whether a deployment-scoped, query-versioned route is also required remains a blocking compatibility question. That answer is needed before the support matrix and proposed criteria can be frozen for an owner decision. The proposed API and parsing choices are recommendations, not recorded agreement or authorization to implement.

    Goal

    Let Python applications explicitly use non-streaming Responses text completions through either TypeChat's existing HTTP transport or a caller-configured asynchronous client, while preserving Chat Completions compatibility and TypeChat's validation and repair guarantees.

    Scope

    • Add keyword-only use_responses_api=False selection to create_language_model, create_openai_language_model, create_azure_openai_language_model, and create_openai_language_model_from_client. Do not infer the mode from endpoint names. For opted-in HTTP calls, require a complete Responses request endpoint instead of silently reusing or rewriting the Chat Completions default.
    • Keep HttpxLanguageModel's transport, token-provider invocation, retries, timeout, capped response reader, and lifecycle. Add mode-specific request construction and common Responses text parsing rules for HTTP mappings and configured-client objects. Leave TypeChatLanguageModel, text PromptSection inputs, and the translator contract unchanged.
    • Add and export a separate ResponsesClient structural protocol for responses.create without SDK imports. Keep ChatCompletionClient unchanged and make client-adapter typing depend on the explicitly selected mode, so neither kind of minimal client needs the other API member.
    • Recommend an initial HTTP endpoint matrix of complete OpenAI-compatible /v1/responses endpoints and Azure /openai/v1/responses endpoints. Supply model or Azure deployment explicitly, adding keyword-only model pass-through to the Azure and environment-based factories. Preserve caller-supplied endpoint/query values and configured-client settings. Resolve the recorded Azure route/version question before treating this matrix as settled.
    • Accept completed assistant message/output_text results in order, distinguish present empty text from absent text, and reject malformed, refused, filtered, failed, incomplete, nonterminal, and unsupported tool-only output explicitly. Keep schema validation and bounded repair in the existing translator, and propagate configured-client exceptions and cancellation unchanged.
    • Extend the existing Python regression coverage, API documentation, and examples with deterministic text-only HTTP and configured-client Responses cases. Preserve the contributions in merged PR 516, use merged PR 305 as TypeScript prior art, and treat open PR 519 as related TypeScript work rather than a Python dependency or an approved implementation.

    Non-goals

    • Do not implement streaming, tool execution, agent orchestration, multimodal prompts, hosted state, or automatic fallback between Responses and Chat Completions. Existing translator repair history remains application-local behavior, not a new conversation service.
    • Do not acquire, store, cache, or renew credentials in TypeChat, import provider SDKs into the library, add required SDK or Azure Identity dependencies, or take ownership of caller-configured clients and their transport controls.
    • Do not change existing Chat Completions defaults or environment behavior, reimplement merged Python authentication work, modify TypeScript, or make acceptance or merging of PR 519 a prerequisite.
    • Do not claim universal OpenAI-compatible provider support or support for every legacy Azure endpoint and API version. The proposed initial v1 matrix remains subject to the specific Azure compatibility clarification.

    Acceptance criteria

    • A keyword-only use_responses_api option defaults to False on create_language_model, both HTTP factories, and create_openai_language_model_from_client. Endpoint spelling alone never changes the selected API. With the option omitted or False, existing positional/keyword calls, environment routing and precedence, organization aliases, literal identity values, Chat Completions request shapes, and headers remain unchanged.
    • With Responses explicitly selected and a complete endpoint supplied for HTTP, requests contain input, the required model or deployment value, and non-streaming behavior, but no messages or n field. Do not copy the Chat Completions temperature default into the new minimal request. String prompts and system/user/assistant text sections retain their content and order without mutating caller data. Missing or blank required model values fail before dispatch.
    • The proposed initial endpoint matrix covers complete OpenAI-compatible /v1/responses endpoints and Azure /openai/v1/responses endpoints. The Azure factory and create_language_model accept an additive keyword-only model value for the Azure deployment. Mock requests show that supplied endpoints and query strings are unchanged. Responses mode with a missing HTTP endpoint fails explicitly rather than using the Chat Completions default, rewriting a route, or falling back to another API. Configured clients require no endpoint or environment-variable configuration from TypeChat.
    • Separate structural ResponsesClient and ChatCompletionClient contracts allow a responses-only client in explicitly selected Responses mode and a chat-only client in default mode, including static type-check fixtures. The adapter calls the selected create method once per completion, preserves the supplied model/deployment value and client instance, does not reconfigure or close it, adds no retry/timeout layer, and propagates client exceptions and cancellation unchanged.
    • HTTP mapping fixtures and configured-client object fixtures for completed Responses envelopes produce the exact concatenation of supported assistant message/output_text parts in output order. Known non-text reasoning items do not become completion text. An explicitly present empty text string is distinguished from absent text and remains subject to translator validation. A top-level convenience output_text value alone cannot bypass canonical envelope and output checks.
    • Missing or malformed envelope/output/content containers and non-string text produce explicit Failure results. Refusal, content filtering, failed, cancelled, incomplete, or nonterminal status prevents success even when text is also present. Unsupported tool-only output is an explicit failure, not executed or converted to fabricated text. Error reporting does not dump entire raw provider payloads or credentials.
    • Offline translator fixtures exercise both HTTP and configured-client Responses paths: valid schema-conforming JSON succeeds; invalid JSON and schema-invalid JSON follow the existing bounded repair path; exhausted repair retains the existing failure information. Repair requests preserve assistant/user message order. Provider refusals and other model Failure results are not treated as successful JSON or retried as schema repair.
    • Azure Responses HTTP fixtures preserve API-key headers and API-key/token-provider exclusivity. Synchronous and asynchronous token providers, including awaitable results, are resolved and validated once per HTTP attempt, including retries, with changing tokens visible on successive mocked attempts. Invalid provider results fail without dispatch or credential exposure, cancellation propagates, and credential caching and renewal stay caller-owned.
    • Responses uses the existing HTTP loop and capped reader. Mock fixtures preserve defaults of three retries, a one-second retry pause, a ten-second request timeout, and a 100 MiB response limit. Requests never exceed max_retry_attempts plus the initial attempt, and configured timeouts are forwarded. A byte limit B permits B bytes and rejects B+1 bytes for advertised and incrementally read bodies; disabling the limit preserves existing behavior.
    • Python API documentation and a minimal text-only translation example show explicit Responses selection, complete HTTP endpoint requirements, model/deployment handling, configured-client reuse, and ownership of authentication, retries, timeouts, and response-size controls. The proposed endpoint matrix and unsupported cases are explicit. New regression coverage uses deterministic offline fixtures and existing tooling, imports need no provider SDK, and no required SDK or Azure Identity dependencies are added. Combined image/Responses coverage is added only when separate multimodal support is available.

    Open questions

    • For robgruen: Is initial Azure Responses HTTP support for /openai/v1/responses with an explicit deployment-name model value sufficient? I recommend that baseline. If the first release must also support a deployment-scoped route with api-version, which path format and API version are required, and can you provide a public request/response fixture with private data removed?

    Evidence limits and assumptions

    • Azure Responses endpoint/version compatibility and the behavior of arbitrary OpenAI-compatible services are not established by the inspected repository evidence. No external provider documentation, reproduction links, or live endpoints were accessed.
    • TypeScript prior art was inspected through PR 305's merged model diff and PR 519's description and full head metadata, not the complete current TypeScript model or PR 519 implementation. Their reported validation was not independently verified.
    • Python model and translator code, exports, README, and targeted test sources were inspected at the trusted revision; the site's full Python API documentation was not read. No code, tests, reproductions, installations, or browser actions were executed. Later issue comments were not fetched or incorporated.

    Related contributions: #516, #305, #519.

    Not eligible for acceptance yet. Discuss the remaining questions and request /typechat propose again.

    Proposal run | Approved scope policy

  4. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    I don't know, some endpoints sit behind proxies that don't surface if it's a responses or chat endpoint. Responses is now the standard so we should consider adopting that. Couldn't we have a fallback mechanism that we could attempt (maybe that should be configurable i.e. turn it on/off)?

    Models have moved on and become more sophisticated, we should as well (while maintaining backwards compat).

  5. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    /typechat propose

  6. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Work proposal P2

    Proposal for community discussion, not accepted work or permission to build.

    Recommendation

    You're right that a proxy URL can hide the upstream API, so its spelling should not determine the request format. In the inspected Python code, the HTTP model always sends messages and reads choices, and the configured-client adapter always calls chat.completions.create. Both already support caller-supplied configuration. I recommend retaining P1's explicit use_responses_api option, accepting complete proxy destinations without requiring a Responses path suffix, and making Responses the recommended choice in new examples while keeping existing Chat Completions defaults unchanged.

    I would revise P1 to add fallback_to_chat_completions=False: an optional switch from Responses to Chat Completions, not a second attempt after every error. With it enabled, try Responses first and switch once only when a documented, fixture-backed error specifically identifies the Responses operation as unsupported. HTTP callers must supply the fallback destination; they may explicitly use the same proxy destination for both formats. A bare 404, an authentication error, a timeout, or a refusal must not trigger the switch. Emit a warning without request or credential details when switching. This is safer than guessing from URLs or broadly retrying another API, which can hide configuration problems or repeat a request that already generated output.

    Both APIs should return real completion text through TypeChat's existing schema validation, which checks generated JSON against the application's types, and bounded repair. Keep HTTP authentication and transport safeguards intact. Configured clients retain their authentication, transport controls, and ownership; only callers enabling fallback need both client API members. This extends robgruen's merged Python integration in PR 516 and draws on Copilot's merged TypeScript API separation in PR 305. Robgruen's PR 519 is now merged, but remains TypeScript-only rather than a Python Responses implementation.

    For the initial guarantee, I recommend the OpenAI v1 and Azure v1 text contracts plus proxy aliases implementing those contracts, using an explicit model or deployment name and preserving supplied paths and queries. The remaining blockers are the exact unsupported-operation signal and whether additional Azure route/version contracts must be guaranteed initially. Can you or another contributor provide public, sanitized HTTP and configured-client error fixtures for an unsupported Responses operation? Does the first release also need a deployment-scoped, query-versioned Azure contract, and if so, which public request/response fixture defines it?

    Changes since the previous proposal

    • P1 excluded automatic API fallback. In response to robgruen's feedback, this revision recommends an explicit, disabled-by-default Responses-to-Chat switch limited to fixture-backed unsupported-operation errors. It adds one-switch and shared-retry bounds, a sanitized warning, and negative cases so fallback cannot hide refusals, configuration failures, or ambiguous request outcomes.
    • Clarified that a complete HTTP destination need not expose an API-specific path suffix. Explicit mode selection governs the request format, and callers supply both destinations when enabling fallback, including an intentional shared proxy destination. This addresses hidden proxy routing without URL guessing, rewriting, or capability probes.
    • Made Responses the recommended explicit choice in new examples while retaining P1's backward-compatible defaults. Kept a concrete OpenAI/Azure v1 contract recommendation, but did not treat the unanswered deployment-scoped Azure question as settled. Public HTTP and client unsupported-operation fixtures are now an additional blocking evidence need for fallback.
    • Updated the contribution assessment because PR 519 is now merged rather than open. It remains TypeScript-only; the Python proposal still extends robgruen's merged PR 516 and preserves Copilot's PR 305 as prior art. Source conclusions remain tied to the trusted revision rather than adopting later branch content.

    Direction and readiness

    The frozen, approved GOALS.md supports this extension under G1 for type-defined interfaces, G2 for reliable validation and explicit failures, G3 for compatible Python APIs, G4 for optional integrations without SDK dependencies, and G5 for documentation and deterministic tests. It extends an existing optional provider integration without binding the core to that provider, consistent with N3. Restricting fallback to API compatibility, preserving validation, and excluding tool execution and orchestration respect N1, N2, and N4. Neither the recommendation nor community interest establishes approval under N5.

    The inspected HTTP code reports status and reason but establishes no reliable unsupported-Responses error contract. No public HTTP or configured-client fixture in the frozen conversation distinguishes that condition from a missing model, deployment, or route. Those fixtures are needed to define a narrow fallback allowlist. The earlier Azure route/version question also remains unanswered; the proposed v1 baseline is a recommendation, not recorded agreement. Concrete terms and criteria are offered for discussion, but these blocking questions prevent an acceptance recommendation.

    Goal

    Let Python applications explicitly use non-streaming Responses text completions over the existing HTTP transport or a caller-configured asynchronous client, including proxy destinations that hide the upstream API, with optional narrowly classified Chat Completions fallback and unchanged legacy defaults, validation, and repair guarantees.

    Scope

    • Add keyword-only use_responses_api=False and fallback_to_chat_completions=False to create_language_model, create_openai_language_model, create_azure_openai_language_model, and create_openai_language_model_from_client. Reject fallback unless Responses is selected. Preserve existing positional arguments and default behavior. Recommend Responses in new examples without silently migrating existing callers.
    • Require explicit complete HTTP destinations for Responses and, when enabled, fallback_endpoint for Chat Completions. Accept opaque proxy aliases without suffix checks, URL rewriting, inference, or extra capability probes. The caller may explicitly choose the same destination for both formats. Recommend initial guarantees for OpenAI v1 and Azure v1 text contracts plus equivalent proxy aliases. Leave any additional deployment-scoped Azure contract contingent on the blocking compatibility clarification.
    • Reuse HttpxLanguageModel's transport and authentication. Add mode-specific request bodies and additive keyword-only model pass-through to the Azure and environment-based factories. Responses requires an explicit model or deployment value, uses input, and omits Chat-Completions-only fields and the inherited temperature default. Use the same caller-selected model/deployment for fallback; assume it supports the requested text task on both APIs rather than substituting another model.
    • Permit one request-local Responses-to-Chat switch only for documented, fixture-backed errors explicitly rejecting the Responses operation before generation. Keep fallback off by default, emit a sanitized warning when switching, and share the HTTP retry allowance across both APIs with at most one extra dispatch for the switch. Do not switch for ambiguous transport, configuration, output, or validation failures. Final failures stay failures; no placeholder completion text is generated.
    • Add and export a separate ResponsesClient structural protocol, a description of the asynchronous client members TypeChat requires without SDK imports. Keep ChatCompletionClient unchanged. Require both API members only for fallback-enabled clients. Preserve client configuration and ownership; do not add a retry/timeout layer, and propagate exceptions unchanged except for the specifically classified opt-in switch condition.
    • Use common Responses parsing rules for HTTP mappings and client objects. Accept ordered completed assistant text, distinguish empty from absent text, and report malformed, refused, filtered, failed, incomplete, nonterminal, or unsupported output explicitly. Keep TypeChatLanguageModel, text PromptSection inputs, and translator validation/repair contracts unchanged.
    • Extend existing Python regression coverage, API documentation, and examples with offline Responses and bounded-fallback cases. Build on robgruen's merged PR 516 rather than duplicating authentication/client work. Preserve Copilot's merged PR 305 as TypeScript prior art and recognize robgruen's now-merged PR 519 as related TypeScript work, not a Python implementation or dependency.

    Non-goals

    • Do not implement streaming, tool execution, multimodal prompts, agent orchestration, hosting, storage, or a remote conversation-state service. Separate multimodal work is not a prerequisite for text-only Responses support.
    • Do not import provider SDKs into TypeChat, add required SDK or Azure Identity dependencies, manage credential acquisition/caching/renewal, or take ownership of caller-configured clients and their transport controls.
    • Do not change existing Chat Completions defaults or environment semantics, infer capabilities from URL names or generic failures, send discovery probes, silently substitute models, or perform general cross-provider failover. Do not change TypeScript as part of this Python item.
    • Do not claim universal OpenAI-compatible service support or guarantee every Azure path/API version. Additional Azure contract guarantees and the exact fallback allowlist require the stated public evidence before the proposal can be considered ready.

    Acceptance criteria

    • All four model factories expose keyword-only use_responses_api=False and fallback_to_chat_completions=False. Omitting both preserves existing positional/keyword calls, Chat Completions bodies and headers, environment routing and precedence, organization aliases, and literal identity values. Endpoint spelling alone never selects a format. Enabling fallback without selecting Responses raises an explicit configuration error before dispatch.
    • Responses HTTP mode requires an explicit complete destination; enabled HTTP fallback additionally requires fallback_endpoint. Tests preserve supplied paths and query strings for OpenAI /v1/responses, Azure /openai/v1/responses, and equivalent proxy aliases with no API-specific suffix. Both destinations may explicitly be the same proxy destination. No destination is inferred or rewritten, no capability probe is sent, and missing configuration fails before dispatch. Any additional guaranteed Azure contract has its own documented fixture.
    • HTTP and configured-client Responses requests use input, a nonempty explicit model or deployment value, and non-streaming behavior, with no messages, n, or inherited Chat Completions temperature default. Add keyword-only model support to the Azure and environment-based factories without changing legacy Azure bodies. String prompts and system/user/assistant text sections preserve content and order without caller-data mutation. Fallback uses the same explicitly selected model/deployment, not a substituted model.
    • A separate exported ResponsesClient structural contract accepts a Responses-only client in Responses-only mode. The unchanged ChatCompletionClient contract accepts a chat-only client in default mode; only fallback-enabled mode requires both members. Static type fixtures cover all three cases. Adapters preserve the supplied instance and settings, do not close or reconfigure it, and add no SDK retry/timeout layer. Except for the explicitly classified opt-in fallback condition, client exceptions and cancellation propagate unchanged.
    • Positive HTTP and configured-client fixtures for each documented unsupported-operation code cause exactly one Responses-to-Chat switch when enabled, and none when disabled. A switch emits one warning containing only fixed API/reason labels, not endpoint, prompt, credentials, or raw provider output. The fallback sends a Chat Completions request, not the Responses body. No switch back, capability cache, or permanent mode change occurs; each complete call starts in its configured mode.
    • Negative fixtures prove no API switch for bare 400/404 statuses, missing models/deployments, authentication/authorization errors, rate limits, server errors, network errors, timeouts, cancellation, oversized bodies, malformed/missing output, refusals, filtering, or incomplete output. Existing same-API transient retries remain available. No output-validation error is classified as API incompatibility. If the Chat fallback also fails, its normal failure or exception is surfaced rather than replaced with fabricated text, and the switch warning remains observable.
    • HTTP mapping and configured-client object fixtures use the same Responses parsing rules. Completed assistant message/output_text parts concatenate exactly in output order; known reasoning items are not completion text. Present empty text is distinguished from absent text and still reaches translator validation. Malformed containers or non-string text, refusal/filtering, failed/incomplete/nonterminal status, and unsupported tool output produce explicit Failure results even if text is also present. A convenience output_text property alone cannot bypass canonical envelope checks. Errors do not dump raw payloads.
    • Offline translator fixtures cover direct HTTP Responses, configured-client Responses, and a successful Chat fallback. Schema-conforming JSON succeeds; invalid JSON and schema-invalid JSON follow the existing bounded repair path, preserving assistant/user history order and final failure information. Provider Failure results do not become successful JSON, trigger schema repair, or cause another API switch. No schema-generation, validation, repair-limit, or Failure-payload semantics change.
    • HTTP fixtures retain defaults of three retries, a one-second pause, a ten-second request timeout, and a 100 MiB response limit. With retry limit R, completion uses at most R+1 dispatches without a switch or R+2 with one switch, sharing retries across APIs rather than restarting them. Both success and inspected error bodies use the capped reader: limit B accepts B bytes and rejects B+1 for advertised and incremental bodies. Sync, async, and awaitable token providers resolve afresh per attempt, including fallback; invalid tokens fail before dispatch. Existing authentication exclusivity, cancellation, configured limits, and disabled-size-limit behavior remain intact.
    • Python API documentation and a minimal text-only translation example show Responses as the recommended explicit choice for new integrations, unchanged legacy defaults, opaque proxy destinations, the supported endpoint/model matrix, fallback disabled by default, exact fixture-backed triggers, warning behavior, and request bounds. Document caller-owned SDK authentication, retries, timeouts, size controls, and lifecycle. Imports and deterministic regression/type fixtures require no provider SDK or Azure Identity dependency. Combined image/Responses coverage is conditional on the separate multimodal capability being available.

    Open questions

    • Can robgruen or another contributor provide public, sanitized HTTP and configured-client error fixtures for a Responses operation that is explicitly unsupported? Include the HTTP status, structured error code, and client exception fields, without credentials, private endpoints, or user content. These must distinguish API incompatibility from missing models, deployments, and routes before fallback triggers can be finalized.
    • For robgruen: Must the first release guarantee a deployment-scoped, query-versioned Azure Responses contract in addition to the recommended Azure v1 contract and equivalent proxy aliases? If so, which path format, API version, model/deployment placement, and public sanitized request/response fixture define that additional guarantee? No endpoint suffix will be required or used to infer the API.

    Evidence limits and assumptions

    • Discussion evidence is limited to the complete frozen issue and its two comments: P1 and robgruen's proxy/fallback feedback. No later target-thread comments were fetched. Python source, exports, documentation, and targeted test sources were inspected at the trusted revision, not a moving branch.
    • No public proxy/Azure unsupported-operation or configured-client exception fixture appears in the frozen conversation. External provider documentation, reproduction links, other repositories, and live endpoints were not accessed. Exact safe fallback codes and additional Azure route/version compatibility are therefore not established.
    • PR 305's model patch and PR 516/519 details were inspected. The complete current TypeScript model and PR 519 implementation patch were not checked. PR 519's current merged status is contribution metadata, not a substitute for source at the trusted revision. PR descriptions' reported validation was not independently verified.
    • No code, reproductions, tests, installations, or browser actions were executed. Existing test sources informed the proposed regression cases; the proposed Python Responses and fallback behavior is not an implemented or verified capability.

    Related contributions: #516, #305, #519.

    Not eligible for acceptance yet. Discuss the remaining questions and request /typechat propose again.

    Proposal run | Approved scope policy

  7. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor
    1. Yes, we can provide an endpoint for testing ensuring that everything works.
    2. Yes, it should work for all of the contracts. We can't guarantee what the URL will look like since we have no idea or control over the service. Either it returns a result or does not and we have to handle it accordingly.
    3. We will also want to update the samples/documentation to include responses endpoints. We'll want to retain at least one chat endpoint example.
  8. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    /typechat propose

  9. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Work proposal P3

    Proposal for community discussion, not accepted work or permission to build.

    Recommendation

    I recommend keeping P2's explicit Responses selection and treating endpoint addresses as opaque: the selected request and response format, not an address suffix, defines compatibility. Cover the environment factory, both HTTP factories, and the configured-client adapter, preserving supplied paths and queries. I take your all-contracts clarification to mean consistent support across those integration paths and compatible provider/proxy destinations, not a guarantee that every service or API version implements Responses. There is no need to choose one Azure route spelling as a prerequisite.

    The inspected Python HTTP code still sends messages and reads choices, while the adapter calls chat.completions.create. Extend those paths with use_responses_api=False by default and a separate ResponsesClient contract describing the asynchronous client members TypeChat needs. This preserves chat-only clients and builds on your merged PR 516 rather than duplicating it; Copilot's merged PR 305 and your merged PR 519 provide TypeScript prior art. Recommend explicit Responses selection in new examples, while retaining at least one Chat Completions example and the existing defaults.

    Keep fallback_to_chat_completions=False and permit one Responses-to-Chat switch only for a documented structured error that explicitly rejects the Responses operation before generation. HTTP callers would supply fallback_endpoint, which may intentionally be the same proxy destination; only fallback-enabled clients need both API members. Emit a warning without request details and share the HTTP retry allowance across both APIs. This is less automatic than switching after any failure, but avoids hiding configuration errors, bypassing refusals, or repeating a request with an uncertain outcome. Successful text from either API must still pass through TypeChat's schema validation and bounded repair.

    Thanks for offering a test endpoint. It could support a later, separately authorized integration check, but the remaining design evidence is a public, sanitized unsupported-operation example for each transport. Could you or another contributor provide the HTTP status and structured error fields, plus the corresponding configured-client exception attributes, that distinguish an unsupported Responses operation from a missing model, deployment, or route? The inspected code and frozen conversation do not yet define that signal; a failed request alone is not enough to safely trigger another API call.

    Changes since the previous proposal

    • P2 already allowed opaque proxy aliases. In response to the latest clarification, this revision stops treating the Azure route/version choice as a blocking design decision and defines destination handling independently of the selected text data contract. It preserves supplied paths/queries without claiming that every provider version supports Responses.
    • Made coverage of all existing Python construction, authentication, and client contracts explicit in the proposed offline regression matrix. This translates the latest all-contracts request into observable checks rather than an unverifiable promise about arbitrary services, and states that interpretation as an assumption.
    • Added a concrete requirement to retain at least one Chat Completions example while adding minimal Responses examples and updating Python API documentation, following the latest sample/documentation feedback.
    • Acknowledged the offer of a live test endpoint and narrowed the remaining blocker to public HTTP/client unsupported-operation fixtures. A future separately authorized live check can supplement those fixtures but cannot replace a safe fallback contract; no endpoint was accessed in this review.

    Direction and readiness

    The approved GOALS.md supplied at the frozen trusted revision supports this bounded extension under G1 for type-defined interfaces, G2 for reliable validation and explicit failures, G3 for compatible Python APIs, G4 for optional dependency-free integrations, and G5 for useful documentation and deterministic tests. Extending an existing optional provider integration without binding the core to it respects N3. Excluding orchestration and application business logic respects N1 and N2; preserving validation respects N4. Neither this recommendation nor earlier public proposals establish approval under N5.

    The latest feedback supports addressing complete opaque destinations and retaining a Chat Completions example, so the earlier Azure route-spelling question need not block the recommended contract-based design. All-contract coverage is an explicit integration-coverage assumption, not a claim of universal provider/version compatibility. The remaining blocker is the exact structured unsupported-operation signal for HTTP and configured clients. No public fixtures in the frozen conversation distinguish that condition from configuration or ambiguous request failures. Concrete proposed terms and tests are provided, but the fallback allowlist cannot yet be frozen for an owner acceptance decision. Prior proposals and feedback are not acceptance of these terms.

    Goal

    Let Python applications explicitly select non-streaming Responses text completions through existing HTTP factories or a configured asynchronous client, including opaque proxy destinations, with optional narrowly classified Chat Completions fallback and unchanged legacy defaults, validation, repair, and client ownership.

    Scope

    • Add keyword-only use_responses_api=False and fallback_to_chat_completions=False to create_language_model, create_openai_language_model, create_azure_openai_language_model, and create_openai_language_model_from_client. Reject fallback unless Responses is selected. Keep existing positional arguments, defaults, environment behavior, and Chat Completions requests unchanged.
    • Require explicit complete destinations for Responses HTTP calls and fallback_endpoint when fallback is enabled. Pass supplied paths and queries through unchanged, including opaque proxies and deployment-scoped routes, without inferring mode or deriving another route. Callers may explicitly reuse one destination for both APIs. Define support by the selected OpenAI-compatible/Azure text data contract, not address spelling; callers supply any required API-version query. Interpret all-contract coverage as covering existing Python construction, authentication, and client contracts, not every incompatible provider data format.
    • Build Responses bodies with input, explicit model or deployment, and non-streaming behavior, without messages, n, or an inherited temperature default. Add keyword-only Azure model/deployment pass-through, including the Azure branch of create_language_model. Preserve text-role content and order. Assume fallback destinations accept the same caller-selected model/deployment and authentication; fail normally rather than silently substitute either.
    • Retain HttpxLanguageModel's transport, lifecycle, authentication, per-attempt token providers, and configurable retry, timeout, and response-size controls. Read new error payloads needed for fallback through the existing capped reader. Share the HTTP retry allowance across both APIs rather than restarting it when switching.
    • Permit at most one Responses-to-Chat switch per complete call, only when enabled and a documented structured error explicitly rejects the Responses operation before generation. Define supported signals from public HTTP and client fixtures before freezing these proposed terms. Emit one fixed, sanitized warning on switching. Do not switch for bare status codes, ambiguous failures, output rejection, or validation errors; do not cache capabilities or permanently change the configured mode.
    • Export a separate ResponsesClient structural protocol, a description of asynchronous client members rather than an SDK dependency. Keep ChatCompletionClient unchanged; require both API members only for fallback-enabled clients. Reuse supplied client configuration and ownership without closing it or adding transport retries/timeouts. Propagate exceptions unchanged except for the explicitly classified opt-in switch, and propagate cancellation unchanged.
    • Share Responses parsing rules between HTTP mappings and client objects. Accept completed assistant message/output_text parts in order and ignore known non-text reasoning. Distinguish empty text from absent text. Explicitly fail malformed, refused, filtered, failed, incomplete, nonterminal, or unsupported output, even alongside partial text. Keep TypeChatLanguageModel, text PromptSection inputs, schema validation, bounded repair, and Failure payload behavior unchanged.
    • Extend existing deterministic Python regression coverage and API documentation with Responses and bounded-fallback cases. Add minimal HTTP and configured-client examples, recommend explicit Responses for new integrations, and retain at least one Chat Completions example. Build on robgruen's merged PR 516; preserve Copilot's merged PR 305 and robgruen's merged PR 519 as TypeScript prior art rather than duplicate work. A future live check is supplementary, not an offline-test dependency.

    Non-goals

    • Do not implement streaming, tool execution, multimodal prompts, agent orchestration, hosting, storage, or a remote conversation-state service. Separate multimodal work is not a prerequisite for text-only Responses support.
    • Do not import provider SDKs into TypeChat, add required SDK or Azure Identity dependencies, manage credential acquisition/caching/renewal, or take ownership of caller-configured clients and their transport controls.
    • Do not infer capabilities from endpoint names or generic failures, rewrite destinations or API versions, send capability probes, silently substitute models, switch back to Responses, or implement general cross-provider failover. Do not broaden fallback to refusals, malformed output, or schema-validation failures.
    • Do not change existing Chat Completions defaults or environment semantics, modify TypeScript, duplicate merged authentication/client work, weaken schema validation, or change repair limits and Failure payload semantics.
    • Do not promise that arbitrary services, proxy deployments, or every Azure API version implement the selected text contract. Accepting complete destinations and covering all existing Python integration contracts is not a universal provider-compatibility guarantee. Do not treat this proposal or prior feedback as accepted work or permission to implement.

    Acceptance criteria

    • All four construction functions expose keyword-only use_responses_api=False and fallback_to_chat_completions=False. Omitting them preserves legacy positional/keyword calls, environment routing and precedence, organization aliases, literal identity values, Chat Completions bodies, and headers. Endpoint spelling never changes mode. Fallback without Responses, missing explicit Responses HTTP destinations, and enabled HTTP fallback without fallback_endpoint fail with explicit configuration errors before dispatch.
    • Offline HTTP and client fixtures show Responses requests using input, a nonempty explicit model/deployment, and non-streaming behavior, without messages, n, or inherited Chat Completions temperature. String prompts and system/user/assistant text sections retain exact content and order without mutation. The Azure factory and environment factory's Azure branch pass the added keyword-only model/deployment value to Responses without changing legacy Azure bodies. Blank required names fail before dispatch; fallback never substitutes a model.
    • An offline matrix covers the environment factory, both HTTP factories, API-key authentication, Azure token providers, and configured clients. Complete OpenAI, Azure, deployment-scoped query-versioned, and opaque proxy destinations retain supplied paths and queries when serving the selected text contract. Explicitly identical Responses and fallback proxy destinations work. No suffix allowlist, URL rewrite, inferred mode, or capability probe occurs. Incompatible services produce explicit errors rather than claimed compatibility; synthetic route fixtures establish pass-through behavior, not live API-version support.
    • Static structural-type fixtures accept a chat-only client in default mode and a Responses-only client in explicit Responses mode, and require both members for fallback. The adapter preserves client identity, settings, and ownership and adds no transport retry/timeout layer. It makes one selected create call, or at most two with one enabled switch, per complete call. SDK-internal retries are not represented as TypeChat-controlled request bounds. Unclassified exceptions and cancellation propagate unchanged.
    • HTTP mapping and configured-client object fixtures for completed Responses envelopes yield the exact concatenation of supported assistant message/output_text parts in order. Known reasoning items add no text. Present empty text is distinct from absent text and remains subject to translator validation. A convenience output_text property alone never bypasses canonical envelope/output checks.
    • Malformed or missing envelope/output/content containers, non-string text, refusal, filtering/blocking, failed/cancelled/incomplete/nonterminal statuses, and unsupported tool output yield explicit Failure results even if text is present. No tool is executed and no fabricated fallback text is returned. New diagnostics and switch warnings do not expose endpoints, prompts, credentials, or raw provider payloads. These output failures never cause an API switch.
    • For every documented unsupported-operation signal backed by public sanitized HTTP and client fixtures, enabled fallback switches exactly once to a correctly formed Chat Completions request, with one sanitized warning; disabled fallback never switches. Bare 400/404, missing models/deployments, ambiguous missing routes, authentication/authorization errors, rate limits, server/network errors, timeouts, cancellation, oversized bodies, and output/validation failures never switch. Unknown errors retain normal failures or exceptions. Each complete call starts in its configured mode, with no switch back or capability cache.
    • Offline translator cases cover HTTP Responses, client Responses, and a successful Chat fallback. Valid schema-conforming JSON succeeds; invalid JSON and schema-invalid JSON follow the existing bounded repair path, preserving assistant/user history order and final Failure values and response text. Model Failure results do not trigger schema repair or another API switch. Schema conversion, validation rules, and the existing one-repair default remain unchanged.
    • With retry limit R, HTTP dispatches per complete call are at most R+1 without a switch or R+2 with one, sharing retries. Defaults remain R=3, a one-second pause, a ten-second request timeout, and a 100 MiB response limit. Limit B accepts B bytes and rejects B+1 for advertised and incremental success and newly inspected error bodies; nonpositive limits stay disabled. Sync, async, and awaitable token providers resolve afresh once per HTTP attempt, including retries and fallback, with changing tokens observed. Invalid tokens prevent dispatch; cancellation and API-key/provider exclusivity remain intact.
    • Python API documentation and minimal HTTP/client examples show explicit Responses selection, model/deployment placement, complete destinations with arbitrary paths/queries, unchanged defaults, and at least one retained Chat Completions example. They document supported fallback triggers, warnings, request bounds, and caller-owned SDK authentication, retries, timeouts, size controls, and lifecycle. Offline regression and type fixtures use existing tooling, imports work without provider SDKs, and no required SDK or Azure Identity dependency is added. Combined image/Responses regression coverage is conditional on separate multimodal support being available.

    Open questions

    • Can you or another contributor provide public, sanitized HTTP and configured-client error fixtures that explicitly identify an unsupported Responses operation before generation, including the status, structured error fields, and client exception attributes? They must distinguish that rejection from a missing model, deployment, or route. Omit credentials, private addresses, and user content; access to a live endpoint is not a substitute for this contract evidence.

    Evidence limits and assumptions

    • Discussion evidence is the complete frozen issue and all four comments, including P1, P2, and both owner feedback messages. No later target-thread comments were fetched. Python model, translator, exports, dependency manifest, README, API documentation, and five targeted test sources were inspected at the trusted revision rather than a moving branch.
    • The frozen conversation contains no public HTTP/client error fixtures proving a safe unsupported-Responses signal. The offered live endpoint was not accessed. Live service behavior, arbitrary proxies, and Azure API-version compatibility were not verified. No external provider documentation, reproduction links, other repositories, or browser actions were accessed.
    • PR 516, PR 305, and PR 519 metadata were inspected, along with PR 305's model patch. The complete current TypeScript model and PR 519 implementation patch were not inspected. PR descriptions' reported validation was not independently verified. Searches found no competing open Python Responses implementation, but cannot establish that no unindexed or future contribution exists.
    • No code, reproductions, tests, installations, or live requests were executed. Existing test sources inform the proposed deterministic cases; the recommended Python Responses and fallback behavior is not an implemented or verified capability. All-contract coverage is the stated interpretation of the latest feedback, not recorded agreement to these detailed terms.

    Related contributions: #516, #305, #519.

    Not eligible for acceptance yet. Discuss the remaining questions and request /typechat propose again.

    Proposal run | Approved scope policy

  10. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    For your question rather than providing an error why don't we use the response schema as expected from the endpoint? We can't really hypothesis about the type of non-conformity we'd get from any given endpoint. What's your take?

  11. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    /typechat reply

  12. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    I agree: the expected response schema is the right starting point. We do not need to predict every endpoint's nonconforming response or collect provider-specific error codes to support Responses. The earlier request for error fixtures matters only if an automatic second request depends on recognizing a particular error; it should not block ordinary Responses request and response handling.

    There are two schemas to keep separate: the service response envelope, which wraps the generated text, and the application's schema for the JSON inside that text. In the inspected Python code, the HTTP model sends messages and reads choices, while the configured-client adapter calls chat.completions.create. Responses needs an input request and extraction from supported output message/text parts, using responses.create for configured clients. The extracted text can then pass through the existing translator's application-schema validation and bounded repair.

    I recommend explicit API selection for opaque proxy addresses, paired request and response handling, and unchanged Chat Completions defaults. We can tolerate extra response fields without guessing at their meaning, while checking the fields and outcome indicators needed for usable text. Missing or malformed required output, refusals, blocking, and incomplete output still need explicit failures, not fabricated completion text. This would extend your merged Python authentication/client work rather than duplicate it, retain the HTTP safeguards and caller-owned client settings, and add Responses examples while keeping a Chat Completions example.

    The remaining distinction is whether fallback means reading another supported response format or making another model request. Recognizing a supported format in the same response does not require resending anything. A schema mismatch alone does not establish that the first request did no work, so I would not use it to trigger an automatic resend. For the configurable fallback you suggested, do you mean accepting either supported response format from the same successful call, or sending another request using Chat Completions?

    Related contributions: #516, #305, #519.

    Automated response requested by the project owner. This does not accept work or authorize implementation.

  13. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    I'm saying, when enabled, we should try the chat endpoint if the responses endpoint fails. I think this is just a stop-gap as we transition away from the older chat endpoint (for backward compatibility). Ideally this should be off, enabled consciously, and then eventually deprecated and then removed from the library. Make sense?

  14. robgruen commented on Nov 4, 2026

    @robgruen
    ContributorAuthor

    /typechat reply

  15. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Yes, that makes sense: an explicitly enabled, temporary compatibility bridge. Try Responses first, then switch to a Chat Completions request if it fails; keep fallback off by default. This is a new request, not reinterpretation of the original response. My earlier unsupported-operation-only restriction was narrower than your intent, and provider-specific error fixtures need not gate the design.

    The inspected Python HTTP model still sends messages and reads choices, and the configured-client adapter calls chat.completions.create. Supporting Responses means adding its input request and text-output parsing, plus responses.create for configured clients, then constructing a real Chat Completions request for fallback. This extends your merged authentication/client work, with merged TypeScript contributions as prior art, while preserving supplied proxy destinations and client settings.

    I recommend covering endpoint errors and missing or malformed service response structure, with at most one observable API switch and shared HTTP retry limits. Refusals, blocking, cancellation, invalid local configuration and response-size-limit failures should remain terminal. Application JSON that fails schema validation should use TypeChat's existing bounded repair, not trigger API fallback. Keep existing Chat Completions defaults and at least one chat example; retiring the temporary fallback needs a separate migration decision.

    A failed request may already have generated output, so another call can duplicate work and cost. I recommend initially excluding timeouts or connection loss after dispatch, where that outcome is especially uncertain. Should deliberately enabling fallback also authorize a Chat Completions attempt in those cases? That is the remaining failure-policy detail, rather than a need to predict every provider's error response.

    Related contributions: #516, #305, #519.

    Automated response requested by the project owner. This does not accept work or authorize implementation.

  16. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    no it should not. it should only fallback to chat if we get a "method not allowed" or whatever it is...we should figure out what the actual error is if you try to post a response to a chat endpoint and use that. Anything else is just a standard error handling

  17. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat reply

  18. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor

    Understood: fallback stays off by default and applies only to a confirmed Responses-versus-Chat API mismatch. Timeouts, connection loss, authentication failures, and malformed output keep their normal handling. I recommend at most one switch, sending a correctly formed Chat Completions request, rather than treating fallback as general recovery.

    I would not assume that signal is HTTP 405, Method Not Allowed: that describes an unsupported HTTP verb, while both APIs use POST. In the inspected Python model, terminal HTTP errors return only a status and reason phrase; the configured-client adapter calls chat.completions.create and propagates exceptions unchanged. Neither currently identifies this mismatch. The TypeScript test using a chat-named address returns a mocked success, so it does not establish a real rejection signal.

    This should extend your merged Python authentication/client integration, drawing on Copilot's TypeScript Responses work and your TypeScript client adapter. New error-body inspection should retain the HTTP size cap. Successful text from either API must still be checked against the application's types and use the existing bounded repair process. Existing Chat Completions defaults and at least one chat example should remain; retiring the temporary fallback later needs a separate compatibility decision.

    The remaining gap is the concrete rejection signal, not another fallback-policy choice. The discussion and inspected sources do not establish that signal, and I have not made a live request. Is there an existing public error example, with private data removed, showing the status and error fields for this mismatch and how the configured client exposes them? That evidence would let the trigger be specified without switching on unrelated errors.

    Related contributions: #516, #305, #519.

    Automated response requested by the project owner. This does not accept work or authorize implementation.

  19. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    We can figure out what the error/response shape is when we test it with a live endpoint during build-out.

  20. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat propose

  21. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor

    Work proposal P4

    Proposal for community discussion, not accepted work or permission to build.

    Recommendation

    Yes. I recommend making discovery of the actual rejection response part of build-out, rather than asking you to supply error fixtures before this proposal can progress. Your latest clarification gives the fallback a concrete boundary: it is off by default and switches only when a Responses request is positively identified as incompatible with a Chat Completions endpoint. Other failures keep their normal handling. We should not assume that HTTP 405, Method Not Allowed, identifies that mismatch; both APIs use POST.

    The inspected Python HTTP model still sends messages and reads choices, while the configured-client adapter calls chat.completions.create. Responses therefore needs its own input request construction, output parsing and responses.create client path, not just another endpoint address. This should extend robgruen's merged Python authentication and client-reuse contribution in PR 516, with Copilot's PR 305 and robgruen's PR 519 providing merged TypeScript prior art rather than duplicate Python implementations.

    I recommend retaining explicit API selection across all four construction functions, preserving complete caller-supplied paths and queries, and requiring an explicit HTTP fallback destination that may intentionally be the same proxy address. That is more predictable than guessing from an address or changing existing defaults. Chat-only clients should remain valid, and configured clients should retain their settings and ownership. New examples should recommend explicit Responses selection while retaining at least one Chat Completions example.

    For a later, separately authorized build and live check, capture the actual mismatch through HTTP and a configured client, remove private details, and turn those observations into precise matching rules and offline regression fixtures. Permit at most one observable switch per completion, using a real Chat Completions request and a shared HTTP retry allowance. Unknown or ambiguous errors must not switch; an inconclusive investigation leaves that completion gate unmet rather than justifying broader fallback. A switch is another model request and can add cost and latency. Successful text from either API must still pass through the existing validation and bounded repair. Document the fallback's temporary purpose without scheduling deprecation or removal in this work.

    Changes since the previous proposal

    • Compared with P3, moved actual HTTP/client mismatch discovery from a pre-proposal request for public fixtures into required work during separately authorized build-out, following the latest owner feedback. Exact error fields remain unverified; the proposal now gates completion on observed matching rules and sanitized regression fixtures instead of requiring those facts in advance.
    • Reconciled the intervening broad-failure suggestion with the owner's later restriction: fallback applies only to a positively identified Responses-request-to-Chat-endpoint mismatch. Timeouts, connection loss, malformed output and other errors retain normal handling. The proposal does not assume HTTP 405 is the signal, promise a rejection is non-billable, or broaden fallback when discovery is inconclusive.
    • Added an explicit inconclusive-investigation outcome and contrasting-error checks so build-time discovery cannot become generic failover or a silently ineffective fallback. I now recommend these concrete terms for an owner decision without another clarification question; readiness is a recommendation, not recorded agreement, acceptance or build authorization. P3's explicit selection, opaque destinations, compatibility safeguards and contributor credit are retained.

    Direction and readiness

    The approved frozen policy supports G1 for type-defined interfaces, G2 for explicit failures and validated output, G3 for compatible Python APIs, G4 for optional integrations without required provider SDKs, and G5 for documentation and deterministic tests. Extending an existing optional provider integration does not bind the core to a vendor under N3. Excluding orchestration respects N1; preserving validation respects N4. Under N5, this recommendation and the preceding proposals do not establish acceptance or authorization to implement.

    The latest owner feedback settles the fallback boundary and explicitly places error-shape discovery during build-out. I recommend concrete terms with that investigation as a testable completion gate, rather than another request for advance fixtures. Exact error fields remain unverified implementation evidence, not an unanswered direction choice. If observations cannot distinguish the API mismatch, the fallback criterion remains unmet and returns to discussion; triggers cannot be broadened silently. This is a recommendation for an owner decision, not acceptance, permission to run live checks, or authorization to build.

    Goal

    Let Python applications explicitly select non-streaming Responses text completions through existing HTTP factories or a configured asynchronous client, including opaque proxy destinations, with an opt-in, evidence-backed Chat Completions compatibility fallback and unchanged legacy defaults, validation, repair and client ownership.

    Scope

    • Add keyword-only use_responses_api=False and fallback_to_chat_completions=False across the dictionary/environment factory, both HTTP factories and configured-client adapter. Reject fallback unless Responses is selected. Keep existing positional arguments, defaults, environment behavior and Chat Completions requests unchanged. Do not infer the selected API from endpoint names.
    • Require complete supplied Responses HTTP destinations and fallback_endpoint when HTTP fallback is enabled. Preserve paths and queries, including opaque proxies and deployment-scoped routes; callers may explicitly use one destination for both APIs. Interpret all-contract coverage as existing Python construction, authentication and client paths serving the documented text contract, not universal provider/version support.
    • Construct minimal Responses requests using input, an explicit model/deployment and non-streaming behavior, without messages, n or inherited temperature. Add keyword-only model/deployment pass-through for Azure, including the dictionary factory's Azure branch, without changing legacy Azure bodies. Preserve text-role content/order. Assume both fallback destinations accept the same selected model/deployment and authentication; never substitute either silently.
    • Export a separate ResponsesClient structural protocol, meaning the required asynchronous client members without importing an SDK. Preserve ChatCompletionClient. Require both client API members only for enabled fallback. Reuse caller configuration and ownership without added transport retries/timeouts or client cleanup. Propagate cancellation and all exceptions except a positively classified opt-in mismatch unchanged.
    • Make actual mismatch discovery and regression-fixture capture part of later, separately authorized build-out and live checks, not a prerequisite for discussing these terms. Establish precise HTTP and client classification rules from observed Responses-request-to-Chat-endpoint rejection, with contrasting unrelated errors. Publish only sanitized fixtures. If a distinct signal cannot be established, the fallback completion criterion remains unmet and must return to discussion.
    • Allow one request-local Responses-to-Chat switch only when explicitly enabled and the observed, documented mismatch rule matches. Send a correctly formed Chat Completions request, emit one fixed warning without request details and share the HTTP retry allowance across both APIs, allowing one additional dispatch for the switch. Unknown failures use normal handling. Do not cache capability or permanently change mode. Explain that fallback is a new request with possible extra cost and latency.
    • Share Responses parsing rules between HTTP mappings and client objects. Accept ordered completed assistant text, tolerate unrelated extra fields and ignore known reasoning items. Explicitly reject missing, malformed, refused, blocked, failed, incomplete, nonterminal or unsupported output, even with partial text. Keep TypeChatLanguageModel, text PromptSection inputs, schema validation, bounded repair and Failure payload semantics unchanged.
    • Reuse HttpxLanguageModel transport, lifecycle, authentication, per-attempt token providers, retry limits, timeout and response-size safeguards. Read any new error payloads used for mismatch classification through the capped reader. Keep credential acquisition, caching and renewal caller-owned; configured clients retain their own transport controls and internal retry policies.
    • Extend existing deterministic Python regression coverage, API documentation and minimal HTTP/client examples; recommend explicit Responses for new integrations and retain at least one Chat Completions example. Build on robgruen's merged PR 516 and preserve credit for Copilot's merged PR 305 and robgruen's merged PR 519 as TypeScript prior art, not Python implementations or dependencies. Document the fallback's temporary compatibility purpose and later retirement intent.

    Non-goals

    • Do not implement streaming, tool execution, multimodal prompts, agent orchestration, hosting, storage or remote conversation-state management. Combined image/Responses regression coverage is conditional on the separate image capability being available.
    • Do not add required provider SDK or Azure Identity dependencies, manage credential acquisition/caching/renewal, or take ownership of caller-configured clients and their transport controls.
    • Do not change existing Chat Completions defaults, deprecate either existing API path, or schedule fallback removal in this work. Deprecation and removal require a separate compatibility and migration decision.
    • Do not guess capabilities from addresses or generic failures, rewrite destinations or API versions, send capability probes, silently substitute models/authentication, or implement general cross-provider failover. Do not promise every proxy, provider or Azure API version implements Responses.
    • Do not modify TypeScript, duplicate merged authentication/client work, weaken schema validation, change repair limits or Failure payload behavior, or treat discovery of an ambiguous error as permission to broaden fallback.

    Acceptance criteria

    • Offline factory cases show keyword-only use_responses_api=False and fallback_to_chat_completions=False on create_language_model, create_openai_language_model, create_azure_openai_language_model and create_openai_language_model_from_client. Omitting them preserves positional calls, environment precedence and organization aliases, literal identity values, Chat Completions bodies and headers. Fallback without Responses fails before dispatch.
    • Responses HTTP mode requires a complete supplied destination; enabled HTTP fallback also requires fallback_endpoint, permitting an explicitly shared proxy destination. OpenAI-compatible, Azure, deployment-scoped/query-versioned and opaque-route fixtures preserve paths and queries without inference, rewriting or probes. Responses sends input, stream=False and a nonblank model/deployment, not messages, n or inherited temperature. Keyword-only Azure and dictionary-factory model pass-through leaves legacy Azure bodies unchanged. Text-role content and order are preserved without mutation; missing required configuration fails before dispatch.
    • Structural type fixtures accept the unchanged chat-only ChatCompletionClient in default mode and a Responses-only ResponsesClient in explicit mode; only fallback requires both members. Missing required members fail before dispatch. The adapter uses the supplied instance and model/deployment, never reconfigures or closes it, adds no transport retry/timeout layer and requires no TypeChat environment variables. Unclassified client exceptions and cancellation propagate unchanged; SDK-internal retries remain caller-owned.
    • HTTP mappings and configured-client objects follow the same Responses parsing rules. Completed assistant message/output_text parts concatenate in output order; known reasoning adds no text, present empty text differs from absent text, and unrelated extra fields are tolerated. Missing or malformed required containers, non-string text, refusal/blocking, failed/incomplete/cancelled/nonterminal status and unsupported tool output yield explicit Failure even alongside text. A convenience output_text property cannot bypass canonical envelope checks. No output failure triggers fallback or fabricated completion text.
    • After separate build authorization and permission for a live check, reproduce the Responses-request-to-Chat-endpoint mismatch through HTTP and a configured client on the owner-provided endpoint. Capture the observed status, structured error fields and client exception attributes as public-safe fixtures, with contract/version coverage and contrasting missing-route/model/deployment cases. Document exact matching rules; HTTP 405 or another bare status is not proof by itself. No fallback trigger is released without distinguishing evidence. Inconclusive evidence leaves this criterion unmet and returns the issue to discussion rather than broadening fallback.
    • Each captured, documented mismatch fixture causes exactly one Responses-to-Chat switch when enabled and none when disabled. The second call uses a Chat Completions body and explicit fallback destination or chat.completions.create, preserving the selected model/deployment and authentication. One fixed warning contains only API/reason labels. There is no switch back, capability cache or persistent mode change; each complete call starts in its configured mode. Client adapters make at most two create calls per completion, excluding SDK-hidden retries. A failed fallback remains a normal failure or exception.
    • Negative fixtures cause no API switch for unclassified or malformed errors, bare status codes, missing routes/models/deployments, authentication/authorization errors, rate limits, server errors, timeouts, connection loss, cancellation, invalid local configuration, oversized responses, refusals/blocking, malformed service output or application JSON/schema errors. Existing same-API retries still apply where they already did. New diagnostics and switch warnings omit credentials, prompts, addresses and raw provider payloads.
    • HTTP cases preserve defaults of three retries, a one-second pause, a ten-second timeout and a 100 MiB response limit, plus configured values. With retry limit R, each complete call has at most R+1 dispatches without a switch or R+2 with one, sharing retries across APIs. Success and inspected error bodies use the capped reader: limit B accepts B bytes and rejects B+1 for advertised and incremental bodies; nonpositive limits stay disabled. Sync, async and awaitable token providers resolve afresh per attempt, including retries and fallback. Invalid tokens prevent dispatch; authentication exclusivity and cancellation behavior remain intact.
    • Offline HTTP Responses, client Responses and successful fallback cases pass valid application JSON through the existing validator. Malformed JSON and schema-invalid JSON use bounded repair with the one-repair default, assistant/user history order and final Failure values/response_text preserved. Final model Failure results terminate translation without another repair or API switch. Schema errors never classify an endpoint mismatch; a later repair completion starts in the configured mode with the same per-completion switch limit.
    • Python API documentation and minimal HTTP/client Responses examples explain explicit selection, supported text contracts, model/deployment placement, opaque destinations, unchanged defaults, verified fallback triggers, warnings, extra-request cost/latency and request bounds. At least one Chat Completions example remains. Document caller-owned SDK controls/lifecycle and the fallback's temporary purpose without a removal date. TypeChat imports and deterministic offline regression/type fixtures need no provider SDK or Azure Identity dependency. Combined image/Responses cases are added only when separate image support exists.

    Evidence limits and assumptions

    • Discussion evidence is the complete frozen issue and provided conversation, including P1, P2, P3 and intervening feedback through the latest build-out clarification. No later target-thread comments were fetched or incorporated.
    • Python model, translator, exports, dependency manifest, README, Python API documentation and five targeted test sources were inspected at the trusted revision. No code, reproductions, tests, installations, browser actions or live requests were executed. The proposed Python Responses and fallback behavior is not implemented or independently verified by this review.
    • No external provider documentation, reproduction links, other repositories or live endpoints were accessed. Actual mismatch status/error fields, configured-client exception attributes and real provider/API-version compatibility remain unverified. Their discovery and public-safe regression evidence are proposed completion work, not established facts or permission to access an endpoint now.
    • PR 516, PR 305 and PR 519 metadata and PR 305's model patch were inspected. The complete current TypeScript model and PR 519 implementation patch were not inspected, and contributors' reported validation was not independently verified. An open Responses PR search returned no matches; unindexed or future contributions cannot be ruled out.

    Related contributions: #516, #305, #519.

    The owner may accept these exact terms with /typechat accept P4. Acceptance does not start a build.

    Proposal run | Approved scope policy

  22. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat accept P4

  23. github-actions commented on Nov 5, 2026

    @github-actions
    Contributor

    Accepted work

    Approved by the project owner, robgruen, for issue #518. Proposal P4.

    Goal

    Let Python applications explicitly select non-streaming Responses text completions through existing HTTP factories or a configured asynchronous client, including opaque proxy destinations, with an opt-in, evidence-backed Chat Completions compatibility fallback and unchanged legacy defaults, validation, repair and client ownership.

    Scope

    • Add keyword-only use_responses_api=False and fallback_to_chat_completions=False across the dictionary/environment factory, both HTTP factories and configured-client adapter. Reject fallback unless Responses is selected. Keep existing positional arguments, defaults, environment behavior and Chat Completions requests unchanged. Do not infer the selected API from endpoint names.
    • Require complete supplied Responses HTTP destinations and fallback_endpoint when HTTP fallback is enabled. Preserve paths and queries, including opaque proxies and deployment-scoped routes; callers may explicitly use one destination for both APIs. Interpret all-contract coverage as existing Python construction, authentication and client paths serving the documented text contract, not universal provider/version support.
    • Construct minimal Responses requests using input, an explicit model/deployment and non-streaming behavior, without messages, n or inherited temperature. Add keyword-only model/deployment pass-through for Azure, including the dictionary factory's Azure branch, without changing legacy Azure bodies. Preserve text-role content/order. Assume both fallback destinations accept the same selected model/deployment and authentication; never substitute either silently.
    • Export a separate ResponsesClient structural protocol, meaning the required asynchronous client members without importing an SDK. Preserve ChatCompletionClient. Require both client API members only for enabled fallback. Reuse caller configuration and ownership without added transport retries/timeouts or client cleanup. Propagate cancellation and all exceptions except a positively classified opt-in mismatch unchanged.
    • Make actual mismatch discovery and regression-fixture capture part of later, separately authorized build-out and live checks, not a prerequisite for discussing these terms. Establish precise HTTP and client classification rules from observed Responses-request-to-Chat-endpoint rejection, with contrasting unrelated errors. Publish only sanitized fixtures. If a distinct signal cannot be established, the fallback completion criterion remains unmet and must return to discussion.
    • Allow one request-local Responses-to-Chat switch only when explicitly enabled and the observed, documented mismatch rule matches. Send a correctly formed Chat Completions request, emit one fixed warning without request details and share the HTTP retry allowance across both APIs, allowing one additional dispatch for the switch. Unknown failures use normal handling. Do not cache capability or permanently change mode. Explain that fallback is a new request with possible extra cost and latency.
    • Share Responses parsing rules between HTTP mappings and client objects. Accept ordered completed assistant text, tolerate unrelated extra fields and ignore known reasoning items. Explicitly reject missing, malformed, refused, blocked, failed, incomplete, nonterminal or unsupported output, even with partial text. Keep TypeChatLanguageModel, text PromptSection inputs, schema validation, bounded repair and Failure payload semantics unchanged.
    • Reuse HttpxLanguageModel transport, lifecycle, authentication, per-attempt token providers, retry limits, timeout and response-size safeguards. Read any new error payloads used for mismatch classification through the capped reader. Keep credential acquisition, caching and renewal caller-owned; configured clients retain their own transport controls and internal retry policies.
    • Extend existing deterministic Python regression coverage, API documentation and minimal HTTP/client examples; recommend explicit Responses for new integrations and retain at least one Chat Completions example. Build on robgruen's merged PR 516 and preserve credit for Copilot's merged PR 305 and robgruen's merged PR 519 as TypeScript prior art, not Python implementations or dependencies. Document the fallback's temporary compatibility purpose and later retirement intent.

    Non-goals

    • Do not implement streaming, tool execution, multimodal prompts, agent orchestration, hosting, storage or remote conversation-state management. Combined image/Responses regression coverage is conditional on the separate image capability being available.
    • Do not add required provider SDK or Azure Identity dependencies, manage credential acquisition/caching/renewal, or take ownership of caller-configured clients and their transport controls.
    • Do not change existing Chat Completions defaults, deprecate either existing API path, or schedule fallback removal in this work. Deprecation and removal require a separate compatibility and migration decision.
    • Do not guess capabilities from addresses or generic failures, rewrite destinations or API versions, send capability probes, silently substitute models/authentication, or implement general cross-provider failover. Do not promise every proxy, provider or Azure API version implements Responses.
    • Do not modify TypeScript, duplicate merged authentication/client work, weaken schema validation, change repair limits or Failure payload behavior, or treat discovery of an ambiguous error as permission to broaden fallback.

    Acceptance criteria

    • Offline factory cases show keyword-only use_responses_api=False and fallback_to_chat_completions=False on create_language_model, create_openai_language_model, create_azure_openai_language_model and create_openai_language_model_from_client. Omitting them preserves positional calls, environment precedence and organization aliases, literal identity values, Chat Completions bodies and headers. Fallback without Responses fails before dispatch.
    • Responses HTTP mode requires a complete supplied destination; enabled HTTP fallback also requires fallback_endpoint, permitting an explicitly shared proxy destination. OpenAI-compatible, Azure, deployment-scoped/query-versioned and opaque-route fixtures preserve paths and queries without inference, rewriting or probes. Responses sends input, stream=False and a nonblank model/deployment, not messages, n or inherited temperature. Keyword-only Azure and dictionary-factory model pass-through leaves legacy Azure bodies unchanged. Text-role content and order are preserved without mutation; missing required configuration fails before dispatch.
    • Structural type fixtures accept the unchanged chat-only ChatCompletionClient in default mode and a Responses-only ResponsesClient in explicit mode; only fallback requires both members. Missing required members fail before dispatch. The adapter uses the supplied instance and model/deployment, never reconfigures or closes it, adds no transport retry/timeout layer and requires no TypeChat environment variables. Unclassified client exceptions and cancellation propagate unchanged; SDK-internal retries remain caller-owned.
    • HTTP mappings and configured-client objects follow the same Responses parsing rules. Completed assistant message/output_text parts concatenate in output order; known reasoning adds no text, present empty text differs from absent text, and unrelated extra fields are tolerated. Missing or malformed required containers, non-string text, refusal/blocking, failed/incomplete/cancelled/nonterminal status and unsupported tool output yield explicit Failure even alongside text. A convenience output_text property cannot bypass canonical envelope checks. No output failure triggers fallback or fabricated completion text.
    • After separate build authorization and permission for a live check, reproduce the Responses-request-to-Chat-endpoint mismatch through HTTP and a configured client on the owner-provided endpoint. Capture the observed status, structured error fields and client exception attributes as public-safe fixtures, with contract/version coverage and contrasting missing-route/model/deployment cases. Document exact matching rules; HTTP 405 or another bare status is not proof by itself. No fallback trigger is released without distinguishing evidence. Inconclusive evidence leaves this criterion unmet and returns the issue to discussion rather than broadening fallback.
    • Each captured, documented mismatch fixture causes exactly one Responses-to-Chat switch when enabled and none when disabled. The second call uses a Chat Completions body and explicit fallback destination or chat.completions.create, preserving the selected model/deployment and authentication. One fixed warning contains only API/reason labels. There is no switch back, capability cache or persistent mode change; each complete call starts in its configured mode. Client adapters make at most two create calls per completion, excluding SDK-hidden retries. A failed fallback remains a normal failure or exception.
    • Negative fixtures cause no API switch for unclassified or malformed errors, bare status codes, missing routes/models/deployments, authentication/authorization errors, rate limits, server errors, timeouts, connection loss, cancellation, invalid local configuration, oversized responses, refusals/blocking, malformed service output or application JSON/schema errors. Existing same-API retries still apply where they already did. New diagnostics and switch warnings omit credentials, prompts, addresses and raw provider payloads.
    • HTTP cases preserve defaults of three retries, a one-second pause, a ten-second timeout and a 100 MiB response limit, plus configured values. With retry limit R, each complete call has at most R+1 dispatches without a switch or R+2 with one, sharing retries across APIs. Success and inspected error bodies use the capped reader: limit B accepts B bytes and rejects B+1 for advertised and incremental bodies; nonpositive limits stay disabled. Sync, async and awaitable token providers resolve afresh per attempt, including retries and fallback. Invalid tokens prevent dispatch; authentication exclusivity and cancellation behavior remain intact.
    • Offline HTTP Responses, client Responses and successful fallback cases pass valid application JSON through the existing validator. Malformed JSON and schema-invalid JSON use bounded repair with the one-repair default, assistant/user history order and final Failure values/response_text preserved. Final model Failure results terminate translation without another repair or API switch. Schema errors never classify an endpoint mismatch; a later repair completion starts in the configured mode with the same per-completion switch limit.
    • Python API documentation and minimal HTTP/client Responses examples explain explicit selection, supported text contracts, model/deployment placement, opaque destinations, unchanged defaults, verified fallback triggers, warnings, extra-request cost/latency and request bounds. At least one Chat Completions example remains. Document caller-owned SDK controls/lifecycle and the fallback's temporary purpose without a removal date. TypeChat imports and deterministic offline regression/type fixtures need no provider SDK or Azure Identity dependency. Combined image/Responses cases are added only when separate image support exists.

    Existing contributions

    Proposal run | Approved scope policy

    This accepts the scope above. It does not start or authorize an automated implementation run, increase any budget, or approve merging. Material scope changes require a new proposal and owner decision.
    After separate owner authorization and pilot activation, use /typechat build P4.

  24. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat build P4

  25. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat build P4

  26. robgruen commented on Nov 5, 2026

    @robgruen
    ContributorAuthor

    /typechat build P4

  27. robgruen commented on Nov 10, 2026

    @robgruen
    ContributorAuthor

    Done in #523

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Language: PythonPertains to the Python implementation of TypeChat.SuggestionNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions