Native runtime and DeepAgents
Choose supported LangChain packages, expose middleware state safely, and add DeepAgents capabilities without adapters.
RELKIT runs ordinary agents through LangChain and uses DeepAgents when you select capabilities such as subagents, skills, or memory files. There is no public conversion wrapper or application-level runtime adapter.
Use the certified package cohort
Native execution belongs to the explicit @relkit/langchain integration. Its selected SDK cohort
comes from that integration’s dependency metadata. The following setup also selects the local runtime
profiles used by the first-agent tutorial:
From this guide’s application/package root, install only its selected requirements:
bun add @langchain/core@1.2.9 @langchain/langgraph@1.4.14 @relkit/langchain@0.7.13 @relkit/local@0.7.12 langchain@1.5.10 langsmith@0.10.8
Keep these owner-specific versions and the lockfile together. Runtime SDKs belong in dependencies; build/type tooling belongs in devDependencies. Installing an adapter does not supply its optional SDK peers or enable the feature’s configuration.
Import native defineAgent, defineGraph, and persistence resources from @relkit/langchain.
Generic descriptors and public event/state contracts remain available from @relkit/app/agents.
Install the model-provider package used by the application separately. DeepAgents is required only
when a declaration selects a deep capability; AG-UI has its own independent
transport installation. Neither belongs in a tool-only MCP app.
If a deep capability is activated without that package, execution fails with
RELKIT_DEEPAGENTS_UNAVAILABLE and names the required version. Optional model, saver, store, and backend
packages remain application dependencies; a missing import fails before execution, while an incompatible
checkpointer or store fails protocol validation instead of being cast to a supported driver.
Combine native and RELKIT behavior
This agent passes a native model, native tool, real todoListMiddleware(), and RELKIT function-backed
tools through one declaration:
/** Composes the offline support model, explicit order/native tools, todo middleware and shared checkpoint/memory drivers. */
import { defineAgent } from "@relkit/langchain";
import { todoListMiddleware } from "langchain";
import { supportInput, supportOutput } from "../../../platform/schemas.js";
import lookupOrder from "../tools/lookup-order.tool.js";
import cancelOrder from "../tools/cancel-order.tool.js";
import { createCommerceModel } from "./commerce-model.js";
import { orderCheckpoints, orderMemory } from "./order-agent-persistence.js";
import { orderStatus } from "./order-native-tool.js";
const orderSupport = defineAgent({
// Inputs and final answers remain schema checked around the model call.
input: supportInput,
output: supportOutput,
model: createCommerceModel("support"),
instructions: "Answer order questions using the read-only order lookup tool.",
// Only explicitly listed application tools are available to the agent.
tools: [lookupOrder, cancelOrder, orderStatus],
middleware: [todoListMiddleware()],
checkpointer: orderCheckpoints,
store: orderMemory,
// Bound both tool use and total execution time.
limits: { maxSteps: 4, maxToolCalls: 4, timeoutMs: 60_000 },
stateProfile: "agents",
client: { public: true, state: ["todos"] },
chat: { input: "message", output: "answer" },
controls: ["steer", "follow-up", "stop", "approve"],
});
export default orderSupport;
RELKIT function tools still execute through the common function engine, including schema validation,
authorization, cancellation, tracing, approval policy, and output validation. Native tools execute through
their native contract. Unknown native output remains unknown unless the declaration supplies output
schema metadata; RELKIT does not infer a contract by running the tool.
Middleware state is private unless client.state selects a contributed key. In the example, todos is
inferred from todoListMiddleware() and becomes a precise generated status union. values remains
undefined until an authorized snapshot or state event arrives. Messages, tool calls, progress, custom
events, waiting requests, and final output remain separate client fields.
Declared custom-event and tool schemas remain exact. Opaque native extensions use an explicit dynamic
discriminator with unknown data instead of widening every known event or tool.
Add DeepAgents capabilities
Only for a declaration using deep capabilities, use this selected recipe instead of the ordinary-agent recipe. SDK installation alone does not expand the currently verified native capability boundary:
From this guide’s application/package root, install only its selected requirements:
bun add @langchain/core@1.2.9 @langchain/langgraph@1.4.14 @relkit/langchain@0.7.13 @relkit/local@0.7.12 deepagents@1.13.3 langchain@1.5.10 langsmith@0.10.8
Keep these owner-specific versions and the lockfile together. Runtime SDKs belong in dependencies; build/type tooling belongs in devDependencies. Installing an adapter does not supply its optional SDK peers or enable the feature’s configuration.
This declaration adds a subagent, skills, memory files, a RELKIT bucket backend, checkpointer, and store:
/** Delegates offline inventory checks to an inherited-model specialist using shared persistence and a private bucket workspace. */
import { defineAgent } from "@relkit/langchain";
import { supportInput, supportOutput } from "../../../platform/schemas.js";
import agentWorkspace from "../buckets/agent-workspace.bucket.js";
import lookupOrder from "../tools/lookup-order.tool.js";
import { createCommerceModel } from "./commerce-model.js";
import { orderCheckpoints, orderMemory } from "./order-agent-persistence.js";
const inventorySpecialist = defineAgent({
id: "inventory-specialist",
description: "Checks inventory delegated by the commerce assistant.",
input: supportInput,
output: supportOutput,
instructions: "COMMERCE_INVENTORY_SPECIALIST: answer the delegated inventory question.",
tools: [lookupOrder],
limits: { maxSteps: 3, maxToolCalls: 2, timeoutMs: 10_000 },
});
const orderDeep = defineAgent({
input: supportInput,
output: supportOutput,
model: createCommerceModel("deep"),
instructions: "Delegate inventory checks to the specialist and return its conclusion.",
tools: [],
subagents: [inventorySpecialist],
// Seed these paths in the workspace bucket to inject team-specific guidance.
skills: ["/skills/commerce/"],
memory: ["/AGENTS.md"],
backend: agentWorkspace,
checkpointer: orderCheckpoints,
store: orderMemory,
limits: { maxSteps: 6, maxToolCalls: 4, timeoutMs: 60_000 },
stateProfile: "agents",
client: { public: true },
chat: { input: "message", output: "answer" },
controls: ["stop"],
});
export default orderDeep;
Children inherit the parent model unless they declare one. They share the caller-supplied root thread and use isolated native checkpoint namespaces; nested scopes do not become independent business threads. Root cancellation and limits include child execution. Start an unrelated child operation with another application-owned thread ID.
RELKIT does not emulate Python-only APIs, LangSmith Agent Server, or arbitrary structured-agent message conversion. A RELKIT bucket backend implements the supported DeepAgents filesystem protocol, but Redis cache clients are not saver/store drivers and generic S3 clients are not treated as DeepAgents backends.
Understand public event semantics
One authorized, redacted event sequence feeds HTTP iteration, AG-UI SSE, WebSocket, snapshots, replay, generated clients, and Inspector. The transports do not execute the agent independently. Disconnecting an observer does not cancel execution; reconnect restores a consistent snapshot and continues after its journal cursor. A cursor gap triggers explicit snapshot recovery rather than silent event loss.
Public events preserve root, node, task, attempt, subgraph, and subagent scope where metadata is known. Raw checkpoints, commands, private middleware state, provider payloads, system prompts, credentials, hidden reasoning, and unrestricted native state never enter browser contracts.