@@ -38,10 +38,10 @@ type responsesInterceptionBase struct {
3838 metrics metrics.Metrics
3939}
4040
41- func NewResponsesService (baseURL string , key string , logger slog. Logger ) responses.ResponseService {
41+ func NewResponsesService (baseURL string , apiKey string ) responses.ResponseService {
4242 opts := []option.RequestOption {
43- option .WithAPIKey (key ),
4443 option .WithBaseURL (baseURL ),
44+ option .WithAPIKey (apiKey ),
4545 }
4646
4747 return responses .NewResponseService (opts ... )
@@ -99,7 +99,7 @@ func (i *responsesInterceptionBase) validateRequest(ctx context.Context, w http.
9999 return nil
100100}
101101
102- func (i * responsesInterceptionBase ) requestOptions (respBody * deltaBuffer ) []option.RequestOption {
102+ func (i * responsesInterceptionBase ) requestOptions (payloadBuff * deltaBuffer ) []option.RequestOption {
103103 opts := []option.RequestOption {
104104 // Sends original payload to solve json re-encoding issues
105105 // eg. Codex CLI produces requests without ID set in reasoning items: https://platform.openai.com/docs/api-reference/responses/create#responses_create-input-input_item_list-item-reasoning-id
@@ -108,15 +108,15 @@ func (i *responsesInterceptionBase) requestOptions(respBody *deltaBuffer) []opti
108108 option .WithRequestBody ("application/json" , i .reqPayload ),
109109
110110 // Reads response body into given buffer
111- option .WithMiddleware (teeMiddleware (respBody )),
111+ option .WithMiddleware (teeMiddleware (payloadBuff )),
112112 }
113113 if ! i .req .Stream {
114114 opts = append (opts , option .WithRequestTimeout (time .Second * 60 )) // TODO: configurable timeout
115115 }
116116 return opts
117117}
118118
119- // handleUpstreamError checks error if it is an openAI error and if ProcessRequest should exit early.
119+ // handleUpstreamError checks if error is an openAI error and if caller should exit early.
120120// If it is openAI responses error -> sets proper http response code and returns false to not exit early
121121// response body will be sent using the same method as non-error response, using teeMiddleware -> deltaBuffer.
122122// If it is a connection error or unnknown error -> returns given error + true to indicate early exit
@@ -142,22 +142,24 @@ func (i *responsesInterceptionBase) handleUpstreamError(ctx context.Context, ups
142142}
143143
144144// teeMiddleware copies response body to given buffer leaving original response intact/consumable for openAI SDK
145- func teeMiddleware (respBody io. Writer ) func (req * http.Request , next option.MiddlewareNext ) (* http.Response , error ) {
145+ func teeMiddleware (payloadBuff * deltaBuffer ) func (req * http.Request , next option.MiddlewareNext ) (* http.Response , error ) {
146146 return func (req * http.Request , next option.MiddlewareNext ) (* http.Response , error ) {
147147 resp , err := next (req )
148148 if err != nil || resp == nil || resp .Body == nil {
149149 return resp , err
150150 }
151151
152- resp .Body = io .NopCloser (io .TeeReader (resp .Body , respBody ))
152+ payloadBuff .closer = resp .Body
153+ resp .Body = io .NopCloser (io .TeeReader (resp .Body , payloadBuff ))
153154 return resp , nil
154155 }
155156}
156157
157- // deltaBuffer stores everything written to it and lets you read only the new bytes since last drain.
158+ // deltaBuffer is a thread safe byte buffer that supports reading incremental data (added after last read)
158159type deltaBuffer struct {
159- mu sync.Mutex
160- buf bytes.Buffer
160+ mu sync.Mutex
161+ buf bytes.Buffer
162+ closer io.ReadCloser
161163}
162164
163165func (d * deltaBuffer ) Write (p []byte ) (int , error ) {
@@ -166,11 +168,16 @@ func (d *deltaBuffer) Write(p []byte) (int, error) {
166168 return d .buf .Write (p )
167169}
168170
169- func (d * deltaBuffer ) Read (p []byte ) (int , error ) {
171+ // Reads all from original resqusts body so it is properly copied by TeeReader to buffer
172+ func (d * deltaBuffer ) drain () error {
173+ if d .closer == nil {
174+ return nil
175+ }
176+
170177 d .mu .Lock ()
171178 defer d .mu .Unlock ()
172- c , err := d . buf . Read ( p )
173- return c , err
179+ _ , err := io . ReadAll ( d . closer )
180+ return err
174181}
175182
176183// readDelta returns only the bytes appended since the last readDelta call.
0 commit comments