llms/anthropic: GenerateContent never calls HandleLLMGenerateContentEnd on success

Author: atharvamhaskeCreated Sep 17, 2026Updated Sep 17, 2026

Summary

llms/anthropic's GenerateContent calls CallbacksHandler.HandleLLMGenerateContentStart on entry and HandleLLMError on failure, but never calls HandleLLMGenerateContentEnd on a successful response. Every other provider I checked (openai, googleai) calls HandleLLMGenerateContentEnd on success. This breaks any callbacks.Handler implementation that tracks call duration or state between start and end, since the end hook for a successful call never fires.

Where

llms/anthropic/anthropicllm.go, both generateCompletionsContent (legacy text completions path) and generateMessagesContent (the main path) return their result directly on success:

go
resp := &llms.ContentResponse{
    Choices: []*llms.ContentChoice{
        {
            Content: result.Text,
        },
    },
}
return resp, nil

Neither ever calls o.CallbacksHandler.HandleLLMGenerateContentEnd(ctx, resp).

Compare with openai

llms/openai/openaillm.go's GenerateContent calls o.CallbacksHandler.HandleLLMGenerateContentEnd(ctx, response) right before returning on the success path. llms/anthropic should do the same.

Impact

Any code using a custom callbacks.Handler to trace or measure Anthropic calls through langchaingo gets a start event with no matching end event on success. We found this while instrumenting langchaingo for Braintrust's Go SDK — our tracer pushes a span on HandleLLMGenerateContentStart and only closes it on HandleLLMGenerateContentEnd/HandleLLMError, so every successful Anthropic call through llms/anthropic leaves an open span with no output, no metrics, and no end time.

Suggested fix

Call o.CallbacksHandler.HandleLLMGenerateContentEnd(ctx, resp) before return resp, nil in both generateCompletionsContent and generateMessagesContent, matching the pattern already used in llms/openai.