diff --git a/components/model/claude/claude.go b/components/model/claude/claude.go index 24d5bdac6..da9648dce 100644 --- a/components/model/claude/claude.go +++ b/components/model/claude/claude.go @@ -627,8 +627,10 @@ func (cm *ChatModel) populateInput(params *anthropic.MessageNewParams, system [] return fmt.Errorf("convert schema message fail: %w", err) } - if ctrl := msgParam.Content[len(msgParam.Content)-1].GetCacheControl(); ctrl != nil && ctrl.Type != "" { - hasSetMsgBreakPoint = true + if len(msgParam.Content) > 0 { + if ctrl := msgParam.Content[len(msgParam.Content)-1].GetCacheControl(); ctrl != nil && ctrl.Type != "" { + hasSetMsgBreakPoint = true + } } msgParams = append(msgParams, msgParam) @@ -636,8 +638,10 @@ func (cm *ChatModel) populateInput(params *anthropic.MessageNewParams, system [] if !hasSetMsgBreakPoint && specOptions.AutoCacheControl != nil { lastMsgParam := msgParams[len(msgParams)-1] - lastBlock := lastMsgParam.Content[len(lastMsgParam.Content)-1] - populateContentBlockBreakPoint(lastBlock, specOptions.AutoCacheControl) + if len(lastMsgParam.Content) > 0 { + lastBlock := lastMsgParam.Content[len(lastMsgParam.Content)-1] + populateContentBlockBreakPoint(lastBlock, specOptions.AutoCacheControl) + } } params.Messages = msgParams diff --git a/components/model/claude/claude_test.go b/components/model/claude/claude_test.go index d5f10fb86..da97d07e9 100644 --- a/components/model/claude/claude_test.go +++ b/components/model/claude/claude_test.go @@ -246,6 +246,35 @@ func TestClaude(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "I see a beautiful sunset image", resp.Content) }) + + mockey.PatchConvey("assistant message with tool calls but empty content should not panic", t, func() { + resp, err := model.genMessageNewParams([]*schema.Message{ + schema.UserMessage("What's the weather in Paris?"), + schema.AssistantMessage("", []schema.ToolCall{ + { + ID: "call_1", + Function: schema.FunctionCall{ + Name: "get_weather", + Arguments: `{"city":"Paris"}`, + }, + }, + }), + schema.ToolMessage(`{"temperature": 20}`, "call_1"), + }) + assert.NoError(t, err) + assert.Len(t, resp.Messages, 3) + }) + + mockey.PatchConvey("message with empty content should not panic", t, func() { + resp, err := model.genMessageNewParams([]*schema.Message{ + {Role: schema.User, Content: "hello"}, + {Role: schema.Assistant}, + {Role: schema.User, Content: "world"}, + }) + assert.NoError(t, err) + assert.Len(t, resp.Messages, 3) + assert.Empty(t, resp.Messages[1].Content) + }) } func clearAnthropicAuthEnv(t *testing.T) {