mirror of
https://github.com/langchain-ai/deepagents.git
synced 2026-07-25 04:46:03 -04:00
f0ca89c962
Opt-in JavaScript interpreter (`js_eval`) middleware for `deepagents-code`, gated behind `--interpreter` / `[interpreter]` config. Local mode only. Install with the new `quickjs` extra. --- ## Description Wires `CodeInterpreterMiddleware` from `langchain-quickjs` into `deepagents-code` as an opt-in feature. Motivation: <https://www.langchain.com/blog/give-your-agents-an-interpreter>. The interpreter is local-mode only — subagents and remote-sandbox mode are out of scope for v1. Splitting the host between a remote sandbox (file/shell tools) and a local JS REPL defeats the point of the sandbox and confuses the trust boundary, so `enable_interpreter=True` paired with a non-`None` sandbox raises `ValueError` at agent-build time. The primary safety mechanism is the **PTC allowlist** (`settings.interpreter_ptc`), not HITL. Programmatic tool calling exposes host tools inside the REPL as `tools.*` async functions, and those calls go through the host-function bridge — they do **not** trigger `interrupt_on`. Per-`js_eval` HITL approval would be unusably noisy and would not gate PTC fan-out anyway, so `js_eval` is intentionally not in `interrupt_on`. Defaults: `ptc=False` (pure REPL); `"safe"` exposes a curated read-only preset (`read_file`, `glob`, `grep`, `task`, `web_search`, `web_fetch`); `"all"` requires `interpreter_ptc_acknowledge_unsafe=True` unless `auto_approve` is on. Enable from the CLI with `--interpreter` and optionally `--interpreter-tools safe|all|<csv>`; from `~/.deepagents/config.toml` via `[interpreter]`. Requires the `quickjs` optional extra (`langchain-quickjs>=0.1.2,<0.2.0`), declared standalone — not pulled in by `all-providers` or `all-sandboxes`. `langchain-quickjs` is imported lazily inside the conditional so `dcode -v` stays fast. _Opened collaboratively by Mason Daugherty and open-swe._ --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com> Co-authored-by: Mason Daugherty <61371264+mdrxy@users.noreply.github.com> Co-authored-by: Mason Daugherty <github@mdrxy.com> Co-authored-by: Mason Daugherty <mason@langchain.dev>
46 lines
1.8 KiB
Python
46 lines
1.8 KiB
Python
"""Stderr marker emission used by the langgraph server graph entry point.
|
|
|
|
Lives in its own module so unit tests can exercise the marker contract
|
|
without triggering `server_graph.make_graph()` at import time.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import sys
|
|
import traceback
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
STARTUP_ERROR_MARKER = "DEEPAGENTS_STARTUP_ERROR:"
|
|
"""Stderr marker the parent app scans for in `server._extract_startup_error_marker`
|
|
to upgrade an opaque "Server process exited with code N" into a one-line summary.
|
|
Format is `{STARTUP_ERROR_MARKER}{single-line message}`."""
|
|
|
|
|
|
def emit_startup_failure(exc: BaseException) -> None:
|
|
"""Report a server graph startup failure to the parent app process.
|
|
|
|
Emits two stderr outputs: the full traceback for logs/debugging, then a
|
|
single-line `{STARTUP_ERROR_MARKER}{type}: {summary}` line that
|
|
`server._extract_startup_error_marker` parses to upgrade an opaque
|
|
"Server process exited with code N" into an actionable summary.
|
|
|
|
Args:
|
|
exc: The exception raised during graph initialization.
|
|
"""
|
|
logger.critical("Failed to initialize server graph", exc_info=exc)
|
|
print( # noqa: T201 # stderr fallback — logger may not reach parent process
|
|
f"Failed to initialize server graph: {exc}\n{traceback.format_exc()}",
|
|
file=sys.stderr,
|
|
)
|
|
# Marker contract is single-line; guard against multi-line/empty `str(exc)`
|
|
# and include the type so e.g. `ValueError` and `RuntimeError` are
|
|
# distinguishable in the parent's truncated summary.
|
|
exc_lines = str(exc).splitlines()
|
|
summary = exc_lines[0] if exc_lines else "<no message>"
|
|
print( # noqa: T201
|
|
f"{STARTUP_ERROR_MARKER}{type(exc).__name__}: {summary}",
|
|
file=sys.stderr,
|
|
)
|