fix(ai-proxy): include tool call type in Claude stream deltas (#3985)

Signed-off-by: DENG <33118163+XinhhD@users.noreply.github.com>
Co-authored-by: woody <yaodiwu618@gmail.com>
This commit is contained in:
DENG
2026-06-17 12:18:18 +08:00
committed by GitHub
parent 7e11e2f320
commit 3c3a067f07
3 changed files with 45 additions and 0 deletions

View File

@@ -115,6 +115,28 @@ func TestBedrockStreamPreservesClaudeNativeIndexesAndStops(t *testing.T) {
assert.Equal(t, 2, *events[0].Payload.Index)
}
func TestBedrockStreamToolCallArgumentDeltaIncludesFunctionType(t *testing.T) {
provider := &bedrockProvider{}
ctx := newMockMultipartHttpContext()
chunk, err := provider.convertEventFromBedrockToOpenAI(ctx, ConverseStreamEvent{
ContentBlockIndex: 0,
Delta: &converseStreamEventContentBlockDelta{
ToolUse: &toolUseBlockDelta{Input: `{"path":"/tmp/example"}`},
},
})
require.NoError(t, err)
body := strings.TrimPrefix(strings.TrimSpace(string(chunk)), ssePrefix)
var event chatCompletionResponse
require.NoError(t, json.Unmarshal([]byte(body), &event))
require.Len(t, event.Choices, 1)
require.NotNil(t, event.Choices[0].Delta)
require.Len(t, event.Choices[0].Delta.ToolCalls, 1)
assert.Equal(t, "function", event.Choices[0].Delta.ToolCalls[0].Type)
assert.Equal(t, `{"path":"/tmp/example"}`, event.Choices[0].Delta.ToolCalls[0].Function.Arguments)
}
func TestBedrockResponsePreservesClaudeNativeRedactedThinking(t *testing.T) {
provider := &bedrockProvider{}
ctx := newMockMultipartHttpContext()

View File

@@ -925,6 +925,7 @@ func (c *claudeProvider) streamResponseClaude2OpenAI(ctx wrapper.HttpContext, or
ToolCalls: []toolCall{
{
Index: index,
Type: "function",
Function: functionCall{
Arguments: origResponse.Delta.PartialJson,
},

View File

@@ -443,6 +443,28 @@ func TestClaudeProvider_StreamPreservesNativeSignatureAndStopsForClaudeConversio
assert.Equal(t, "content_block_stop", events[0].Name)
}
func TestClaudeProvider_StreamToolCallArgumentDeltaIncludesFunctionType(t *testing.T) {
provider := &claudeProvider{}
ctx := newMockMultipartHttpContext()
index := 0
response := provider.streamResponseClaude2OpenAI(ctx, &claudeTextGenStreamResponse{
Type: "content_block_delta",
Index: &index,
Delta: &claudeTextGenDelta{
Type: "input_json_delta",
PartialJson: `{"path":"/tmp/example"}`,
},
})
require.NotNil(t, response)
require.Len(t, response.Choices, 1)
require.NotNil(t, response.Choices[0].Delta)
require.Len(t, response.Choices[0].Delta.ToolCalls, 1)
assert.Equal(t, "function", response.Choices[0].Delta.ToolCalls[0].Type)
assert.Equal(t, `{"path":"/tmp/example"}`, response.Choices[0].Delta.ToolCalls[0].Function.Arguments)
}
func TestClaudeProvider_BuildClaudeTextGenRequest_ClaudeCodeMode(t *testing.T) {
provider := &claudeProvider{
config: ProviderConfig{