diff --git a/providers/openai/openai_test.go b/providers/openai/openai_test.go index dd79810272716488f3b0b7c9aeebda0777035451..e9fd29dfc0bd73703a44219d2823bba27f8e8749 100644 --- a/providers/openai/openai_test.go +++ b/providers/openai/openai_test.go @@ -3631,6 +3631,7 @@ func TestResponsesGenerate_PreviousResponseIDOption(t *testing.T) { ProviderOptions: fantasy.ProviderOptions{ Name: &ResponsesProviderOptions{ PreviousResponseID: fantasy.Opt("resp_prev_123"), + Store: fantasy.Opt(true), }, }, }) @@ -4015,6 +4016,7 @@ func TestResponsesStream_PreviousResponseIDOption(t *testing.T) { ProviderOptions: fantasy.ProviderOptions{ Name: &ResponsesProviderOptions{ PreviousResponseID: fantasy.Opt("resp_prev_456"), + Store: fantasy.Opt(true), }, }, }) diff --git a/providers/openai/responses_language_model.go b/providers/openai/responses_language_model.go index 9126ac3c6366e270791fcca0a4d5446ea1647807..9704e14fdbefa00e9b71235f1d3367f4748d3c09 100644 --- a/providers/openai/responses_language_model.go +++ b/providers/openai/responses_language_model.go @@ -122,6 +122,7 @@ func getResponsesModelConfig(modelID string) responsesModelConfig { } const previousResponseIDHistoryError = "cannot combine previous_response_id with replayed conversation history; use either previous_response_id (server-side chaining) or explicit message replay, not both" +const previousResponseIDStoreError = "previous_response_id requires store to be true; the current response will not be stored and cannot be used for further chaining" func (o responsesLanguageModel) prepareParams(call fantasy.Call) (*responses.ResponseNewParams, []fantasy.CallWarning, error) { var warnings []fantasy.CallWarning @@ -167,6 +168,9 @@ func (o responsesLanguageModel) prepareParams(call fantasy.Call) (*responses.Res if err := validatePreviousResponseIDPrompt(call.Prompt); err != nil { return nil, warnings, err } + if openaiOptions.Store == nil || !*openaiOptions.Store { + return nil, warnings, errors.New(previousResponseIDStoreError) + } params.PreviousResponseID = param.NewOpt(*openaiOptions.PreviousResponseID) } diff --git a/providers/openai/responses_params_test.go b/providers/openai/responses_params_test.go index 0cefc1b182e6969ff97f3e29ddb62380be68ce96..2687f1db57108e47f58c240500b90bf1bc5e8d8b 100644 --- a/providers/openai/responses_params_test.go +++ b/providers/openai/responses_params_test.go @@ -66,6 +66,7 @@ func TestPrepareParams_PreviousResponseID(t *testing.T) { params, warnings, err := lm.prepareParams(testCall(prompt, &ResponsesProviderOptions{ PreviousResponseID: fantasy.Opt("resp_abc123"), + Store: fantasy.Opt(true), })) require.NoError(t, err) require.Empty(t, warnings) @@ -98,7 +99,10 @@ func TestPrepareParams_PreviousResponseID_Validation(t *testing.T) { t.Parallel() lm := testResponsesLM() - opts := &ResponsesProviderOptions{PreviousResponseID: fantasy.Opt("resp_abc123")} + opts := &ResponsesProviderOptions{ + PreviousResponseID: fantasy.Opt("resp_abc123"), + Store: fantasy.Opt(true), + } t.Run("rejects with assistant messages", func(t *testing.T) { t.Parallel() @@ -141,6 +145,29 @@ func TestPrepareParams_PreviousResponseID_Validation(t *testing.T) { }, opts)) require.EqualError(t, err, previousResponseIDHistoryError) }) + + t.Run("rejects without store", func(t *testing.T) { + t.Parallel() + + _, _, err := lm.prepareParams(testCall(fantasy.Prompt{ + testTextMessage(fantasy.MessageRoleUser, "hello"), + }, &ResponsesProviderOptions{ + PreviousResponseID: fantasy.Opt("resp_abc123"), + })) + require.EqualError(t, err, previousResponseIDStoreError) + }) + + t.Run("rejects with store false", func(t *testing.T) { + t.Parallel() + + _, _, err := lm.prepareParams(testCall(fantasy.Prompt{ + testTextMessage(fantasy.MessageRoleUser, "hello"), + }, &ResponsesProviderOptions{ + PreviousResponseID: fantasy.Opt("resp_abc123"), + Store: fantasy.Opt(false), + })) + require.EqualError(t, err, previousResponseIDStoreError) + }) } func TestValidatePreviousResponseIDPrompt(t *testing.T) {