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:

b4.config.ts
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:

bash
b4 check
b4 build
b4 verify

The target writes .b4/build/langgraph.json and one .b4/build/<route-slug>.ts entry per discovered route. Here is a representative config:

.b4/build/langgraph.json
{
  "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.

  • authenticate runs 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 undefined can'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-written defineThreadAccess policy is refused (B4_E1005). ownedThreads compiles to owner-stamp metadata filters, so another caller's thread reads as not found. adminsRead can't be expressed, so admins read only their own threads there, and the build warns.
  • Clients create a thread with POST /threads before 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 in src/auth.ts. LangGraph copies x-* request headers into the stored run config, where the thread's owner can read them. Send a secret as authorization instead.
  • Memory scoped by user, tenant or agent. 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

  1. Confirm that every route has the expected <routeId>#<kind> entry and use it as assistant_id.
  2. Inspect the environment-file path and move actual secrets into platform-managed configuration.
  3. Add a src/auth.ts, and an ownedThreads thread policy if callers own threads, or configure authentication on the platform.
  4. Test agent materialization and raw workflow/graph/chain entries through the platform transport.
  5. Resolve the Node 22/Node 24 incompatibility with the target platform before production use.
  6. 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, env and node_version take precedence by design.
  • The platform can't find an assistant: use the full <routeId>#<kind> key from generated graphs.
  • 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: authenticate returned undefined. LangGraph has no anonymous user.
  • Local Node HTTP tests pass but platform calls fail: exercise the platform transport and its environment/build process directly.