feat(langchain): add LangChain DeepAgents backend adapter#310
feat(langchain): add LangChain DeepAgents backend adapter#310johannhartmann wants to merge 12 commits intokubernetes-sigs:mainfrom
Conversation
✅ Deploy Preview for agent-sandbox canceled.
|
|
|
Welcome @johannhartmann! |
|
Hi @johannhartmann. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
/ok-to-test |
|
|
||
| ## Architecture | ||
|
|
||
| ``` |
There was a problem hiding this comment.
FYI - in case you find it cumbersome to maintain this diagram, GitHub supports mermaid diagrams via ```mermaid: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-diagrams#creating-mermaid-diagrams
| @@ -0,0 +1,59 @@ | |||
| # Copyright 2025 The Kubernetes Authors. | |||
There was a problem hiding this comment.
nit: 2026 (and other places too!)
| # Copyright 2025 The Kubernetes Authors. | |
| # Copyright 2026 The Kubernetes Authors. |
| # SandboxTemplate for LangChain DeepAgents | ||
| # This template defines the container image and resources for sandbox pods. | ||
| --- | ||
| apiVersion: agents.x-k8s.io/v1alpha1 |
There was a problem hiding this comment.
The API group for SandboxTemplate should be:
| apiVersion: agents.x-k8s.io/v1alpha1 | |
| apiVersion: extensions.agents.x-k8s.io/v1alpha1 |
| if self._custom_claim_name: | ||
| self.claim_name = self._custom_claim_name | ||
| # Check if the claim already exists | ||
| if self._claim_exists(self.claim_name): |
There was a problem hiding this comment.
Before reconnecting, should it verify that the existing claim was created from the same template_name? Otherwise, it might be surprising.
| raise | ||
|
|
||
| @trace_span("create_claim") | ||
| def _create_claim(self, trace_context_str: str = ""): |
There was a problem hiding this comment.
Perhaps this needs to be renamed, given that it supports reconnecting as well (something like _setup_claim perhaps?) Reminder to update trace_span as well.
|
|
||
| logging.info(f"Explicitly deleting SandboxClaim: {self.claim_name}") | ||
| try: | ||
| self.custom_objects_api.delete_namespaced_custom_object( |
There was a problem hiding this comment.
We should clear self.claim_name as well, so that we don't attempt to delete the same claim again (will result in 404)
| secured = SandboxPolicyWrapper( | ||
| backend, | ||
| deny_prefixes=["/etc", "/sys", "/proc"], | ||
| deny_commands=["rm -rf", "curl", "wget"], |
There was a problem hiding this comment.
This can be bypassed by variations like rm -r -f or using aliases. Suggest adding a warning in the doc that this is a best-effort guardrail and not a substitute for kernel-level isolation (like gVisor).
| # Wrap with security policies | ||
| secured = SandboxPolicyWrapper( | ||
| backend, | ||
| deny_prefixes=["/etc", "/sys", "/proc"], |
There was a problem hiding this comment.
A malicious agent could bypass /etc using a path like /app/../etc. Does SandboxPolicyWrapper use something like os.path.abspath() or os.path.realpath()?
|
@johannhartmann thanks for the PR! Reminder to sign the CLA following #310 (comment) |
…upport Add claim_name parameter for SandboxClaim-based provisioning, delete_on_exit parameter for automatic cleanup, connect() classmethod for reconnecting to existing sandboxes, delete() method for explicit teardown, and was_reconnected property for detecting reconnection state.
Implement BackendProtocol from langchain-deepagents providing sandbox lifecycle management, file I/O, and code execution. Includes factory pattern with SandboxBackendFactory, configurable cleanup policies, and warm pool support via SandboxClaim integration. Comprehensive test suite covers backend lifecycle, file operations, and policy configurations.
Add end-to-end test for the LangChain DeepAgents backend running against a kind cluster with sandbox templates and warm pools.
Add example application demonstrating the LangChain DeepAgents backend with sandbox templates, skills support, and a kind cluster test script.
ls -a -p on Linux outputs ./ and ../ with trailing slashes, but the filter only checked for . and .. (without slash), letting dot entries leak into results. Also handles empty lines from trailing newlines.
… root_dir=/
- AgentSandboxBackend now inherits from SandboxBackendProtocol so
isinstance checks in DeepAgents FilesystemMiddleware pass without
needing ABC.register().
- Fix _to_internal path validation when root_dir='/': the check
startswith(root_dir + '/') became startswith('//') which rejected
every valid absolute path. Now handles the root case separately.
f202be6 to
f7f6921
Compare
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: johannhartmann The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
From the test failure |
|
@johannhartmann: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
What This Does
This adds a LangChain DeepAgents backend implementation that uses agent-sandbox for isolated code execution. It lets LangChain agents spin up Sandboxes on the fly to run code, read/write files, and clean up after themselves.
We've been using this at Mayflower to run LangChain agents on our clusters and wanted to contribute it back upstream.
Changes
1.
SandboxClientenhancements (clients/python/agentic-sandbox-client/)claim_nameparameter for SandboxClaim-based provisioning (warm pool support)delete_on_exitparameter for automatic cleanupconnect()classmethod for reconnecting to existing sandboxesdelete()method andwas_reconnectedproperty2. New
langchain-agent-sandboxpackage (clients/python/langchain-agent-sandbox/)BackendProtocolfrom langchain-deepagentsSandboxBackendFactoryfor multi-agent use3. Example application (
examples/langchain-deepagents/)4. E2E test (
test/e2e/clients/python/)How to Test
Notes
langchain-deepagentspackage from LangChain