diff --git a/libs/langchain-cloudflare/examples/workers/README.md b/libs/langchain-cloudflare/examples/workers/README.md index 308842c..58edc46 100644 --- a/libs/langchain-cloudflare/examples/workers/README.md +++ b/libs/langchain-cloudflare/examples/workers/README.md @@ -8,7 +8,7 @@ This example demonstrates how to use `langchain-cloudflare` with Cloudflare Pyth - Structured output with Pydantic models - Tool calling - Multi-turn conversations -- `create_agent` pattern (requires langchain>=0.3.0) +- `create_agent` pattern (requires langchain>=1.0.0) - Vectorize operations (insert, search, delete) - D1 database operations diff --git a/libs/langchain-cloudflare/examples/workers/pyproject.toml b/libs/langchain-cloudflare/examples/workers/pyproject.toml index e482384..6955581 100644 --- a/libs/langchain-cloudflare/examples/workers/pyproject.toml +++ b/libs/langchain-cloudflare/examples/workers/pyproject.toml @@ -7,8 +7,9 @@ requires-python = ">=3.12" dependencies = [ "webtypy>=0.1.7", "langchain-cloudflare @ file:////Users/collierking/Desktop/github/langchain-cloudflare/libs/langchain-cloudflare", + # Keep pywrangler sync on the latest Pyodide-compatible 0.3.x core. + # scripts/setup_pyodide_deps.sh replaces this with LangChain 1.x wheels. "langchain-core>=0.3.81,<1.0.0", - "langchain>=0.3.0,<1.0.0", "sqlalchemy-cloudflare-d1 @ file:////Users/collierking/Desktop/github/sqlalchemy-cloudflare-d1", # NOTE: Do NOT include pydantic - use Pyodide's built-in version # pydantic_core requires compiled Rust binaries that aren't available for WebAssembly diff --git a/libs/langchain-cloudflare/examples/workers/scripts/setup_pyodide_deps.sh b/libs/langchain-cloudflare/examples/workers/scripts/setup_pyodide_deps.sh index 3cd99d9..ca8906b 100755 --- a/libs/langchain-cloudflare/examples/workers/scripts/setup_pyodide_deps.sh +++ b/libs/langchain-cloudflare/examples/workers/scripts/setup_pyodide_deps.sh @@ -13,8 +13,9 @@ # - pywrangler sync fails when it encounters these missing wheels # # Solution: -# - Install langchain-core>=1.0.0 via pywrangler (pure Python, has wheels) -# - Manually extract langchain, langgraph, langgraph_sdk wheels +# - Install a Pyodide-compatible langchain-core 0.3.x via pywrangler +# - Replace it by manually extracting langchain-core 1.x plus langchain, +# langgraph, and langgraph_sdk wheels # - Use pure Python stubs for xxhash and ormsgpack set -e @@ -27,8 +28,9 @@ TEMP_DIR="$PROJECT_DIR/.wheels_temp" # MARK: - Configuration -# Wheel versions to download -# NOTE: langchain 1.0.0 actually needs langchain-core 1.1.0 for all imports to work +# Wheel versions to download. +# This stack is known to keep create_agent available in Python Workers without +# pulling newer native dependencies that do not have Pyodide wheels. LANGCHAIN_VERSION="1.0.0" LANGCHAIN_CORE_VERSION="1.1.0" LANGGRAPH_VERSION="1.0.0" @@ -107,6 +109,8 @@ rm -rf "$PYTHON_MODULES/langchain_core" "$PYTHON_MODULES/langchain_core-"*.dist- rm -rf "$PYTHON_MODULES/langgraph" "$PYTHON_MODULES/langgraph-"*.dist-info 2>/dev/null || true rm -rf "$PYTHON_MODULES/langgraph_sdk" "$PYTHON_MODULES/langgraph_sdk-"*.dist-info 2>/dev/null || true rm -rf "$PYTHON_MODULES/langgraph_checkpoint" "$PYTHON_MODULES/langgraph_checkpoint-"*.dist-info 2>/dev/null || true +rm -rf "$PYTHON_MODULES/langchain_protocol" "$PYTHON_MODULES/langchain_protocol-"*.dist-info 2>/dev/null || true +rm -rf "$PYTHON_MODULES/langgraph_prebuilt" "$PYTHON_MODULES/langgraph_prebuilt-"*.dist-info 2>/dev/null || true download_and_extract_wheel "langchain" "$LANGCHAIN_VERSION" download_and_extract_wheel "langchain-core" "$LANGCHAIN_CORE_VERSION" @@ -131,6 +135,9 @@ echo "Step 3: Building and copying stubs..." # Remove old stub copies rm -rf "$PYTHON_MODULES/xxhash" 2>/dev/null || true rm -rf "$PYTHON_MODULES/ormsgpack" 2>/dev/null || true +rm -rf "$PYTHON_MODULES/orjson" "$PYTHON_MODULES/orjson-"*.dist-info 2>/dev/null || true +rm -rf "$PYTHON_MODULES/uuid_utils" "$PYTHON_MODULES/uuid_utils-"*.dist-info 2>/dev/null || true +rm -rf "$PYTHON_MODULES/websockets" "$PYTHON_MODULES/websockets-"*.dist-info 2>/dev/null || true build_stub "xxhash" build_stub "ormsgpack" diff --git a/libs/langchain-cloudflare/examples/workers/src/entry.py b/libs/langchain-cloudflare/examples/workers/src/entry.py index b0b16bb..0d4a869 100644 --- a/libs/langchain-cloudflare/examples/workers/src/entry.py +++ b/libs/langchain-cloudflare/examples/workers/src/entry.py @@ -677,7 +677,7 @@ async def handle_agent_structured_output(self, request): """Handle create_agent with structured output.""" if not CREATE_AGENT_AVAILABLE: return Response.json( - {"error": "create_agent is not available. Install langchain>=0.3.0"}, + {"error": "create_agent is not available. Install langchain>=1.0.0"}, status=501, ) @@ -815,7 +815,7 @@ async def handle_agent_tools(self, request): """Handle create_agent with tools.""" if not CREATE_AGENT_AVAILABLE: return Response.json( - {"error": "create_agent is not available. Install langchain>=0.3.0"}, + {"error": "create_agent is not available. Install langchain>=1.0.0"}, status=501, ) diff --git a/libs/langchain-cloudflare/tests/integration_tests/test_worker_integration.py b/libs/langchain-cloudflare/tests/integration_tests/test_worker_integration.py index fff7287..8bda860 100644 --- a/libs/langchain-cloudflare/tests/integration_tests/test_worker_integration.py +++ b/libs/langchain-cloudflare/tests/integration_tests/test_worker_integration.py @@ -302,12 +302,7 @@ def test_multi_turn_conversation(self, dev_server, model): class TestWorkerAgentStructuredOutput: - """Test create_agent with structured output endpoint. - - Note: These tests will fail with 501 if create_agent is not available in the - Pyodide environment due to the uuid-utils dependency in langsmith. - See .claude/create_agent_pyodide_issue.md for details. - """ + """Test create_agent with structured output endpoint.""" @pytest.mark.parametrize("model", MODELS) def test_agent_structured_output(self, dev_server, model): @@ -319,9 +314,6 @@ def test_agent_structured_output(self, dev_server, model): headers={"Content-Type": "application/json"}, ) - if response.status_code == 501: - pytest.skip("create_agent unavailable (uuid-utils not in Pyodide)") - assert response.status_code == 200, ( f"Expected 200, got {response.status_code}. Response: {response.text}" ) @@ -352,9 +344,6 @@ def test_agent_structured_json_schema(self, dev_server, model): headers={"Content-Type": "application/json"}, ) - if response.status_code == 501: - pytest.skip("create_agent or ToolStrategy unavailable in Pyodide") - assert response.status_code == 200, ( f"Expected 200, got {response.status_code}. Response: {response.text}" ) @@ -369,12 +358,7 @@ def test_agent_structured_json_schema(self, dev_server, model): class TestWorkerAgentTools: - """Test create_agent with tools endpoint. - - Note: These tests will fail with 501 if create_agent is not available in the - Pyodide environment due to the uuid-utils dependency in langsmith. - See .claude/create_agent_pyodide_issue.md for details. - """ + """Test create_agent with tools endpoint.""" @pytest.mark.parametrize("model", MODELS) def test_agent_tools(self, dev_server, model): @@ -386,9 +370,6 @@ def test_agent_tools(self, dev_server, model): headers={"Content-Type": "application/json"}, ) - if response.status_code == 501: - pytest.skip("create_agent unavailable (uuid-utils not in Pyodide)") - assert response.status_code == 200, ( f"Expected 200, got {response.status_code}. Response: {response.text}" )