Implement as langchain codeinterpreter sandbox provider#318
Implement as langchain codeinterpreter sandbox provider#318FAUST-BENCHOU wants to merge 5 commits into
Conversation
Signed-off-by: zhoujinyu <2319109590@qq.com>
Signed-off-by: zhoujinyu <2319109590@qq.com>
Signed-off-by: zhoujinyu <2319109590@qq.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 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 |
There was a problem hiding this comment.
Code Review
This pull request introduces a LangChain integration for AgentCube, implementing a BaseSandbox backend for Deep Agents along with supporting examples and E2E tests. The core SDK is updated with a new execute_command_result method to handle command execution without raising exceptions on non-zero exit codes. Review feedback suggests avoiding hardcoded model versions in examples, refining output formatting when stdout is empty, ensuring robust handling of potential null values for exit codes, and maintaining consistent type hints across the SDK.
| from langchain_anthropic import ChatAnthropic | ||
|
|
||
| return ChatAnthropic( | ||
| model=os.environ.get("ANTHROPIC_MODEL", "claude-haiku-4-5-20251001"), |
There was a problem hiding this comment.
Hardcoding a specific dated model version like claude-haiku-4-5-20251001 as a default can lead to maintenance issues when the model is deprecated or updated. Consider using a more stable alias (e.g., claude-3-5-haiku-latest) or requiring the user to provide the model via environment variables without a hardcoded default.
| out = r.get("stdout") or "" | ||
| stderr = (r.get("stderr") or "").strip() | ||
| if stderr: | ||
| out += f"\n<stderr>{stderr}</stderr>" |
There was a problem hiding this comment.
Appending stderr with a leading newline can result in unexpected output formatting if stdout is empty (the result will start with a newline). Consider checking if out is empty before adding the newline.
| out += f"\n<stderr>{stderr}</stderr>" | |
| out = f"{out}\n<stderr>{stderr}</stderr>" if out else f"<stderr>{stderr}</stderr>" |
| return { | ||
| "stdout": result.get("stdout") or "", | ||
| "stderr": result.get("stderr") or "", | ||
| "exit_code": int(result.get("exit_code", -1)), |
There was a problem hiding this comment.
The use of result.get("exit_code", -1) will return None if the key "exit_code" exists in the response but its value is null. Passing None to int() will raise a TypeError. It is safer to handle the None case explicitly to avoid potential crashes if the API returns a null exit code.
| "exit_code": int(result.get("exit_code", -1)), | |
| "exit_code": int(result.get("exit_code") if result.get("exit_code") is not None else -1), |
| return self.dp_client.execute_command(command, timeout) | ||
|
|
||
| def execute_command_result( | ||
| self, command: str, timeout: Optional[float] = None |
There was a problem hiding this comment.
The type hint for command should be updated to str | list[str] to be consistent with the underlying CodeInterpreterDataPlaneClient.execute_command_result method which accepts both types. This ensures better type safety and documentation for users of the SDK.
| self, command: str, timeout: Optional[float] = None | |
| self, command: str | list[str], timeout: Optional[float] = None |
There was a problem hiding this comment.
Pull request overview
This PR adds a LangChain Deep Agents sandbox backend for AgentCube’s Code Interpreter by introducing a new langchain-agentcube integration package and extending the Python SDK with a non-raising command execution API that the sandbox can use.
Changes:
- Added
langchain-agentcubeintegration implementingAgentcubeSandbox(Deep AgentsBaseSandbox) with execute + file upload/download support. - Extended the Python SDK with
execute_command_result()to return{stdout, stderr, exit_code}without raising on non-zero exit codes. - Wired the new integration into E2E runs (new E2E test + install step) and ensured CI sets up Python 3.11.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/e2e/test_langchain_agentcube_sandbox.py | New E2E coverage for the Deep Agents sandbox adapter against live Router/WM. |
| test/e2e/run_e2e.sh | Installs the new integration and runs the new LangChain sandbox E2E test. |
| sdk-python/agentcube/code_interpreter.py | Exposes execute_command_result() on the high-level client. |
| sdk-python/agentcube/clients/code_interpreter_data_plane.py | Implements execute_command_result() and refactors execute_command() to use it. |
| integrations/langchain-agentcube/README.md | Usage docs for the new integration and example script. |
| integrations/langchain-agentcube/pyproject.toml | New Python package metadata/deps for the integration. |
| integrations/langchain-agentcube/langchain_agentcube/sandbox.py | Implements AgentcubeSandbox (execute + upload/download) on top of the SDK client. |
| integrations/langchain-agentcube/langchain_agentcube/init.py | Exports AgentcubeSandbox. |
| integrations/langchain-agentcube/example/deep_agent_sandbox.py | Example of using create_deep_agent(..., backend=AgentcubeSandbox(...)). |
| .github/workflows/e2e.yml | Ensures Python 3.11 is available for E2E runs. |
| verbose=True, | ||
| ) as client: | ||
| backend = AgentcubeSandbox(client=client) | ||
| self.assertTrue(backend.id) |
|
|
||
| def _normalize_remote_path(path: str) -> str: | ||
| """Map paths from Deep Agents (often absolute) to session workspace-relative paths.""" | ||
| return path.replace("\\", "/").strip().lstrip("/") |
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #318 +/- ##
==========================================
+ Coverage 47.57% 47.74% +0.17%
==========================================
Files 30 30
Lines 2819 2855 +36
==========================================
+ Hits 1341 1363 +22
- Misses 1338 1344 +6
- Partials 140 148 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
record for result
|
|
It's unclear why Deepseek keeps getting hung up on the path issue and insists on using absolute paths (which would definitely fail due to the existence of picod). However, LangChain itself is functioning correctly, and Deepagent can plan normally. |
|
/cc @hzxuzhonghu @acsoto |
Signed-off-by: zhoujinyu <2319109590@qq.com>
What does this mean? While deepagent works well |
There was a problem hiding this comment.
I am thinking about contributing to upstream lang chain organization if possible
There was a problem hiding this comment.
about what. The agentcube Code Interpreter?
There was a problem hiding this comment.
This implement, you can see aws agentcore is there.
|
Ah, you mean it cannot find |
exactly,The model interprets "hello.py in the working directory" as /hello.py (disk root), while the actual file is located in {working directory}/hello.py (e.g., /root/hello.py). |
it creats lots of hello.py in different places |
|
at last it give up creating file in workspace and run |
|
Seems the client want to upload the file in |
What type of PR is this?
What this PR does / why we need it:
Which issue(s) this PR fixes:
Fixes #278
Special notes for your reviewer:
Does this PR introduce a user-facing change?: