mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-07 16:18:29 +08:00
Merge pull request #5307 from lenzhang/fix/ws-prewarm-continuation
fix(ws): allow Codex prewarm continuation
This commit is contained in:
@@ -551,13 +551,22 @@ func TestNormalizeOpenAIWSPayloadWithoutInputAndPreviousResponseID(t *testing.T)
|
||||
t.Parallel()
|
||||
|
||||
normalized, err := normalizeOpenAIWSPayloadWithoutInputAndPreviousResponseID(
|
||||
[]byte(`{"model":"gpt-5.1","input":[1],"previous_response_id":"resp_x","metadata":{"b":2,"a":1}}`),
|
||||
[]byte(`{"model":"gpt-5.1","input":[1],"previous_response_id":"resp_x","client_metadata":{"request_start_ms":"1"},"stream_options":{"include_usage":true},"generate":false,"metadata":{"b":2,"a":1}}`),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.False(t, gjson.GetBytes(normalized, "input").Exists())
|
||||
require.False(t, gjson.GetBytes(normalized, "previous_response_id").Exists())
|
||||
require.False(t, gjson.GetBytes(normalized, "client_metadata").Exists())
|
||||
require.False(t, gjson.GetBytes(normalized, "stream_options").Exists())
|
||||
require.False(t, gjson.GetBytes(normalized, "generate").Exists())
|
||||
require.Equal(t, float64(1), gjson.GetBytes(normalized, "metadata.a").Float())
|
||||
|
||||
normalized, err = normalizeOpenAIWSPayloadWithoutInputAndPreviousResponseID(
|
||||
[]byte(`{"model":"gpt-5.1","generate":true}`),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.True(t, gjson.GetBytes(normalized, "generate").Bool())
|
||||
|
||||
_, err = normalizeOpenAIWSPayloadWithoutInputAndPreviousResponseID(nil)
|
||||
require.Error(t, err)
|
||||
|
||||
@@ -662,6 +671,36 @@ func TestShouldKeepIngressPreviousResponseID(t *testing.T) {
|
||||
require.Equal(t, "strict_incremental_ok", reason)
|
||||
})
|
||||
|
||||
t.Run("codex_prewarm_to_business_keep", func(t *testing.T) {
|
||||
prewarmPayload := []byte(`{
|
||||
"type":"response.create",
|
||||
"model":"gpt-5.1",
|
||||
"store":false,
|
||||
"generate":false,
|
||||
"client_metadata":{"x-codex-ws-stream-request-start-ms":"100"},
|
||||
"stream_options":{"include_usage":true},
|
||||
"input":[{"type":"input_text","text":"hello"}]
|
||||
}`)
|
||||
businessPayload := []byte(`{
|
||||
"type":"response.create",
|
||||
"model":"gpt-5.1",
|
||||
"store":false,
|
||||
"client_metadata":{"x-codex-ws-stream-request-start-ms":"200"},
|
||||
"previous_response_id":"resp_prewarm",
|
||||
"input":[{"type":"input_text","text":"hello"}]
|
||||
}`)
|
||||
|
||||
keep, reason, err := shouldKeepIngressPreviousResponseID(
|
||||
prewarmPayload,
|
||||
businessPayload,
|
||||
"resp_prewarm",
|
||||
false,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.True(t, keep)
|
||||
require.Equal(t, "strict_incremental_ok", reason)
|
||||
})
|
||||
|
||||
t.Run("missing_previous_response_id", func(t *testing.T) {
|
||||
payload := []byte(`{"type":"response.create","model":"gpt-5.1","input":[]}`)
|
||||
keep, reason, err := shouldKeepIngressPreviousResponseID(previousPayload, payload, "resp_turn_1", false)
|
||||
|
||||
@@ -449,6 +449,17 @@ func normalizeOpenAIWSPayloadWithoutInputAndPreviousResponseID(payload []byte) (
|
||||
}
|
||||
delete(decoded, "input")
|
||||
delete(decoded, "previous_response_id")
|
||||
// Codex changes transport-only metadata for every response.create. These fields
|
||||
// do not alter the context referenced by previous_response_id and are excluded
|
||||
// from Codex's own websocket reuse comparison.
|
||||
delete(decoded, "client_metadata")
|
||||
delete(decoded, "stream_options")
|
||||
// Official Codex prewarms a connection with generate=false, then omits the
|
||||
// field on the business request that continues from the prewarm response.
|
||||
// Only normalize false so a meaningful generate=true change remains visible.
|
||||
if generate, ok := decoded["generate"].(bool); ok && !generate {
|
||||
delete(decoded, "generate")
|
||||
}
|
||||
return json.Marshal(decoded)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user