Skip to content

chore: replace ResponsesNewParamsWrapper with ResponsesRequestPayload in responses interceptor#213

Merged
pawbana merged 4 commits intomainfrom
pb/responses-remove-paramswrap-blocking
Mar 18, 2026
Merged

chore: replace ResponsesNewParamsWrapper with ResponsesRequestPayload in responses interceptor#213
pawbana merged 4 commits intomainfrom
pb/responses-remove-paramswrap-blocking

Conversation

@pawbana
Copy link
Contributor

@pawbana pawbana commented Mar 12, 2026

Refactored the responses interceptor replacing ResponsesNewParamsWrapper with a new ResponsesRequestPayload type that wraps raw JSON bytes and consolidates operations made on request payload.

@pawbana pawbana force-pushed the pb/responses-remove-paramswrap-blocking branch 2 times, most recently from 5c4e7b0 to 7465ac6 Compare March 12, 2026 16:34
@pawbana pawbana force-pushed the pb/responses-remove-paramswrap-blocking branch 5 times, most recently from 11aeeb0 to be0adac Compare March 13, 2026 08:53
@pawbana pawbana marked this pull request as ready for review March 13, 2026 08:53
@pawbana pawbana force-pushed the pb/responses-remove-paramswrap-blocking branch from be0adac to 809aae2 Compare March 13, 2026 15:25

existing, err := p.existingToolItems()
if err != nil {
return p, err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap errors.

raw: []byte(`{"model":123,"stream":"yes","input":42}`),
want: `{"model":123,"stream":"yes","input":42}`,
model: "123",
stream: false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this is a consequence of not unmarshaling the payload, but this feels like an odd behaviour to test for without explicitly documenting this shortcoming of the new approach.

It won't matter once we move towards a reverse-proxy model, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should it be documented?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even just documenting it here is fine. I just don't want us to mistake "this is how it works" for "this is how it should work".

Comment on lines +123 to +125
if tc.wantSame {
require.Equal(t, p, updated)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: you could drop this and just specify wantNames.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left it as is since it is a bit more stronger check as it checks whole JSON instead of just ".tools" field.

assert.Equal(t, p, updated)
}
if tc.wantFlagSet {
assert.False(t, gjson.GetBytes(updated, "parallel_tool_calls").Bool())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a helper for this in the ResponsesRequestPayload type rather than scattering business logic around like this.

wantFlagSet bool
}{
{
name: "sets flag when tools exist",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more complicated than this now.

We only disable parallel tool calls when injected tools are defined, regardless of whether any client-issued tools exist.

return p.set(reqPathParallelToolCalls, false)
}

func (p ResponsesRequestPayload) withAppendedInputItems(items []responses.ResponseInputItemUnionParam) (ResponsesRequestPayload, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd prefer this were named as setters, which is what they are.

The "withXXX" pattern is usually used with the options pattern.

name: "unsupported input shape errors during rewrite",
raw: []byte(`{"model":"gpt-4o","input":123}`),
items: []responses.ResponseInputItemUnionParam{responses.ResponseInputItemParamOfFunctionCallOutput("call_123", "done")},
wantErr: "unsupported input type",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is not going to be useful to us or operators. We should include the field name and the type of the field plus the type of the incoming value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated error messages and the tests to check full error message instead of just a fragment of it.

require.NoError(t, err)
}

require.True(t, json.Valid(updated))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not necessary in the tests since NewResponsesRequestPayload already rejects invalid input.


// Disable parallel tool calls after injecting tools, so the check for
// existing tools in the payload sees the newly injected ones.
i.disableParallelToolCalls()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice this when I refactored the parallel tool calls logic, but disableParallelToolCalls is now being called twice in this func.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I was supposed to fix it but it got lost. I'll need to double check if it works after rebase.

return nil, fmt.Errorf("responses empty request body")
}
if !json.Valid(raw) {
return nil, fmt.Errorf("responses invalid JSON request body")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this reads a bit strangely.

Suggested change
return nil, fmt.Errorf("responses invalid JSON request body")
return nil, fmt.Errorf("invalid JSON payload")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I changed it to match copilot tests

assert.Contains(t, err.Error(), "unmarshal chat completions request body")

assert.Contains(t, err.Error(), "unmarshal responses request body")

but yeah, it sound a bit weird. Changed.

@pawbana pawbana force-pushed the pb/responses-remove-paramswrap-blocking branch from 809aae2 to 93d2b9c Compare March 16, 2026 14:51
Copy link
Contributor

@ssncferreira ssncferreira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🧹 nice refactor! Just a few nits

Copy link
Contributor Author

pawbana commented Mar 18, 2026

Merge activity

  • Mar 18, 6:29 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Mar 18, 6:29 PM UTC: @pawbana merged this pull request with Graphite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants