LangSmith
Choose the LangSmith target when LangSmith, or another LangGraph deployment platform, must handle transport and execution. This target emits graph entries for the platform to run, without B4.run's HTTP server.
Select the targetCopy link to section: Select the target
B4.run emits LangSmith by default alongside Node. To emit only the platform artifact:
import { config } from "@b4run/cli"
export default config({
build: { targets: ["langsmith"] },
})Build outputCopy link to section: Build output
Run the usual validation and build flow:
b4 check
b4 build
b4 verifyThe target writes .b4/build/langgraph.json and one .b4/build/<route-slug>.ts entry per discovered route. Here is a representative config:
{
"graphs": {
"/navlog#agent": "./.b4/build/navlog.ts:graph"
},
"dependencies": ["."],
"env": ".env.example",
"node_version": "22"
}Each graph key is <routeId>#<kind>. Use the full key, such as /navlog#agent, as the platform assistant_id.
Route entry behaviorCopy link to section: Route entry behavior
Agent routes receive a generated entry that calls materializeResolvedRouteGraph. That path loads the agent descriptor and applies B4.run's agent materialization, including discovered route tools, tool scope, capabilities and permission gates.
Workflow, graph and chain routes skip agent materialization. Their generated entry imports the route's workflow, graph or chain export and re-exports it as graph.
Test every route kind you deploy on the platform itself. B4.run's HTTP scenario tests never see the platform's assistant_id request envelope.
Environment file pathCopy link to section: Environment file path
The generated env field is .env.example when that file exists at the app root, and .env otherwise. The platform build reads this path. Review the selected file before you deploy, and keep secret values in the platform's secret manager, out of Git.
Merge precedenceCopy link to section: Merge precedence
If the app root contains a hand-authored langgraph.json, B4.run shallow-merges it into the generated output. User-defined extra keys survive. The generated graphs, dependencies, env, and node_version fields overwrite user values with those names.
The merge is shallow, so a user graphs map is replaced as a whole.
AuthenticationCopy link to section: Authentication
An app's src/auth.ts compiles to LangGraph's own auth layer. The build writes .b4/build/auth.ts and sets langgraph.json auth to { "path": "./.b4/build/auth.ts:auth", "disable_studio_auth": true }. The second key stops Studio's x-auth-scheme: langsmith header from skipping authenticate.
authenticateruns once per request.reject(status, body)becomes that status. A throw is a 500.- An anonymous request is a 401. LangGraph has no anonymous user, so
undefinedcan't pass through as it does on the node target. - Tools read the caller as
ctx.principal, the same as on node. LangGraph stores the user, principal included, in each run's config, where the thread's owner can read it back. A principal must carry no secrets. - Thread access compiles only from
ownedThreads. LangGraph's handlers never see the stored thread, so a hand-writtendefineThreadAccesspolicy is refused (B4_E1005).ownedThreadscompiles to owner-stamp metadata filters, so another caller's thread reads as not found.adminsReadcan't be expressed, so admins read only their own threads there, and the build warns. - Clients create a thread with
POST /threadsbefore running on it. A run on a client-chosen id that has no row yet returns 404 under the owner filter. The node target creates and stamps the thread in that case.
The build refuses what would deploy ungated or leak:
- An
x-*header compared as a secret insrc/auth.ts. LangGraph copiesx-*request headers into the stored run config, where the thread's owner can read them. Send a secret asauthorizationinstead. - Memory scoped by
user,tenantoragent. Graphs are built once, before any request, so those dimensions can't be resolved per caller yet.
These rules were checked against the open-source langgraphjs dev server, not a hosted LangSmith deployment. Confirm both behaviors on your deployment: that Studio's header no longer bypasses authenticate, and how x-* headers are copied.
Missing B4.run surfacesCopy link to section: Missing B4.run surfaces
The generated target does not include B4.run HTTP middleware (the build warns when src/middleware.ts exists), the AG-UI server, the B4.run sandbox manager or B4.run's Agent Protocol thread-management server.
Agent routes still get policy-aware graph construction. If you need the HTTP or sandbox surfaces, deploy Node and Docker, or Edge and Hono if your app passes its capability gate.
Node version mismatchCopy link to section: Node version mismatch
The emitter currently writes node_version: "22", but B4.run packages require Node 24 or newer. As of this writing, that mismatch is unresolved. B4.run isn't known to run correctly on Node 22, so confirm the platform's supported Node versions before you deploy.
Deployment checklistCopy link to section: Deployment checklist
- Confirm that every route has the expected
<routeId>#<kind>entry and use it asassistant_id. - Inspect the environment-file path and move actual secrets into platform-managed configuration.
- Add a
src/auth.ts, and anownedThreadsthread policy if callers own threads, or configure authentication on the platform. - Test agent materialization and raw workflow/graph/chain entries through the platform transport.
- Resolve the Node 22/Node 24 incompatibility with the target platform before production use.
- Confirm that no requirement depends on B4.run HTTP middleware, AG-UI, or the sandbox manager.
TroubleshootingCopy link to section: Troubleshooting
- A user config field disappeared: generated
graphs,dependencies,envandnode_versiontake precedence by design. - The platform can't find an assistant: use the full
<routeId>#<kind>key from generatedgraphs. - HTTP middleware didn't run: these entries don't include it. Put identity in
src/auth.ts, which does run here. - Every request is a 401:
authenticatereturnedundefined. LangGraph has no anonymous user. - Local Node HTTP tests pass but platform calls fail: exercise the platform transport and its environment/build process directly.