feat: enhance response serialization for compact mode

- Added support for preserving native response.compaction payloads when compact serialization is requested in `serializeResponsesFinalPayload`.
- Implemented serialization of compact mode as `response.compaction` instead of an ordinary response object.
- Introduced a new type `ResponsesFinalSerializationMode` to manage serialization modes.
- Refactored `serializeResponsesFinalPayload` to handle different serialization modes and usage payloads.
- Added tests to ensure correct behavior for compact serialization and preservation of upstream payloads.
- Updated favicon assets and documentation configuration for VitePress.
This commit is contained in:
cita
2026-03-10 01:28:34 +08:00
parent 74d2e559ec
commit cd031b732f
20 changed files with 1387 additions and 90 deletions
@@ -114,6 +114,7 @@ describe('proxy route architecture boundaries', () => {
expect(source).not.toContain('const consumeSseBuffer = (incoming: string): string => {');
expect(source).not.toContain('openAiResponsesTransformer.aggregator.complete(');
expect(source).not.toContain('reply.raw.end();');
expect(source).toContain('reply.hijack();');
expect(source).toContain('openAiResponsesTransformer.proxyStream.createSession(');
});
});
@@ -137,4 +137,49 @@ describe('responses proxy compact upstream routing', () => {
const [targetUrl] = fetchMock.mock.calls[0] as [string, any];
expect(targetUrl).toContain('/v1/responses/compact');
});
it('preserves native response.compaction payloads instead of coercing them into object=response', async () => {
fetchMock.mockResolvedValue(new Response(JSON.stringify({
id: 'cmp_123',
object: 'response.compaction',
input_tokens: 1234,
output_tokens: 321,
total_tokens: 1555,
output: [
{
id: 'rs_123',
type: 'compaction',
encrypted_content: 'enc-compact-payload',
},
],
}), {
status: 200,
headers: { 'content-type': 'application/json' },
}));
const response = await app.inject({
method: 'POST',
url: '/v1/responses/compact',
payload: {
model: 'gpt-5.2',
input: 'hello',
},
});
expect(response.statusCode).toBe(200);
expect(response.json()).toEqual({
id: 'cmp_123',
object: 'response.compaction',
input_tokens: 1234,
output_tokens: 321,
total_tokens: 1555,
output: [
{
id: 'rs_123',
type: 'compaction',
encrypted_content: 'enc-compact-payload',
},
],
});
});
});
@@ -29,4 +29,24 @@ describe('responses proxy compact route', () => {
},
});
});
it('rejects streaming /v1/responses/compact requests because compact is non-streaming', async () => {
const response = await app.inject({
method: 'POST',
url: '/v1/responses/compact',
payload: {
model: 'gpt-5.2',
input: 'hello',
stream: true,
},
});
expect(response.statusCode).toBe(400);
expect(response.json()).toEqual({
error: {
message: 'stream is not supported on /v1/responses/compact',
type: 'invalid_request_error',
},
});
});
});