Repository navigation
Closed
Labels
Language: PythonPertains to the Python implementation of TypeChat.Pertains to the Python implementation of TypeChat.SuggestionNew feature or requestNew feature or request
Description
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
inputand 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.createAPI. 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
- [Python] Support using keyless auth for Azure OpenAI #216 and Add dependency-free Python token providers and client adapters #516 establish authentication/client reuse but currently leave Python on Chat Completions.
- TypeScript already supports an explicit/inferred Responses mode and provides useful prior art for preserving validated structured output.
Metadata
Metadata
Assignees
Labels
Language: PythonPertains to the Python implementation of TypeChat.Pertains to the Python implementation of TypeChat.SuggestionNew feature or requestNew feature or request
Activity
robgruen commentedon Nov 4, 2026
/typechat propose
github-actions commentedon Nov 4, 2026
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
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
Non-goals
Acceptance criteria
Open questions
Evidence limits and assumptions
Related contributions: #516, #305, #519.
Not eligible for acceptance yet. Discuss the remaining questions and request
/typechat proposeagain.Proposal run | Approved scope policy
robgruen commentedon Nov 4, 2026
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).
robgruen commentedon Nov 4, 2026
/typechat propose
github-actions commentedon Nov 4, 2026
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
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
Non-goals
Acceptance criteria
Open questions
Evidence limits and assumptions
Related contributions: #516, #305, #519.
Not eligible for acceptance yet. Discuss the remaining questions and request
/typechat proposeagain.Proposal run | Approved scope policy
robgruen commentedon Nov 4, 2026
robgruen commentedon Nov 4, 2026
/typechat propose
github-actions commentedon Nov 4, 2026
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
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
Non-goals
Acceptance criteria
Open questions
Evidence limits and assumptions
Related contributions: #516, #305, #519.
Not eligible for acceptance yet. Discuss the remaining questions and request
/typechat proposeagain.Proposal run | Approved scope policy
robgruen commentedon Nov 4, 2026
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?
robgruen commentedon Nov 4, 2026
/typechat reply
github-actions commentedon Nov 4, 2026
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.
robgruen commentedon Nov 4, 2026
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?
robgruen commentedon Nov 4, 2026
/typechat reply
github-actions commentedon Nov 4, 2026
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.
robgruen commentedon Nov 5, 2026
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
robgruen commentedon Nov 5, 2026
/typechat reply
github-actions commentedon Nov 5, 2026
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.
robgruen commentedon Nov 5, 2026
We can figure out what the error/response shape is when we test it with a live endpoint during build-out.
robgruen commentedon Nov 5, 2026
/typechat propose
github-actions commentedon Nov 5, 2026
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
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
Non-goals
Acceptance criteria
Evidence limits and assumptions
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
robgruen commentedon Nov 5, 2026
/typechat accept P4
github-actions commentedon Nov 5, 2026
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
Non-goals
Acceptance criteria
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.robgruen commentedon Nov 5, 2026
/typechat build P4
robgruen commentedon Nov 5, 2026
/typechat build P4
robgruen commentedon Nov 5, 2026
/typechat build P4
robgruen commentedon Nov 10, 2026
Done in #523