From b5b11eeeb4642c13d51bbebeae808ffc3cacf4a6 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Thu, 30 Oct 2025 11:36:24 +0000 Subject: [PATCH 1/5] fix: Add LangChain 1.0+ compatibility for CallbackHandler imports - Use try/except to import from langchain_core first (LangChain 1.0+) - Fall back to legacy langchain imports for older versions - Maintains backward compatibility with LangChain 0.x - All existing tests pass (45 passed) Fixes #362 --- posthog/ai/langchain/callbacks.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/posthog/ai/langchain/callbacks.py b/posthog/ai/langchain/callbacks.py index 1922f787..d0a332da 100644 --- a/posthog/ai/langchain/callbacks.py +++ b/posthog/ai/langchain/callbacks.py @@ -20,8 +20,14 @@ ) from uuid import UUID -from langchain.callbacks.base import BaseCallbackHandler -from langchain.schema.agent import AgentAction, AgentFinish +try: + # LangChain 1.0+ and modern 0.x with langchain-core + from langchain_core.callbacks.base import BaseCallbackHandler + from langchain_core.agents import AgentAction, AgentFinish +except (ImportError, ModuleNotFoundError): + # Fallback for older LangChain versions + from langchain.callbacks.base import BaseCallbackHandler # type: ignore + from langchain.schema.agent import AgentAction, AgentFinish # type: ignore from langchain_core.documents import Document from langchain_core.messages import ( AIMessage, From fe694987dabae1ac7499eca40f0f0aa6102981f2 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Thu, 30 Oct 2025 11:43:15 +0000 Subject: [PATCH 2/5] test: Add regression test for AgentAction/AgentFinish imports - Tests that AgentAction and AgentFinish can be imported - Tests on_agent_action and on_agent_finish callbacks with mock data - Ensures compatibility with both LangChain 0.x and 1.0+ - Catches the import issue that was previously only tested with API keys This addresses a test coverage gap identified during code review. --- posthog/test/ai/langchain/test_callbacks.py | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/posthog/test/ai/langchain/test_callbacks.py b/posthog/test/ai/langchain/test_callbacks.py index b6e74e6b..26b1fbe8 100644 --- a/posthog/test/ai/langchain/test_callbacks.py +++ b/posthog/test/ai/langchain/test_callbacks.py @@ -1877,3 +1877,46 @@ def test_tool_definition(mock_client): assert props["$ai_latency"] == 1.0 # Verify that tools are captured in the $ai_tools property assert props["$ai_tools"] == tools + + +def test_agent_action_and_finish_imports(): + """ + Regression test for LangChain 1.0+ compatibility (Issue #362). + Verifies that AgentAction and AgentFinish can be imported and used. + This test ensures the imports work with both LangChain 0.x and 1.0+. + """ + # Import the types that caused the compatibility issue + try: + from langchain_core.agents import AgentAction, AgentFinish + except (ImportError, ModuleNotFoundError): + from langchain.schema.agent import AgentAction, AgentFinish # type: ignore + + # Verify they're available in the callbacks module + from posthog.ai.langchain.callbacks import CallbackHandler + + # Test on_agent_action with mock data + mock_client = MagicMock() + callbacks = CallbackHandler(mock_client) + run_id = uuid.uuid4() + parent_run_id = uuid.uuid4() + + # Create mock AgentAction + action = AgentAction(tool="test_tool", tool_input="test_input", log="test_log") + + # Should not raise an exception + callbacks.on_agent_action(action, run_id=run_id, parent_run_id=parent_run_id) + + # Verify parent was set + assert run_id in callbacks._parent_tree + assert callbacks._parent_tree[run_id] == parent_run_id + + # Test on_agent_finish with mock data + finish = AgentFinish(return_values={"output": "test_output"}, log="finish_log") + + # Should not raise an exception + callbacks.on_agent_finish(finish, run_id=run_id, parent_run_id=parent_run_id) + + # Verify capture was called + assert mock_client.capture.call_count == 1 + call_args = mock_client.capture.call_args[1] + assert call_args["event"] == "$ai_span" From 4ea52bb0fda46f0be31fe683e51e1b05c2adbf90 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Thu, 30 Oct 2025 11:55:46 +0000 Subject: [PATCH 3/5] chore: Add CHANGELOG entry for LangChain 1.0+ compatibility fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b0b08d9..5da0d479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased - fix(django): Restore process_exception method to capture view and downstream middleware exceptions (fixes #329) +- fix(ai/langchain): Add LangChain 1.0+ compatibility for CallbackHandler imports (fixes #362) # 6.7.11 - 2025-10-28 From 87dfcc03d9fb2a22fd6b0ad8d45f0d3a083553ed Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Thu, 30 Oct 2025 12:01:41 +0000 Subject: [PATCH 4/5] fix: Remove unused type: ignore comments for mypy The type: ignore comments were only needed when the except block executes, but CI runs with LangChain 1.0+ so the try block succeeds. Mypy flags these as unused-ignore errors. --- posthog/ai/langchain/callbacks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posthog/ai/langchain/callbacks.py b/posthog/ai/langchain/callbacks.py index d0a332da..756201e0 100644 --- a/posthog/ai/langchain/callbacks.py +++ b/posthog/ai/langchain/callbacks.py @@ -26,8 +26,8 @@ from langchain_core.agents import AgentAction, AgentFinish except (ImportError, ModuleNotFoundError): # Fallback for older LangChain versions - from langchain.callbacks.base import BaseCallbackHandler # type: ignore - from langchain.schema.agent import AgentAction, AgentFinish # type: ignore + from langchain.callbacks.base import BaseCallbackHandler + from langchain.schema.agent import AgentAction, AgentFinish from langchain_core.documents import Document from langchain_core.messages import ( AIMessage, From 7fbccccf8abcf6064adac42c53dc154bf22d95b1 Mon Sep 17 00:00:00 2001 From: Andrew Maguire Date: Sun, 2 Nov 2025 17:06:43 +0000 Subject: [PATCH 5/5] chore: bump version to 6.7.12 for langchain 1.0 compatibility --- CHANGELOG.md | 2 +- posthog/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da0d479..65d65318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Unreleased +# 6.7.12 - 2025-11-02 - fix(django): Restore process_exception method to capture view and downstream middleware exceptions (fixes #329) - fix(ai/langchain): Add LangChain 1.0+ compatibility for CallbackHandler imports (fixes #362) diff --git a/posthog/version.py b/posthog/version.py index 1fe91ee0..b4d60d14 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1,4 +1,4 @@ -VERSION = "6.7.11" +VERSION = "6.7.12" if __name__ == "__main__": print(VERSION, end="") # noqa: T201