fix(interactions): bridge apply_patch tool calls in responses translation

- Handle apply_patch custom tool call streaming deltas and snapshots for Responses API translation
- Track and resolve step indexes, function call identities, and error states across stream events
- Propagate apply_patch tool input errors and upstream failure states in stream and non-stream responses
This commit is contained in:
Luis Pater
2026-10-02 03:48:53 +08:00
parent fd48ea6840
commit 3ebee06516
96 changed files with 14576 additions and 554 deletions

View File

@@ -22,6 +22,7 @@ import (
)
type metaPreparedRequest struct {
applyPatch *helps.ApplyPatchResponsesState
baseModel string
from sdktranslator.Format
responseFormat sdktranslator.Format
@@ -61,12 +62,19 @@ func (e *MetaExecutor) prepareResponsesRequest(ctx context.Context, req cliproxy
body, _ = sjson.DeleteBytes(body, "safety_identifier")
body, _ = sjson.DeleteBytes(body, "stream_options")
body, _ = sjson.DeleteBytes(body, "client_metadata")
applyPatch := helps.NewApplyPatchResponsesState(from, originalPayload, originalTranslated)
var errNormalizePatch error
body, errNormalizePatch = helps.NormalizeApplyPatchResponsesRequest(body, originalPayload)
if errNormalizePatch != nil {
return nil, errNormalizePatch
}
body = normalizeCodexInstructions(body)
body = sanitizeOpenAIResponsesReasoningEncryptedContent(ctx, "meta executor", body)
body = helps.SanitizeMetaWebSearchTools(body)
body = helps.NormalizeCodexToolIntegerTypes(body, opts.Headers)
return &metaPreparedRequest{
applyPatch: applyPatch,
baseModel: baseModel,
from: from,
responseFormat: responseFormat,
@@ -170,25 +178,47 @@ func (e *MetaExecutor) translateMetaCompleted(ctx context.Context, req cliproxye
if errEvent := metaStreamEventError(eventData); errEvent != nil {
return metaCompletedTranslation{}, errEvent
}
eventType := gjson.GetBytes(eventData, "type").String()
switch eventType {
case "response.output_item.done":
xaiCollectOutputItemDone(eventData, outputItemsByIndex, &outputItemsFallback)
case "response.completed", "response.incomplete":
completedData := patchCodexCompletedOutput(eventData, outputItemsByIndex, outputItemsFallback)
var param any
out := sdktranslator.TranslateNonStream(ctx, prepared.to, prepared.responseFormat, req.Model, prepared.originalPayload, prepared.body, completedData, &param)
return metaCompletedTranslation{payload: out, sourceEvent: completedData}, nil
events, errBridge := prepared.applyPatch.Transform(eventData)
if errBridge != nil {
errBridge = statusErr{code: http.StatusBadGateway, msg: helps.ApplyPatchUpstreamErrorMessage}
return metaCompletedTranslation{}, errBridge
}
for _, eventData := range events {
eventType := gjson.GetBytes(eventData, "type").String()
switch eventType {
case "response.output_item.done":
xaiCollectOutputItemDone(eventData, outputItemsByIndex, &outputItemsFallback)
case "response.completed", "response.incomplete":
completedData := patchCodexCompletedOutput(eventData, outputItemsByIndex, outputItemsFallback)
var param any
out := sdktranslator.TranslateNonStream(ctx, prepared.to, prepared.responseFormat, req.Model, prepared.originalPayload, prepared.body, completedData, &param)
if helps.ApplyPatchTranslationError(param) != nil || len(out) == 0 {
return metaCompletedTranslation{}, statusErr{code: http.StatusBadGateway, msg: helps.ApplyPatchUpstreamErrorMessage}
}
return metaCompletedTranslation{payload: out, sourceEvent: completedData}, nil
}
}
}
if completedData, ok := metaAsCompletedEvent(data); ok {
completedData = patchCodexCompletedOutput(completedData, outputItemsByIndex, outputItemsFallback)
var errBridge error
completedData, errBridge = prepared.applyPatch.Bridge.TransformNonStream(completedData)
if errBridge != nil {
errBridge = statusErr{code: http.StatusBadGateway, msg: helps.ApplyPatchUpstreamErrorMessage}
return metaCompletedTranslation{}, errBridge
}
var param any
out := sdktranslator.TranslateNonStream(ctx, prepared.to, prepared.responseFormat, req.Model, prepared.originalPayload, prepared.body, completedData, &param)
if helps.ApplyPatchTranslationError(param) != nil || len(out) == 0 {
return metaCompletedTranslation{}, statusErr{code: http.StatusBadGateway, msg: helps.ApplyPatchUpstreamErrorMessage}
}
return metaCompletedTranslation{payload: out, sourceEvent: completedData}, nil
}
if errFinish := prepared.applyPatch.Finish(); errFinish != nil {
return metaCompletedTranslation{}, statusErr{code: http.StatusBadGateway, msg: helps.ApplyPatchUpstreamErrorMessage}
}
return metaCompletedTranslation{}, statusErr{code: http.StatusRequestTimeout, msg: "meta stream error: stream disconnected before response.completed or response.incomplete"}
}