Skip to content

Commit 671b2d3

Browse files
authored
feat(langchain): add v1 support (#1411)
1 parent 1b61c36 commit 671b2d3

File tree

13 files changed

+1314
-1830
lines changed

13 files changed

+1314
-1830
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- name: Set up Python
3131
uses: actions/setup-python@v4
3232
with:
33-
python-version: "3.12"
33+
python-version: "3.13"
3434
- name: Install poetry
3535
uses: abatilo/actions-poetry@v2
3636
- name: Setup a local virtual environment
@@ -69,9 +69,10 @@ jobs:
6969
fail-fast: false
7070
matrix:
7171
python-version:
72-
- "3.9"
7372
- "3.10"
7473
- "3.11"
74+
- "3.12"
75+
- "3.13"
7576

7677
name: Test on Python version ${{ matrix.python-version }}
7778
steps:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repos:
1212
types_or: [python, pyi, jupyter]
1313

1414
- repo: https://github.com/pre-commit/mirrors-mypy
15-
rev: v1.8.0
15+
rev: v1.18.2
1616
hooks:
1717
- id: mypy
1818
additional_dependencies:

langfuse/_client/client.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,7 @@ def __init__(
211211
additional_headers: Optional[Dict[str, str]] = None,
212212
tracer_provider: Optional[TracerProvider] = None,
213213
):
214-
self._host = host or cast(
215-
str, os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
216-
)
214+
self._host = host or os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
217215
self._environment = environment or cast(
218216
str, os.environ.get(LANGFUSE_TRACING_ENVIRONMENT)
219217
)

langfuse/_utils/serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
# Attempt to import Serializable
2121
try:
22-
from langchain.load.serializable import Serializable
22+
from langchain_core.load.serializable import Serializable
2323
except ImportError:
2424
# If Serializable is not available, set it to a placeholder type
2525
class Serializable: # type: ignore

langfuse/langchain/CallbackHandler.py

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1-
import typing
21
from contextvars import Token
2+
from typing import (
3+
Any,
4+
Dict,
5+
List,
6+
Literal,
7+
Optional,
8+
Sequence,
9+
Set,
10+
Type,
11+
Union,
12+
cast,
13+
)
14+
from uuid import UUID
315

416
import pydantic
517
from opentelemetry import context, trace
@@ -16,41 +28,52 @@
1628
LangfuseSpan,
1729
LangfuseTool,
1830
)
31+
from langfuse._utils import _get_timestamp
32+
from langfuse.langchain.utils import _extract_model_name
1933
from langfuse.logger import langfuse_logger
2034

2135
try:
22-
import langchain # noqa
23-
24-
except ImportError as e:
25-
langfuse_logger.error(
26-
f"Could not import langchain. The langchain integration will not work. {e}"
27-
)
36+
import langchain
2837

29-
from typing import Any, Dict, List, Literal, Optional, Sequence, Set, Type, Union, cast
30-
from uuid import UUID
38+
if langchain.__version__.startswith("1"):
39+
# Langchain v1
40+
from langchain_core.agents import AgentAction, AgentFinish
41+
from langchain_core.callbacks import (
42+
BaseCallbackHandler as LangchainBaseCallbackHandler,
43+
)
44+
from langchain_core.documents import Document
45+
from langchain_core.messages import (
46+
AIMessage,
47+
BaseMessage,
48+
ChatMessage,
49+
FunctionMessage,
50+
HumanMessage,
51+
SystemMessage,
52+
ToolMessage,
53+
)
54+
from langchain_core.outputs import ChatGeneration, LLMResult
3155

32-
from langfuse._utils import _get_timestamp
33-
from langfuse.langchain.utils import _extract_model_name
56+
else:
57+
# Langchain v0
58+
from langchain.callbacks.base import ( # type: ignore
59+
BaseCallbackHandler as LangchainBaseCallbackHandler,
60+
)
61+
from langchain.schema.agent import AgentAction, AgentFinish # type: ignore
62+
from langchain.schema.document import Document # type: ignore
63+
from langchain_core.messages import (
64+
AIMessage,
65+
BaseMessage,
66+
ChatMessage,
67+
FunctionMessage,
68+
HumanMessage,
69+
SystemMessage,
70+
ToolMessage,
71+
)
72+
from langchain_core.outputs import (
73+
ChatGeneration,
74+
LLMResult,
75+
)
3476

35-
try:
36-
from langchain.callbacks.base import (
37-
BaseCallbackHandler as LangchainBaseCallbackHandler,
38-
)
39-
from langchain.schema.agent import AgentAction, AgentFinish
40-
from langchain.schema.document import Document
41-
from langchain_core.messages import (
42-
AIMessage,
43-
BaseMessage,
44-
ChatMessage,
45-
FunctionMessage,
46-
HumanMessage,
47-
SystemMessage,
48-
ToolMessage,
49-
)
50-
from langchain_core.outputs import (
51-
ChatGeneration,
52-
LLMResult,
53-
)
5477
except ImportError:
5578
raise ModuleNotFoundError(
5679
"Please install langchain to use the Langfuse langchain integration: 'pip install langchain'"
@@ -1011,7 +1034,7 @@ def _flatten_comprehension(matrix: Any) -> Any:
10111034
return [item for row in matrix for item in row]
10121035

10131036

1014-
def _parse_usage_model(usage: typing.Union[pydantic.BaseModel, dict]) -> Any:
1037+
def _parse_usage_model(usage: Union[pydantic.BaseModel, dict]) -> Any:
10151038
# maintains a list of key translations. For each key, the usage model is checked
10161039
# and a new object will be created with the new key if the key exists in the usage model
10171040
# All non matched keys will remain on the object.

0 commit comments

Comments
 (0)