Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ffae686
feat(langchain): add ChatAnthropic support to langchain instrumentation
bhumikadangayach Jun 30, 2026
ef52763
changelog: add entry for ChatAnthropic langchain support
bhumikadangayach Jun 30, 2026
b6ef07d
fix: address Copilot review comments
bhumikadangayach Jun 30, 2026
d832e66
fix: rename changelog fragment to match PR number
bhumikadangayach Jun 30, 2026
acd78dc
fix: apply ruff formatting
bhumikadangayach Jun 30, 2026
1731090
fix: apply ruff formatting to test_llm_call.py
bhumikadangayach Jun 30, 2026
b31a02f
test(langchain): add VCR tool-calling test for ChatAnthropic
bhumikadangayach Jul 6, 2026
324cc72
fix: move tool import to top-level
bhumikadangayach Jul 6, 2026
b0ea4d1
fix(langchain): correct stop_reason key lookup for Anthropic finish r…
bhumikadangayach Jul 7, 2026
f02c380
fix(langchain): apply ruff formatting, align finish_reason assertion …
bhumikadangayach Jul 7, 2026
ce861db
style(langchain): remove blank line per ruff 0.14.1 formatting
bhumikadangayach Jul 7, 2026
3083253
style: remove leftover blank lines from conflict resolution
bhumikadangayach Jul 9, 2026
d3bf7e2
docs: clarify changelog entry per rads-1996's review
bhumikadangayach Jul 11, 2026
66e7bea
test(langchain): add coverage for stop_sequences fallback per review
bhumikadangayach Jul 14, 2026
71dbde8
docs(langchain): add AI-generated header to tool_call cassette per AG…
bhumikadangayach Jul 14, 2026
5603c51
fix(langchain): add langchain-anthropic to conformance env deps
bhumikadangayach Jul 14, 2026
13b625a
fix(langchain): rebuild tool_call cassette to match real request body
bhumikadangayach Jul 15, 2026
46c311a
fix(langchain): pin langchain-anthropic in oldest test requirements
bhumikadangayach Jul 15, 2026
1e7c6cf
fix(langchain): add serialized.kwargs fallback for constructor-level …
bhumikadangayach Jul 15, 2026
216acf7
fix(langchain): pin max_tokens for cross-version cassette compatibili…
bhumikadangayach Jul 15, 2026
8ddf514
fix: remove leftover merge conflict markers in requirements.latest.txt
bhumikadangayach Jul 21, 2026
1723280
fix: resolve conflict markers in requirements.latest.txt, sync boto3/…
bhumikadangayach Jul 22, 2026
9845804
Merge branch 'main' into feat/chat-anthropic-langchain-support
lmolkova Jul 22, 2026
e364186
Apply suggestions from code review
lmolkova Jul 22, 2026
67806bc
Initial plan
Copilot Jul 22, 2026
6627ed4
Merge remote-tracking branch 'origin/pr/188' into copilot/fix-lint-in…
Copilot Jul 22, 2026
6a9c5a2
fix: remove trailing whitespace in test_llm_call.py (W291)
Copilot Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add ChatAnthropic tool-calling test coverage and fix finish_reason extraction for
Anthropic responses in LangChain instrumentation.
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,19 @@ def on_chat_model_start(
frequency_penalty = params.get("frequency_penalty")
presence_penalty = params.get("presence_penalty")
stop_sequences = params.get("stop")
if stop_sequences is None:
stop_sequences = params.get("stop_sequences")
if stop_sequences is None:
serialized_kwargs: dict[str, Any] = (
serialized.get("kwargs") or {}
)
stop_sequences = serialized_kwargs.get("stop_sequences")
seed = params.get("seed")
temperature = params.get("temperature")
# ``max_completion_tokens`` is OpenAI-specific; fall back to the
# generic ``max_tokens`` used by Anthropic, Mistral, Cohere, etc.
max_tokens = params.get("max_completion_tokens") or params.get(
"max_tokens"
max_tokens = (
params.get("max_completion_tokens")
if params.get("max_completion_tokens") is not None
else params.get("max_tokens")
)

provider = normalize_provider(metadata) or "unknown"
Expand Down Expand Up @@ -327,7 +334,10 @@ def on_llm_end(
):
finish_reason = (
chat_generation.message.response_metadata.get(
"stopReason", "unknown"
"stopReason"
)
or chat_generation.message.response_metadata.get(
"stop_reason", "unknown"
)
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
interactions:
- request:
body: |-
{"model": "claude-sonnet-4-5", "max_tokens": 1024, "temperature": 0.1, "system": "You are a helpful assistant!", "messages": [{"role": "user", "content": "What is the capital of France?"}]}
headers:
Content-Type:
- application/json
User-Agent:
- !!binary |
QW50aHJvcGljL1B5dGhvbiAxLjAuMA==
x-api-key:
- test_key
anthropic-version:
- '2023-06-01'
method: POST
uri: https://api.anthropic.com/v1/messages
response:
body:
string: |-
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-5",
"content": [
{
"type": "text",
"text": "The capital of France is Paris."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 13,
"output_tokens": 10
}
}
headers:
Content-Type:
- application/json
Date:
- Thu, 04 Sep 2025 20:00:58 GMT
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# TODO: this is generated by AI, re-record
interactions:
- request:
body: |-
{"max_tokens":1024,"messages":[{"role":"user","content":"Say hi"}],"model":"claude-sonnet-4-5","stop_sequences":["STOP"]}
headers:
Content-Type:
- application/json
x-api-key:
- test_key
anthropic-version:
- '2023-06-01'
method: POST
uri: https://api.anthropic.com/v1/messages
response:
body:
string: |-
{
"id": "msg_anthropic_constructor_stop_sequences_001",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-5",
"content": [
{
"type": "text",
"text": "Hi there!"
}
],
"stop_reason": "stop_sequence",
"stop_sequence": "STOP",
"usage": {
"input_tokens": 10,
"output_tokens": 5
}
}
headers:
Content-Type:
- application/json
Date:
- Thu, 04 Sep 2025 20:00:58 GMT
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# TODO: this is generated by AI, re-record
interactions:
- request:
body: |-
{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"temperature": 0.1,
"stop_sequences": ["STOP"],
"messages": [
{
"role": "user",
"content": "Say hi"
}
]
}
headers:
Content-Type:
- application/json
x-api-key:
- test_key
anthropic-version:
- '2023-06-01'
method: POST
uri: https://api.anthropic.com/v1/messages
response:
body:
string: |-
{
"id": "msg_anthropic_stop_sequences_001",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-5",
"content": [
{
"type": "text",
"text": "Hi there!"
}
],
"stop_reason": "stop_sequence",
"stop_sequence": "STOP",
"usage": {
"input_tokens": 10,
"output_tokens": 5
}
}
headers:
Content-Type:
- application/json
Date:
- Thu, 04 Sep 2025 20:00:58 GMT
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# TODO: this is generated by AI, re-record
interactions:
- request:
body: |-
{"model":"claude-sonnet-4-5","max_tokens":1024,"messages":[{"role":"user","content":"What's the weather in Seattle?"}],"temperature":0.1,"tools":[{"name":"get_current_weather","input_schema":{"properties":{"location":{"type":"string"}},"required":["location"],"type":"object"},"description":"Get the current weather in a given location."}]}
headers:
Content-Type:
- application/json
x-api-key:
- test_key
anthropic-version:
- '2023-06-01'
method: POST
uri: https://api.anthropic.com/v1/messages
response:
body:
string: |-
{
"id": "msg_anthropic_tool_call_001",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-5",
"content": [
{
"type": "tool_use",
"id": "toolu_01",
"name": "get_current_weather",
"input": {
"location": "Seattle, WA"
}
}
],
"stop_reason": "tool_use",
"stop_sequence": null,
"usage": {
"input_tokens": 20,
"output_tokens": 15
}
}
headers:
Content-Type:
- application/json
Date:
- Thu, 04 Sep 2025 20:00:58 GMT
status:
code: 200
message: OK
version: 1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import boto3
import pytest
from langchain_anthropic import ChatAnthropic
from langchain_aws import ChatBedrock
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_openai import ChatOpenAI
Expand Down Expand Up @@ -65,6 +66,18 @@ def fixture_us_amazon_nova_lite_v1_0():
yield llm


@pytest.fixture(scope="function", name="chat_anthropic_claude_sonnet")
def fixture_chat_anthropic_claude_sonnet():
llm_model_value = "claude-sonnet-4-5"
llm = ChatAnthropic(
model=llm_model_value,
api_key="test_key",
temperature=0.1,
max_tokens=1024,
)
yield llm


@pytest.fixture(scope="function", name="gemini")
def fixture_gemini():
llm_model_value = "gemini-2.5-pro"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ langchain==1.3.14
langchain-openai==1.3.5
langchain-aws==1.6.2
langchain-google-genai==4.2.7
langchain-anthropic==1.4.8
boto3==1.43.53

-e util/opentelemetry-util-genai
-e instrumentation/opentelemetry-instrumentation-genai-langchain[instruments]
-e instrumentation/opentelemetry-instrumentation-genai-langchain[instruments]
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
langchain-openai==0.2.0
langchain-aws==0.2.2
langchain-google-genai==2.0.0
boto3==1.37.0
langchain-anthropic==0.3.0
boto3==1.37.0
Loading
Loading