Conversation
langchain_quickjs.CodeInterpreterMiddleware hosts its QuickJS VM on a dedicated thread and wakes the caller through call_soon_threadsafe, which the deterministic workflow loop cannot service: an unmodified eval parked the workflow forever with no failure and no deadlock report. The plugin's run context now makes quickjs_rs's worker hops inline while in a workflow (inert elsewhere, a no-op when quickjs-rs is absent) and passes the interpreter's modules through the sandbox. JavaScript is then workflow code, a task() sub-agent runs in-workflow with its own invoke_model activities, and a PTC tool follows its own tool_as_activity wrapping. Verified end to end with replay, also under cache eviction. langchain-quickjs stays optional; it is only a dev dependency for the tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TLDR: Makes Deep Agents' QuickJS code interpreter (
langchain-quickjs) work underDeepAgentsPlugin, with sub-agents dispatched from JavaScript getting their owndeepagents.invoke_modelActivities. Stacked on #1873 (deepagents 0.7 bump), whichlangchain-quickjsrequires.langchain-quickjsstays optional — nothing is imported unless the workflow imports it.Why two pieces
Sandbox passthrough alone would make things worse: today the sandbox fails loudly at middleware construction (
threading.Lockrestricted); with passthrough but no executor change the workflow hangs silently after the first model call. The middleware hosts its VM on a dedicated thread and wakes the caller viacall_soon_threadsafe, which the deterministic workflow loop cannot service and which never runs outside an activation. So this PR ships both:_quickjs.py) — whileworkflow.in_workflow(),quickjs_rs.threading.ThreadWorker'srun_sync/run_asyncrun the coroutine on the calling loop and no thread is started. Outside workflows upstream behavior is untouched; whenquickjs_rsisn't installed the patch is a no-op. Installed/uninstalled with the plugin's other seams inrun_context.langchain_quickjs,quickjs_rs,wasmtime,bsdiff4— a name-only allowlist checked at import time, so it costs nothing for users who don't use the interpreter.What you get
JavaScript runs as workflow code and replays;
task(...)from JavaScript dispatches the sub-agent in-workflow (model calls →invoke_modelActivities); PTCtools.<name>(...)follows the tool's own wrapping (tool_as_activity→invoke_toolActivity). README documents the rules for the JavaScript (noDate.now()/Math.random()— both verified nondeterministic in the VM; generous wall-clocktimeout; prefermode="turn"sincemode="thread"snapshots aren't carried across continue-as-new).Verification
tests/contrib/deepagents/test_quickjs_interpreter.py: one eval that calls a PTC tool and then atask()sub-agent →invoke_model == 3,invoke_tool == 1, result carries the sub-agent's answer, history replays deterministically — under the default sandbox, and again withmax_cached_workflows=0. Plus a test that the patch is inert outside workflows.langchain-quickjsadded to the dev group only (0.3.5 is the newest inside the two-weekexclude-newerwindow).Not in this PR (follow-ups)
Determinism guards inside the VM (host functions for
Date.now/Math.randombacked by workflow time/random), and an upstream ask to LangChain for an executor hook so theThreadWorkerpatch can go away.