mirror of
https://github.com/microsoft/vscode.git
synced 2026-10-10 12:42:25 +01:00
byok: default statefulResponses to true for custom Responses endpoints
The Open Responses spec requires servers to honor previous_response_id or fail with previous_response_not_found, which the existing full-history retry already handles. Chain by default and let stateless servers that silently ignore the ID (e.g. DeepSeek) opt out with statefulResponses: false. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
4 files changed
+18
-17
No files matched your search
@@ -2158,8 +2158,8 @@
|
||||
},
|
||||
"statefulResponses": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "Whether the Responses API server retains prior responses. When `true`, requests chain via `previous_response_id` and send only new history; leave `false` for stateless servers (for example DeepSeek), which require the full history on every request. Ignored when `zeroDataRetentionEnabled` is `true`."
|
||||
"default": true,
|
||||
"markdownDescription": "Whether the Responses API server retains prior responses. When `true`, requests chain via `previous_response_id` and send only new history. Set to `false` for stateless servers that ignore `previous_response_id` (for example DeepSeek), so the full history is sent on every request. Ignored when `zeroDataRetentionEnabled` is `true`."
|
||||
},
|
||||
"supportsReasoningEffort": {
|
||||
"type": "array",
|
||||
|
||||
@@ -208,8 +208,8 @@ export class CustomEndpointBYOKModelProvider extends AbstractOpenAICompatibleLMP
|
||||
* conflicting credentials.
|
||||
* 4. Omits the Responses API `store` property when Zero Data Retention was not
|
||||
* explicitly configured, allowing custom implementations to use their own default.
|
||||
* 5. Sends full Responses history instead of chaining via `previous_response_id`
|
||||
* unless the user declares the server stateful with `statefulResponses: true`.
|
||||
* 5. Chains Responses requests via `previous_response_id` per the Open Responses spec,
|
||||
* unless the user marks the server stateless with `statefulResponses: false`.
|
||||
*/
|
||||
export class CustomEndpointOAIEndpoint extends OpenAIEndpoint {
|
||||
/**
|
||||
@@ -261,11 +261,11 @@ export class CustomEndpointOAIEndpoint extends OpenAIEndpoint {
|
||||
}
|
||||
|
||||
/**
|
||||
* Many OpenAI-compatible Responses implementations (e.g. DeepSeek) are stateless and
|
||||
* ignore `previous_response_id`, so only chain when the user opts in via `statefulResponses`.
|
||||
* Spec-compliant Responses servers honor `previous_response_id`, but some (e.g. DeepSeek)
|
||||
* silently ignore it, so users can opt out with `statefulResponses: false`.
|
||||
*/
|
||||
protected override get supportsStatefulResponses(): boolean {
|
||||
return this.modelMetadata.statefulResponses === true;
|
||||
return this.modelMetadata.statefulResponses !== false;
|
||||
}
|
||||
|
||||
override createRequestBody(options: ICreateEndpointBodyOptions): IEndpointBody {
|
||||
|
||||
+8
-8
@@ -236,7 +236,7 @@ describe('CustomEndpointBYOKModelProvider', () => {
|
||||
};
|
||||
}
|
||||
|
||||
it('omits store and previous_response_id after cloning a Custom Endpoint Responses endpoint when zeroDataRetentionEnabled is omitted', async () => {
|
||||
it('omits store but keeps previous_response_id after cloning a Custom Endpoint Responses endpoint when both flags are omitted', async () => {
|
||||
const endpoint = (await createConfiguredResponsesEndpoint()).cloneWithTokenOverride(64000);
|
||||
const body = createResponsesBody(endpoint);
|
||||
|
||||
@@ -247,12 +247,12 @@ describe('CustomEndpointBYOKModelProvider', () => {
|
||||
}).toEqual({
|
||||
storePresent: false,
|
||||
store: undefined,
|
||||
previousResponseId: undefined,
|
||||
previousResponseId: customResponsesMarker,
|
||||
});
|
||||
});
|
||||
|
||||
it('issue #331636: sends the full tool-call history to stateless Custom Endpoint Responses servers', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint();
|
||||
it('issue #331636: sends the full tool-call history when statefulResponses is false', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint(undefined, false);
|
||||
const body = endpoint.createRequestBody({
|
||||
debugName: 'test',
|
||||
messages: [
|
||||
@@ -280,8 +280,8 @@ describe('CustomEndpointBYOKModelProvider', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('enables store but not previous_response_id when zeroDataRetentionEnabled is false without statefulResponses', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint(false);
|
||||
it('enables store but not previous_response_id when zeroDataRetentionEnabled and statefulResponses are false', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint(false, false);
|
||||
const body = createResponsesBody(endpoint);
|
||||
|
||||
expect({
|
||||
@@ -295,8 +295,8 @@ describe('CustomEndpointBYOKModelProvider', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('chains via previous_response_id when statefulResponses is true', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint(false, true);
|
||||
it('enables store and previous_response_id when zeroDataRetentionEnabled is false and statefulResponses is omitted', async () => {
|
||||
const endpoint = await createConfiguredResponsesEndpoint(false);
|
||||
const body = createResponsesBody(endpoint);
|
||||
|
||||
expect({
|
||||
|
||||
@@ -156,8 +156,9 @@ export type IChatModelInformation = IModelAPIResponse & {
|
||||
modelOptions?: Readonly<IChatModelRequestOptions>;
|
||||
zeroDataRetentionEnabled?: boolean;
|
||||
/**
|
||||
* BYOK Custom Endpoint opt-in declaring that the Responses API server retains prior
|
||||
* responses, so requests may chain via `previous_response_id` and send only post-marker history.
|
||||
* BYOK Custom Endpoint setting declaring whether the Responses API server retains prior
|
||||
* responses, so requests may chain via `previous_response_id` and send only post-marker
|
||||
* history. Unset is treated as `true`; set `false` for stateless servers.
|
||||
*/
|
||||
statefulResponses?: boolean;
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user