mirror of
https://github.com/langchain-ai/docs.git
synced 2026-07-19 16:33:35 -04:00
make existing snippets testable (#4010)
This commit is contained in:
@@ -117,6 +117,7 @@ jobs:
|
||||
env:
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
POSTGRES_URI: postgresql://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable
|
||||
TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }}
|
||||
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
||||
|
||||
@@ -22,6 +22,7 @@ dependencies = [
|
||||
"langchain-google-genai>=2.0.0",
|
||||
"langchain-daytona>=0.0.5",
|
||||
"daytona>=0.100.0",
|
||||
"langchain-quickjs>=0.1.2",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// :snippet-start: backend-composite-js
|
||||
import {
|
||||
createDeepAgent,
|
||||
CompositeBackend,
|
||||
StateBackend,
|
||||
StoreBackend,
|
||||
} from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore();
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new CompositeBackend(new StateBackend(), {
|
||||
"/memories/": new StoreBackend(),
|
||||
}),
|
||||
store,
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,13 @@
|
||||
// :snippet-start: backend-filesystem-js
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,14 @@
|
||||
// :snippet-start: backend-local-shell-js
|
||||
import { createDeepAgent, LocalShellBackend } from "deepagents";
|
||||
|
||||
const backend = new LocalShellBackend({ workingDirectory: "." });
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,15 @@
|
||||
// :snippet-start: backend-state-js
|
||||
import { createDeepAgent, StateBackend } from "deepagents";
|
||||
|
||||
// By default we provide a StateBackend
|
||||
const agent = createDeepAgent();
|
||||
|
||||
// Under the hood, it looks like
|
||||
const agent2 = createDeepAgent({
|
||||
backend: new StateBackend(),
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent || !agent2) throw new Error("agents not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,18 @@
|
||||
// :snippet-start: backend-store-js
|
||||
import { createDeepAgent, StoreBackend } from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new StoreBackend({
|
||||
namespace: (ctx) => [ctx.runtime.context.userId],
|
||||
}),
|
||||
store,
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Customization: virtual filesystem backend examples."""
|
||||
|
||||
# :snippet-start: backend-state-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
|
||||
# By default we provide a StateBackend
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(model="google_genai:gemini-3.1-pro-preview")
|
||||
|
||||
# Under the hood, it looks like
|
||||
# KEEP MODEL
|
||||
agent2 = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=StateBackend(),
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :snippet-start: backend-filesystem-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import FilesystemBackend
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :snippet-start: backend-local-shell-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import LocalShellBackend
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :snippet-start: backend-store-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StoreBackend
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=StoreBackend(
|
||||
namespace=lambda ctx: (ctx.runtime.context.user_id,),
|
||||
),
|
||||
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :snippet-start: backend-context-hub-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import ContextHubBackend
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=ContextHubBackend("my-agent"),
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :snippet-start: backend-composite-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=CompositeBackend(
|
||||
default=StateBackend(),
|
||||
routes={
|
||||
"/memories/": StoreBackend(),
|
||||
},
|
||||
),
|
||||
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :remove-start:
|
||||
assert agent is not None
|
||||
assert agent2 is not None
|
||||
# :remove-end:
|
||||
@@ -0,0 +1,45 @@
|
||||
"""Customization: human-in-the-loop interrupt_on example."""
|
||||
|
||||
# :snippet-start: hitl-basic-config-py
|
||||
from langchain.tools import tool
|
||||
from deepagents import create_deep_agent
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
|
||||
@tool
|
||||
def remove_file(path: str) -> str:
|
||||
"""Delete a file from the filesystem."""
|
||||
return f"Deleted {path}"
|
||||
|
||||
|
||||
@tool
|
||||
def fetch_file(path: str) -> str:
|
||||
"""Read a file from the filesystem."""
|
||||
return f"Contents of {path}"
|
||||
|
||||
|
||||
@tool
|
||||
def notify_email(to: str, subject: str, body: str) -> str:
|
||||
"""Send an email."""
|
||||
return f"Sent email to {to}"
|
||||
|
||||
|
||||
# Checkpointer is REQUIRED for human-in-the-loop
|
||||
checkpointer = MemorySaver()
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
tools=[remove_file, fetch_file, notify_email],
|
||||
interrupt_on={
|
||||
"remove_file": True, # Default: approve, edit, reject, respond
|
||||
"fetch_file": False, # No interrupts needed
|
||||
"notify_email": {"allowed_decisions": ["approve", "reject"]}, # No editing
|
||||
},
|
||||
checkpointer=checkpointer, # Required!
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :remove-start:
|
||||
assert agent is not None
|
||||
# :remove-end:
|
||||
@@ -0,0 +1,74 @@
|
||||
// :snippet-start: hitl-basic-config-js
|
||||
import { tool } from "langchain";
|
||||
import { createDeepAgent } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
import { z } from "zod";
|
||||
|
||||
const removeFile = tool(
|
||||
async ({ path }: { path: string }) => {
|
||||
return `Deleted ${path}`;
|
||||
},
|
||||
{
|
||||
name: "remove_file",
|
||||
description: "Delete a file from the filesystem.",
|
||||
schema: z.object({
|
||||
path: z.string(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const fetchFile = tool(
|
||||
async ({ path }: { path: string }) => {
|
||||
return `Contents of ${path}`;
|
||||
},
|
||||
{
|
||||
name: "fetch_file",
|
||||
description: "Read a file from the filesystem.",
|
||||
schema: z.object({
|
||||
path: z.string(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const notifyEmail = tool(
|
||||
async ({
|
||||
to,
|
||||
subject,
|
||||
body,
|
||||
}: {
|
||||
to: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
}) => {
|
||||
return `Sent email to ${to}`;
|
||||
},
|
||||
{
|
||||
name: "notify_email",
|
||||
description: "Send an email.",
|
||||
schema: z.object({
|
||||
to: z.string(),
|
||||
subject: z.string(),
|
||||
body: z.string(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
// Checkpointer is REQUIRED for human-in-the-loop
|
||||
const checkpointer = new MemorySaver();
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
tools: [removeFile, fetchFile, notifyEmail],
|
||||
interruptOn: {
|
||||
remove_file: true, // Default: approve, edit, reject, respond
|
||||
fetch_file: false, // No interrupts needed
|
||||
notify_email: { allowedDecisions: ["approve", "reject"] }, // No editing
|
||||
},
|
||||
checkpointer, // Required!
|
||||
});
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,33 @@
|
||||
// :snippet-start: skills-usage-filesystem-js
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new FilesystemBackend({ rootDir: process.cwd() });
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
skills: ["./examples/skills/"],
|
||||
interruptOn: {
|
||||
read_file: true,
|
||||
write_file: true,
|
||||
delete_file: true,
|
||||
},
|
||||
checkpointer, // Required!
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
|
||||
const result = await agent.invoke(
|
||||
{ messages: [{ role: "user", content: "what is langraph?" }] },
|
||||
config,
|
||||
);
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
if (!result) throw new Error("result empty");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,56 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
// :snippet-start: skills-usage-state-js
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, StateBackend, type FileData } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new StateBackend();
|
||||
|
||||
// :remove-start:
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
// :remove-end:
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillsFiles: Record<string, FileData> = {};
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
|
||||
skillsFiles["/skills/langgraph-docs/SKILL.md"] = createFileData(skillContent);
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
checkpointer, // Required !
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
|
||||
const result = await agent.invoke(
|
||||
{
|
||||
messages: [{ role: "user", content: "what is langraph?" }],
|
||||
files: skillsFiles,
|
||||
},
|
||||
config,
|
||||
);
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
if (!result) throw new Error("result not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,52 @@
|
||||
// :snippet-start: skills-usage-store-js
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
|
||||
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const store = new InMemoryStore();
|
||||
const backend = new StoreBackend();
|
||||
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
const fileData = createFileData(skillContent);
|
||||
|
||||
await store.put(["filesystem"], "/skills/langgraph-docs/SKILL.md", fileData);
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
store,
|
||||
checkpointer,
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = {
|
||||
recursionLimit: 50,
|
||||
configurable: { thread_id: `thread-${Date.now()}` },
|
||||
};
|
||||
const result = await agent.invoke(
|
||||
{ messages: [{ role: "user", content: "what is langraph?" }] },
|
||||
config,
|
||||
);
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
if (!result) throw new Error("result empty");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,117 @@
|
||||
"""Customization: wiring skills with different backends."""
|
||||
|
||||
# :snippet-start: skills-usage-state-py
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="anthropic:claude-sonnet-4-6",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
# :snippet-end:
|
||||
assert result is not None
|
||||
|
||||
# :snippet-start: skills-usage-store-py
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StoreBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
store = InMemoryStore()
|
||||
backend = StoreBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
store.put(
|
||||
namespace=("filesystem",),
|
||||
key="/skills/langgraph-docs/SKILL.md",
|
||||
value=create_file_data(skill_content),
|
||||
)
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
store=store,
|
||||
skills=["/skills/"],
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)],
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "What is langgraph?"}]},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
from pathlib import Path
|
||||
# :snippet-start: skills-usage-filesystem-py
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends.filesystem import FilesystemBackend
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
# Checkpointer is REQUIRED for human-in-the-loop
|
||||
checkpointer = MemorySaver()
|
||||
root_dir = "/Users/user/{project}"
|
||||
backend = FilesystemBackend(root_dir=root_dir)
|
||||
# :remove-start:
|
||||
# Test harness: make test-code-samples runs from the repo root.
|
||||
example_dir = (Path.cwd() / "src/code-samples/deepagents").resolve()
|
||||
root_dir = str(example_dir)
|
||||
backend = FilesystemBackend(root_dir=root_dir, virtual_mode=True)
|
||||
# :remove-end:
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
skills=[str(Path(root_dir) / "skills")],
|
||||
interrupt_on={
|
||||
"write_file": True,
|
||||
"read_file": False,
|
||||
"edit_file": True,
|
||||
},
|
||||
checkpointer=checkpointer, # Required!
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "What is langgraph?"}]},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :remove-start:
|
||||
assert agent is not None
|
||||
# :remove-end:
|
||||
@@ -0,0 +1,46 @@
|
||||
"""Customization: subagent configuration example."""
|
||||
|
||||
# :snippet-start: subagent-basic-py
|
||||
import os
|
||||
from typing import Literal
|
||||
|
||||
from deepagents import create_deep_agent
|
||||
from tavily import TavilyClient
|
||||
|
||||
tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
|
||||
|
||||
|
||||
def internet_search(
|
||||
query: str,
|
||||
max_results: int = 5,
|
||||
topic: Literal["general", "news", "finance"] = "general",
|
||||
include_raw_content: bool = False,
|
||||
):
|
||||
"""Run a web search"""
|
||||
return tavily_client.search(
|
||||
query,
|
||||
max_results=max_results,
|
||||
include_raw_content=include_raw_content,
|
||||
topic=topic,
|
||||
)
|
||||
|
||||
|
||||
research_subagent = {
|
||||
"name": "research-agent",
|
||||
"description": "Used to research more in depth questions",
|
||||
"system_prompt": "You are a great researcher",
|
||||
"tools": [internet_search],
|
||||
"model": "openai:gpt-5.4", # Optional override, defaults to main agent model
|
||||
}
|
||||
subagents = [research_subagent]
|
||||
|
||||
# KEEP MODEL
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
subagents=subagents,
|
||||
)
|
||||
# :snippet-end:
|
||||
|
||||
# :remove-start:
|
||||
assert agent is not None
|
||||
# :remove-end:
|
||||
+9
-4
@@ -1,4 +1,4 @@
|
||||
```typescript
|
||||
// :snippet-start: subagent-basic-js
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
@@ -44,12 +44,17 @@ const researchSubagent: SubAgent = {
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "openai:gpt-5.4", // Optional override, defaults to main agent model
|
||||
model: "openai:gpt-5.4", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
// KEEP MODEL
|
||||
const agent = createDeepAgent({
|
||||
model: "claude-sonnet-4-6",
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
// :snippet-end:
|
||||
|
||||
// :remove-start:
|
||||
if (!agent) throw new Error("agent not created");
|
||||
// :remove-end:
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: langgraph-docs
|
||||
description: Fetches and references LangGraph Python documentation to build stateful agents, create multi-agent workflows, and implement human-in-the-loop patterns. Use when the user asks about LangGraph, graph agents, state machines, agent orchestration, LangGraph API, or needs LangGraph implementation guidance.
|
||||
---
|
||||
|
||||
# langgraph-docs
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Fetch the Documentation Index
|
||||
|
||||
Use `fetch_url` to read: https://docs.langchain.com/llms.txt
|
||||
|
||||
This returns a structured list of all available documentation with descriptions.
|
||||
|
||||
### 2. Select Relevant Documentation
|
||||
|
||||
Identify 2-4 most relevant URLs from the index. Prioritize:
|
||||
- **Implementation questions** — specific how-to guides
|
||||
- **Conceptual questions** — core concept pages
|
||||
- **End-to-end examples** — tutorials
|
||||
- **API details** — reference docs
|
||||
|
||||
### 3. Fetch and Apply
|
||||
|
||||
Use `fetch_url` on the selected URLs, then complete the user's request using the documentation content.
|
||||
|
||||
If `fetch_url` fails or returns empty content, retry once. If it fails again, inform the user and suggest checking https://langchain-ai.github.io/langgraph/ directly.
|
||||
Generated
+35
@@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^1.3.22",
|
||||
"@langchain/daytona": "^0.2.0",
|
||||
"@langchain/google-genai": "^2.1.30",
|
||||
"@langchain/langgraph-checkpoint-postgres": "^1.0.1",
|
||||
"@langchain/openai": "^1.2.12",
|
||||
"@langchain/quickjs": "^0.4.0",
|
||||
@@ -268,6 +269,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1032.0.tgz",
|
||||
"integrity": "sha512-A1wjVhV3IgsZ5td2l4AWgK03EjZ+ldwbiorxuO1hPf7RHJtSdr6oq/gKzyUwP7Tm7ma/M2xS/tplg5C8XB8RWg==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha1-browser": "5.2.0",
|
||||
"@aws-crypto/sha256-browser": "5.2.0",
|
||||
@@ -1440,6 +1442,15 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@google/generative-ai": {
|
||||
"version": "0.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
|
||||
"integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@grpc/grpc-js": {
|
||||
"version": "1.14.3",
|
||||
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz",
|
||||
@@ -1583,6 +1594,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.46.tgz",
|
||||
"integrity": "sha512-i8rDC83BpItxChCw4Lf+6tAr+k+OUcbirc5ZkrhI9ywYWmvxegUljLGOGYvtJNTbEAIFkhYIODPE5QRqyjF6sA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@cfworker/json-schema": "^4.0.2",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
@@ -1608,6 +1620,21 @@
|
||||
"deepagents": ">=1.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/google-genai": {
|
||||
"version": "2.1.30",
|
||||
"resolved": "https://registry.npmjs.org/@langchain/google-genai/-/google-genai-2.1.30.tgz",
|
||||
"integrity": "sha512-0wKgy1NvV89fw5MwYiOOhh18SnUEH20z6MZrPV6Tj2hMAA3jAHVSLlIcCQ2mDRJo2r1aHLV8MDXhzkvD1tEHoQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@google/generative-ai": "^0.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^1.1.43"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@langchain/langgraph/-/langgraph-1.3.0.tgz",
|
||||
@@ -1639,6 +1666,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-1.0.2.tgz",
|
||||
"integrity": "sha512-F4E5Tr0nt8FGghgdscJtHw+ABzChOHeI80R7Y1pjIHdiJom6c2ieo76vL+FWiny80JmoGqhrVAEIWrw0cXKPxg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
@@ -1869,6 +1897,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
|
||||
"integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
@@ -3372,6 +3401,7 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -3587,6 +3617,7 @@
|
||||
"resolved": "https://registry.npmjs.org/deepagents/-/deepagents-1.10.2.tgz",
|
||||
"integrity": "sha512-Ptp+t/FgIvMhDbVK0ml3IHcNx3gog3Cbqx+s88H4Hz8ieHG7svuR+/4Mawc/g14FY7mCls7Y8gCcrGb0i3Mi4w==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@langchain/core": "^1.1.44",
|
||||
"@langchain/langgraph": "^1.3.0",
|
||||
@@ -4235,6 +4266,7 @@
|
||||
"resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.6.3.tgz",
|
||||
"integrity": "sha512-pXrQ4/4myQvjFFOAUmt5pWRrLEZR20gzIJD7MNdUH+5/S5nLI4ZRBo/SYKC6coaYj9pYTfQdBIzcs+3kfJ5uDA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"p-queue": "6.6.2"
|
||||
},
|
||||
@@ -4501,6 +4533,7 @@
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz",
|
||||
"integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pg-connection-string": "^2.12.0",
|
||||
"pg-pool": "^3.13.0",
|
||||
@@ -4968,6 +5001,7 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -5187,6 +5221,7 @@
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@langchain/anthropic": "^1.3.22",
|
||||
"@langchain/daytona": "^0.2.0",
|
||||
"@langchain/google-genai": "^2.1.30",
|
||||
"@langchain/langgraph-checkpoint-postgres": "^1.0.1",
|
||||
"@langchain/openai": "^1.2.12",
|
||||
"@langchain/quickjs": "^0.4.0",
|
||||
|
||||
@@ -3,17 +3,17 @@ title: Backends
|
||||
description: Choose and configure filesystem backends for Deep Agents. You can specify routes to different backends, implement virtual filesystems, and enforce policies.
|
||||
---
|
||||
|
||||
import BackendStatePy from '/snippets/backend-state-py.mdx';
|
||||
import BackendStateJs from '/snippets/backend-state-js.mdx';
|
||||
import BackendFilesystemPy from '/snippets/backend-filesystem-py.mdx';
|
||||
import BackendFilesystemJs from '/snippets/backend-filesystem-js.mdx';
|
||||
import BackendLocalShellPy from '/snippets/backend-local-shell-py.mdx';
|
||||
import BackendLocalShellJs from '/snippets/backend-local-shell-js.mdx';
|
||||
import BackendStorePy from '/snippets/backend-store-py.mdx';
|
||||
import BackendStoreJs from '/snippets/backend-store-js.mdx';
|
||||
import BackendContextHubPy from '/snippets/backend-context-hub-py.mdx';
|
||||
import BackendCompositePy from '/snippets/backend-composite-py.mdx';
|
||||
import BackendCompositeJs from '/snippets/backend-composite-js.mdx';
|
||||
import BackendStatePy from '/snippets/code-samples/backend-state-py.mdx';
|
||||
import BackendStateJs from '/snippets/code-samples/backend-state-js.mdx';
|
||||
import BackendFilesystemPy from '/snippets/code-samples/backend-filesystem-py.mdx';
|
||||
import BackendFilesystemJs from '/snippets/code-samples/backend-filesystem-js.mdx';
|
||||
import BackendLocalShellPy from '/snippets/code-samples/backend-local-shell-py.mdx';
|
||||
import BackendLocalShellJs from '/snippets/code-samples/backend-local-shell-js.mdx';
|
||||
import BackendStorePy from '/snippets/code-samples/backend-store-py.mdx';
|
||||
import BackendStoreJs from '/snippets/code-samples/backend-store-js.mdx';
|
||||
import BackendContextHubPy from '/snippets/code-samples/backend-context-hub-py.mdx';
|
||||
import BackendCompositePy from '/snippets/code-samples/backend-composite-py.mdx';
|
||||
import BackendCompositeJs from '/snippets/code-samples/backend-composite-js.mdx';
|
||||
|
||||
Deep Agents expose a filesystem surface to the agent via tools like `ls`, `read_file`, `write_file`, `edit_file`, `glob`, and `grep`. These tools operate through a pluggable backend. The `read_file` tool natively supports image files (`.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`) across all backends, returning them as multimodal content blocks.
|
||||
|
||||
@@ -218,6 +218,10 @@ Use with extreme caution and only in appropriate environments.
|
||||
<BackendStoreJs />
|
||||
:::
|
||||
|
||||
<Note>
|
||||
When deploying to [LangSmith Deployment](/langsmith/deployment), omit the `store` parameter. The platform automatically provisions a store for your agent.
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
The `namespace` parameter controls data isolation. For multi-user deployments, always set a [namespace factory](/oss/deepagents/backends#namespace-factories) to isolate data per user or tenant.
|
||||
</Tip>
|
||||
|
||||
@@ -6,23 +6,23 @@ description: Learn how to customize Deep Agents with system prompts, tools, suba
|
||||
|
||||
import ChatModelTabsDaPy from '/snippets/chat-model-tabs-da.mdx';
|
||||
import ChatModelTabsDaJs from '/snippets/chat-model-tabs-da-js.mdx';
|
||||
import HitlBasicConfigPy from '/snippets/hitl-basic-config-py.mdx';
|
||||
import HitlBasicConfigJs from '/snippets/hitl-basic-config-js.mdx';
|
||||
import HitlBasicConfigPy from '/snippets/code-samples/hitl-basic-config-py.mdx';
|
||||
import HitlBasicConfigJs from '/snippets/code-samples/hitl-basic-config-js.mdx';
|
||||
import SkillsUsageTabsPy from '/snippets/skills-usage-tabs-py.mdx';
|
||||
import SkillsUsageTabsJs from '/snippets/skills-usage-tabs-js.mdx';
|
||||
import BackendStatePy from '/snippets/backend-state-py.mdx';
|
||||
import BackendStateJs from '/snippets/backend-state-js.mdx';
|
||||
import BackendFilesystemPy from '/snippets/backend-filesystem-py.mdx';
|
||||
import BackendFilesystemJs from '/snippets/backend-filesystem-js.mdx';
|
||||
import BackendLocalShellPy from '/snippets/backend-local-shell-py.mdx';
|
||||
import BackendLocalShellJs from '/snippets/backend-local-shell-js.mdx';
|
||||
import BackendStorePy from '/snippets/backend-store-py.mdx';
|
||||
import BackendStoreJs from '/snippets/backend-store-js.mdx';
|
||||
import BackendContextHubPy from '/snippets/backend-context-hub-py.mdx';
|
||||
import BackendCompositePy from '/snippets/backend-composite-py.mdx';
|
||||
import BackendCompositeJs from '/snippets/backend-composite-js.mdx';
|
||||
import SubagentBasicPy from '/snippets/subagent-basic-py.mdx';
|
||||
import SubagentBasicJs from '/snippets/subagent-basic-js.mdx';
|
||||
import BackendStatePy from '/snippets/code-samples/backend-state-py.mdx';
|
||||
import BackendStateJs from '/snippets/code-samples/backend-state-js.mdx';
|
||||
import BackendFilesystemPy from '/snippets/code-samples/backend-filesystem-py.mdx';
|
||||
import BackendFilesystemJs from '/snippets/code-samples/backend-filesystem-js.mdx';
|
||||
import BackendLocalShellPy from '/snippets/code-samples/backend-local-shell-py.mdx';
|
||||
import BackendLocalShellJs from '/snippets/code-samples/backend-local-shell-js.mdx';
|
||||
import BackendStorePy from '/snippets/code-samples/backend-store-py.mdx';
|
||||
import BackendStoreJs from '/snippets/code-samples/backend-store-js.mdx';
|
||||
import BackendContextHubPy from '/snippets/code-samples/backend-context-hub-py.mdx';
|
||||
import BackendCompositePy from '/snippets/code-samples/backend-composite-py.mdx';
|
||||
import BackendCompositeJs from '/snippets/code-samples/backend-composite-js.mdx';
|
||||
import SubagentBasicPy from '/snippets/code-samples/subagent-basic-py.mdx';
|
||||
import SubagentBasicJs from '/snippets/code-samples/subagent-basic-js.mdx';
|
||||
import SandboxBasicPy from '/snippets/deepagents-sandbox-basic-py.mdx';
|
||||
import SandboxBasicJs from '/snippets/deepagents-sandbox-basic-js.mdx';
|
||||
import CreateDeepAgentConfigOptionsPy from '/snippets/create-deep-agent-config-options-py.mdx';
|
||||
@@ -406,6 +406,10 @@ If you are using [skills](#skills) or [memory](#memory), you must add the expect
|
||||
<BackendStoreJs />
|
||||
:::
|
||||
|
||||
<Note>
|
||||
When deploying to [LangSmith Deployment](/langsmith/deployment), omit the `store` parameter. The platform automatically provisions a store for your agent.
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
The `namespace` parameter controls data isolation. For multi-user deployments, always set a [namespace factory](/oss/deepagents/backends#namespace-factories) to isolate data per user or tenant.
|
||||
</Tip>
|
||||
|
||||
@@ -3,8 +3,8 @@ title: Human-in-the-loop
|
||||
description: Learn how to configure human approval for sensitive tool operations
|
||||
---
|
||||
|
||||
import HitlBasicConfigPy from '/snippets/hitl-basic-config-py.mdx';
|
||||
import HitlBasicConfigJs from '/snippets/hitl-basic-config-js.mdx';
|
||||
import HitlBasicConfigPy from '/snippets/code-samples/hitl-basic-config-py.mdx';
|
||||
import HitlBasicConfigJs from '/snippets/code-samples/hitl-basic-config-js.mdx';
|
||||
|
||||
Some tool operations may be sensitive and require human approval before execution. Deep Agents support human-in-the-loop workflows through LangGraph's interrupt capabilities. You can configure which tools require approval using the `interrupt_on` parameter.
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ title: Subagents
|
||||
description: Learn how to use subagents to delegate work and keep context clean
|
||||
---
|
||||
|
||||
import SubagentBasicPy from '/snippets/subagent-basic-py.mdx';
|
||||
import SubagentBasicJs from '/snippets/subagent-basic-js.mdx';
|
||||
import SubagentBasicPy from '/snippets/code-samples/subagent-basic-py.mdx';
|
||||
import SubagentBasicJs from '/snippets/code-samples/subagent-basic-js.mdx';
|
||||
|
||||
A deep agent can create subagents to delegate work. You can specify custom subagents in the `subagents` parameter. Subagents are useful for [context quarantine](https://www.dbreunig.com/2025/06/26/how-to-fix-your-context.html#context-quarantine) (keeping the main agent's context clean) and for providing specialized instructions.
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
```typescript
|
||||
import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore();
|
||||
const agent = createDeepAgent({
|
||||
backend: new CompositeBackend(
|
||||
new StateBackend(),
|
||||
{
|
||||
"/memories/": new StoreBackend(),
|
||||
}
|
||||
),
|
||||
store,
|
||||
});
|
||||
```
|
||||
@@ -1,16 +0,0 @@
|
||||
```typescript
|
||||
import { createDeepAgent, StoreBackend } from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
|
||||
const agent = createDeepAgent({
|
||||
backend: new StoreBackend({
|
||||
namespace: (ctx) => [ctx.runtime.context.userId],
|
||||
}),
|
||||
store
|
||||
});
|
||||
```
|
||||
|
||||
<Note>
|
||||
When deploying to [LangSmith Deployment](/langsmith/deployment), omit the `store` parameter. The platform automatically provisions a store for your agent.
|
||||
</Note>
|
||||
@@ -0,0 +1,18 @@
|
||||
```ts
|
||||
import {
|
||||
createDeepAgent,
|
||||
CompositeBackend,
|
||||
StateBackend,
|
||||
StoreBackend,
|
||||
} from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore();
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new CompositeBackend(new StateBackend(), {
|
||||
"/memories/": new StoreBackend(),
|
||||
}),
|
||||
store,
|
||||
});
|
||||
```
|
||||
+2
-2
@@ -9,8 +9,8 @@ agent = create_deep_agent(
|
||||
default=StateBackend(),
|
||||
routes={
|
||||
"/memories/": StoreBackend(),
|
||||
}
|
||||
},
|
||||
),
|
||||
store=InMemoryStore() # Store passed to create_deep_agent, not backend
|
||||
store=InMemoryStore(), # Store passed to create_deep_agent, not backend
|
||||
)
|
||||
```
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import ContextHubBackend
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=ContextHubBackend("my-agent")
|
||||
backend=ContextHubBackend("my-agent"),
|
||||
)
|
||||
```
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
```typescript
|
||||
```ts
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
|
||||
});
|
||||
```
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import FilesystemBackend
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=FilesystemBackend(root_dir=".", virtual_mode=True)
|
||||
backend=FilesystemBackend(root_dir=".", virtual_mode=True),
|
||||
)
|
||||
```
|
||||
+5
-2
@@ -1,6 +1,9 @@
|
||||
```typescript
|
||||
```ts
|
||||
import { createDeepAgent, LocalShellBackend } from "deepagents";
|
||||
|
||||
const backend = new LocalShellBackend({ workingDirectory: "." });
|
||||
const agent = createDeepAgent({ backend });
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
});
|
||||
```
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import LocalShellBackend
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=LocalShellBackend(root_dir=".", env={"PATH": "/usr/bin:/bin"})
|
||||
backend=LocalShellBackend(root_dir=".", virtual_mode=True, env={"PATH": "/usr/bin:/bin"}),
|
||||
)
|
||||
```
|
||||
@@ -1,4 +1,4 @@
|
||||
```typescript
|
||||
```ts
|
||||
import { createDeepAgent, StateBackend } from "deepagents";
|
||||
|
||||
// By default we provide a StateBackend
|
||||
@@ -1,12 +1,13 @@
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
|
||||
# By default we provide a StateBackend
|
||||
agent = create_deep_agent(model="google_genai:gemini-3.1-pro-preview")
|
||||
|
||||
# Under the hood, it looks like
|
||||
from deepagents.backends import StateBackend
|
||||
|
||||
agent = create_deep_agent(
|
||||
agent2 = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=StateBackend()
|
||||
backend=StateBackend(),
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
```ts
|
||||
import { createDeepAgent, StoreBackend } from "deepagents";
|
||||
import { InMemoryStore } from "@langchain/langgraph";
|
||||
|
||||
const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
backend: new StoreBackend({
|
||||
namespace: (ctx) => [ctx.runtime.context.userId],
|
||||
}),
|
||||
store,
|
||||
});
|
||||
```
|
||||
@@ -1,16 +1,13 @@
|
||||
```python
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StoreBackend
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=StoreBackend(
|
||||
namespace=lambda ctx: (ctx.runtime.context.user_id,),
|
||||
),
|
||||
store=InMemoryStore() # Good for local dev; omit for LangSmith Deployment
|
||||
store=InMemoryStore(), # Good for local dev; omit for LangSmith Deployment
|
||||
)
|
||||
```
|
||||
|
||||
<Note>
|
||||
When deploying to [LangSmith Deployment](/langsmith/deployment), omit the `store` parameter. The platform automatically provisions a store for your agent.
|
||||
</Note>
|
||||
+21
-13
@@ -1,15 +1,15 @@
|
||||
```typescript
|
||||
```ts
|
||||
import { tool } from "langchain";
|
||||
import { createDeepAgent } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
import { z } from "zod";
|
||||
|
||||
const deleteFile = tool(
|
||||
const removeFile = tool(
|
||||
async ({ path }: { path: string }) => {
|
||||
return `Deleted ${path}`;
|
||||
},
|
||||
{
|
||||
name: "delete_file",
|
||||
name: "remove_file",
|
||||
description: "Delete a file from the filesystem.",
|
||||
schema: z.object({
|
||||
path: z.string(),
|
||||
@@ -17,12 +17,12 @@ const deleteFile = tool(
|
||||
},
|
||||
);
|
||||
|
||||
const readFile = tool(
|
||||
const fetchFile = tool(
|
||||
async ({ path }: { path: string }) => {
|
||||
return `Contents of ${path}`;
|
||||
},
|
||||
{
|
||||
name: "read_file",
|
||||
name: "fetch_file",
|
||||
description: "Read a file from the filesystem.",
|
||||
schema: z.object({
|
||||
path: z.string(),
|
||||
@@ -30,12 +30,20 @@ const readFile = tool(
|
||||
},
|
||||
);
|
||||
|
||||
const sendEmail = tool(
|
||||
async ({ to, subject, body }: { to: string; subject: string; body: string }) => {
|
||||
const notifyEmail = tool(
|
||||
async ({
|
||||
to,
|
||||
subject,
|
||||
body,
|
||||
}: {
|
||||
to: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
}) => {
|
||||
return `Sent email to ${to}`;
|
||||
},
|
||||
{
|
||||
name: "send_email",
|
||||
name: "notify_email",
|
||||
description: "Send an email.",
|
||||
schema: z.object({
|
||||
to: z.string(),
|
||||
@@ -50,12 +58,12 @@ const checkpointer = new MemorySaver();
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
tools: [deleteFile, readFile, sendEmail],
|
||||
tools: [removeFile, fetchFile, notifyEmail],
|
||||
interruptOn: {
|
||||
delete_file: true, // Default: approve, edit, reject, respond
|
||||
read_file: false, // No interrupts needed
|
||||
send_email: { allowedDecisions: ["approve", "reject"] }, // No editing
|
||||
remove_file: true, // Default: approve, edit, reject, respond
|
||||
fetch_file: false, // No interrupts needed
|
||||
notify_email: { allowedDecisions: ["approve", "reject"] }, // No editing
|
||||
},
|
||||
checkpointer, // Required!
|
||||
checkpointer, // Required!
|
||||
});
|
||||
```
|
||||
+12
-8
@@ -3,32 +3,36 @@ from langchain.tools import tool
|
||||
from deepagents import create_deep_agent
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
|
||||
@tool
|
||||
def delete_file(path: str) -> str:
|
||||
def remove_file(path: str) -> str:
|
||||
"""Delete a file from the filesystem."""
|
||||
return f"Deleted {path}"
|
||||
|
||||
|
||||
@tool
|
||||
def read_file(path: str) -> str:
|
||||
def fetch_file(path: str) -> str:
|
||||
"""Read a file from the filesystem."""
|
||||
return f"Contents of {path}"
|
||||
|
||||
|
||||
@tool
|
||||
def send_email(to: str, subject: str, body: str) -> str:
|
||||
def notify_email(to: str, subject: str, body: str) -> str:
|
||||
"""Send an email."""
|
||||
return f"Sent email to {to}"
|
||||
|
||||
|
||||
# Checkpointer is REQUIRED for human-in-the-loop
|
||||
checkpointer = MemorySaver()
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
tools=[delete_file, read_file, send_email],
|
||||
tools=[remove_file, fetch_file, notify_email],
|
||||
interrupt_on={
|
||||
"delete_file": True, # Default: approve, edit, reject, respond
|
||||
"read_file": False, # No interrupts needed
|
||||
"send_email": {"allowed_decisions": ["approve", "reject"]}, # No editing
|
||||
"remove_file": True, # Default: approve, edit, reject, respond
|
||||
"fetch_file": False, # No interrupts needed
|
||||
"notify_email": {"allowed_decisions": ["approve", "reject"]}, # No editing
|
||||
},
|
||||
checkpointer=checkpointer # Required!
|
||||
checkpointer=checkpointer, # Required!
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
```ts
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new FilesystemBackend({ rootDir: process.cwd() });
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
skills: ["./examples/skills/"],
|
||||
interruptOn: {
|
||||
read_file: true,
|
||||
write_file: true,
|
||||
delete_file: true,
|
||||
},
|
||||
checkpointer, // Required!
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
|
||||
const result = await agent.invoke(
|
||||
{ messages: [{ role: "user", content: "what is langraph?" }] },
|
||||
config,
|
||||
);
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends.filesystem import FilesystemBackend
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
# Checkpointer is REQUIRED for human-in-the-loop
|
||||
checkpointer = MemorySaver()
|
||||
root_dir = "/Users/user/{project}"
|
||||
backend = FilesystemBackend(root_dir=root_dir)
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
skills=[str(Path(root_dir) / "skills")],
|
||||
interrupt_on={
|
||||
"write_file": True,
|
||||
"read_file": False,
|
||||
"edit_file": True,
|
||||
},
|
||||
checkpointer=checkpointer, # Required!
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "What is langgraph?"}]},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,43 @@
|
||||
```ts
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, StateBackend, type FileData } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new StateBackend();
|
||||
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillsFiles: Record<string, FileData> = {};
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
|
||||
skillsFiles["/skills/langgraph-docs/SKILL.md"] = createFileData(skillContent);
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
checkpointer, // Required !
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = { configurable: { thread_id: `thread-${Date.now()}` } };
|
||||
const result = await agent.invoke(
|
||||
{
|
||||
messages: [{ role: "user", content: "what is langraph?" }],
|
||||
files: skillsFiles,
|
||||
},
|
||||
config,
|
||||
);
|
||||
```
|
||||
@@ -0,0 +1,260 @@
|
||||
<CodeGroup>
|
||||
```python Google
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python OpenAI
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="openai:gpt-5.4",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python Anthropic
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="anthropic:claude-sonnet-4-6",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python OpenRouter
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="openrouter:anthropic/claude-sonnet-4-6",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python Fireworks
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="fireworks:accounts/fireworks/models/qwen3p5-397b-a17b",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python Baseten
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="baseten:zai-org/GLM-5",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
|
||||
```python Ollama
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StateBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="ollama:devstral-2",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)], # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [{"role": "user", "content": "What is langgraph?"}],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files,
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -0,0 +1,46 @@
|
||||
```ts
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
|
||||
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const store = new InMemoryStore();
|
||||
const backend = new StoreBackend();
|
||||
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
const fileData = createFileData(skillContent);
|
||||
|
||||
await store.put(["filesystem"], "/skills/langgraph-docs/SKILL.md", fileData);
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "google-genai:gemini-3.1-pro-preview",
|
||||
backend,
|
||||
store,
|
||||
checkpointer,
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = {
|
||||
recursionLimit: 50,
|
||||
configurable: { thread_id: `thread-${Date.now()}` },
|
||||
};
|
||||
const result = await agent.invoke(
|
||||
{ messages: [{ role: "user", content: "what is langraph?" }] },
|
||||
config,
|
||||
);
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
```python
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StoreBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
|
||||
store = InMemoryStore()
|
||||
backend = StoreBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
store.put(
|
||||
namespace=("filesystem",),
|
||||
key="/skills/langgraph-docs/SKILL.md",
|
||||
value=create_file_data(skill_content),
|
||||
)
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
store=store,
|
||||
skills=["/skills/"],
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)],
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{"messages": [{"role": "user", "content": "What is langgraph?"}]},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,393 @@
|
||||
<CodeGroup>
|
||||
```ts Google
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "google-genai:gemini-3.1-pro-preview", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts OpenAI
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "openai:gpt-5.4", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts Anthropic
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "anthropic:claude-sonnet-4-6", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts OpenRouter
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "openrouter:anthropic/claude-sonnet-4-6", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts Fireworks
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "fireworks:accounts/fireworks/models/qwen3p5-397b-a17b", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts Baseten
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "baseten:zai-org/GLM-5", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
|
||||
```ts Ollama
|
||||
import { tool } from "langchain";
|
||||
import { TavilySearch } from "@langchain/tavily";
|
||||
import { createDeepAgent, type SubAgent } from "deepagents";
|
||||
import { z } from "zod";
|
||||
|
||||
const internetSearch = tool(
|
||||
async ({
|
||||
query,
|
||||
maxResults = 5,
|
||||
topic = "general",
|
||||
includeRawContent = false,
|
||||
}: {
|
||||
query: string;
|
||||
maxResults?: number;
|
||||
topic?: "general" | "news" | "finance";
|
||||
includeRawContent?: boolean;
|
||||
}) => {
|
||||
const tavilySearch = new TavilySearch({
|
||||
maxResults,
|
||||
tavilyApiKey: process.env.TAVILY_API_KEY,
|
||||
includeRawContent,
|
||||
topic,
|
||||
});
|
||||
return await tavilySearch._call({ query });
|
||||
},
|
||||
{
|
||||
name: "internet_search",
|
||||
description: "Run a web search",
|
||||
schema: z.object({
|
||||
query: z.string().describe("The search query"),
|
||||
maxResults: z.number().optional().default(5),
|
||||
topic: z
|
||||
.enum(["general", "news", "finance"])
|
||||
.optional()
|
||||
.default("general"),
|
||||
includeRawContent: z.boolean().optional().default(false),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const researchSubagent: SubAgent = {
|
||||
name: "research-agent",
|
||||
description: "Used to research more in depth questions",
|
||||
systemPrompt: "You are a great researcher",
|
||||
tools: [internetSearch],
|
||||
model: "ollama:devstral-2", // Optional override, defaults to main agent model
|
||||
};
|
||||
const subagents = [researchSubagent];
|
||||
|
||||
const agent = createDeepAgent({
|
||||
model: "google_genai:gemini-3.1-pro-preview",
|
||||
subagents,
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
+7
-3
@@ -1,11 +1,13 @@
|
||||
```python
|
||||
import os
|
||||
from typing import Literal
|
||||
from tavily import TavilyClient
|
||||
|
||||
from deepagents import create_deep_agent
|
||||
from tavily import TavilyClient
|
||||
|
||||
tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
|
||||
|
||||
|
||||
def internet_search(
|
||||
query: str,
|
||||
max_results: int = 5,
|
||||
@@ -20,6 +22,7 @@ def internet_search(
|
||||
topic=topic,
|
||||
)
|
||||
|
||||
|
||||
research_subagent = {
|
||||
"name": "research-agent",
|
||||
"description": "Used to research more in depth questions",
|
||||
@@ -29,8 +32,9 @@ research_subagent = {
|
||||
}
|
||||
subagents = [research_subagent]
|
||||
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="claude-sonnet-4-6",
|
||||
subagents=subagents
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
subagents=subagents,
|
||||
)
|
||||
```
|
||||
@@ -1,166 +1,15 @@
|
||||
import SkillsUsageStateJs from '/snippets/code-samples/skills-usage-state-js.mdx';
|
||||
import SkillsUsageStoreJs from '/snippets/code-samples/skills-usage-store-js.mdx';
|
||||
import SkillsUsageFilesystemJs from '/snippets/code-samples/skills-usage-filesystem-js.mdx';
|
||||
|
||||
<Tabs>
|
||||
<Tab title="StateBackend">
|
||||
|
||||
```typescript
|
||||
import { createDeepAgent, StateBackend, type FileData } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new StateBackend();
|
||||
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillsFiles: Record<string, FileData> = {};
|
||||
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
|
||||
skillsFiles["/skills/langgraph-docs/SKILL.md"] = createFileData(skillContent);
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "openai:gpt-5.4",
|
||||
backend,
|
||||
checkpointer,
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = {
|
||||
configurable: {
|
||||
thread_id: `thread-${Date.now()}`,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await agent.invoke(
|
||||
{
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "what is langraph? Use the langgraph-docs skill if available.",
|
||||
},
|
||||
],
|
||||
files: skillsFiles,
|
||||
},
|
||||
config,
|
||||
);
|
||||
```
|
||||
|
||||
<SkillsUsageStateJs />
|
||||
</Tab>
|
||||
<Tab title="StoreBackend">
|
||||
|
||||
```typescript
|
||||
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
|
||||
import {
|
||||
InMemoryStore,
|
||||
MemorySaver,
|
||||
} from "@langchain/langgraph";
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const store = new InMemoryStore();
|
||||
const backend = new StoreBackend();
|
||||
|
||||
function createFileData(content: string): FileData {
|
||||
const now = new Date().toISOString();
|
||||
return {
|
||||
content: content.split("\n"),
|
||||
created_at: now,
|
||||
modified_at: now,
|
||||
};
|
||||
}
|
||||
|
||||
const skillUrl =
|
||||
"https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
|
||||
|
||||
const response = await fetch(skillUrl);
|
||||
const skillContent = await response.text();
|
||||
const fileData = createFileData(skillContent);
|
||||
|
||||
await store.put(["filesystem"], "/skills/langgraph-docs/SKILL.md", fileData);
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "openai:gpt-5.4",
|
||||
backend,
|
||||
store: store,
|
||||
checkpointer,
|
||||
// IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
|
||||
skills: ["/skills/"],
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = {
|
||||
recursionLimit: 50,
|
||||
configurable: {
|
||||
thread_id: `thread-${Date.now()}`,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await agent.invoke(
|
||||
{
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "what is langraph? Use the langgraph-docs skill if available.",
|
||||
},
|
||||
],
|
||||
},
|
||||
config,
|
||||
);
|
||||
```
|
||||
|
||||
<SkillsUsageStoreJs />
|
||||
</Tab>
|
||||
<Tab title="FilesystemBackend">
|
||||
|
||||
```typescript
|
||||
import { createDeepAgent, FilesystemBackend } from "deepagents";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";
|
||||
|
||||
const checkpointer = new MemorySaver();
|
||||
const backend = new FilesystemBackend({ rootDir: process.cwd() });
|
||||
|
||||
const agent = await createDeepAgent({
|
||||
model: "openai:gpt-5.4",
|
||||
backend,
|
||||
skills: ["./examples/skills/"],
|
||||
interruptOn: {
|
||||
read_file: true,
|
||||
write_file: true,
|
||||
delete_file: true,
|
||||
},
|
||||
checkpointer, // Required!
|
||||
middleware: [createCodeInterpreterMiddleware({ skillsBackend: backend })],
|
||||
});
|
||||
|
||||
const config = {
|
||||
configurable: {
|
||||
thread_id: `thread-${Date.now()}`,
|
||||
},
|
||||
};
|
||||
|
||||
const result = await agent.invoke(
|
||||
{
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: "what is langraph? Use the langgraph-docs skill if available.",
|
||||
},
|
||||
],
|
||||
},
|
||||
config,
|
||||
);
|
||||
```
|
||||
|
||||
<SkillsUsageFilesystemJs />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -1,126 +1,15 @@
|
||||
import SkillsUsageStatePy from '/snippets/code-samples/skills-usage-state-py.mdx';
|
||||
import SkillsUsageStorePy from '/snippets/code-samples/skills-usage-store-py.mdx';
|
||||
import SkillsUsageFilesystemPy from '/snippets/code-samples/skills-usage-filesystem-py.mdx';
|
||||
|
||||
<Tabs>
|
||||
<Tab title="StateBackend">
|
||||
```python
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
from deepagents.backends import StateBackend
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
|
||||
checkpointer = MemorySaver()
|
||||
backend = StateBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
skills_files = {
|
||||
"/skills/langgraph-docs/SKILL.md": create_file_data(skill_content)
|
||||
}
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
skills=["/skills/"],
|
||||
checkpointer=checkpointer,
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)] # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is langgraph?",
|
||||
}
|
||||
],
|
||||
# Seed the default StateBackend's in-state filesystem (virtual paths must start with "/").
|
||||
"files": skills_files
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
<SkillsUsageStatePy />
|
||||
</Tab>
|
||||
<Tab title="StoreBackend">
|
||||
```python
|
||||
from urllib.request import urlopen
|
||||
from deepagents import create_deep_agent
|
||||
from deepagents.backends import StoreBackend
|
||||
from deepagents.backends.utils import create_file_data
|
||||
from langgraph.store.memory import InMemoryStore
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
|
||||
|
||||
store = InMemoryStore()
|
||||
backend = StoreBackend()
|
||||
|
||||
skill_url = "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/libs/cli/examples/skills/langgraph-docs/SKILL.md"
|
||||
with urlopen(skill_url) as response:
|
||||
skill_content = response.read().decode('utf-8')
|
||||
|
||||
store.put(
|
||||
namespace=("filesystem",),
|
||||
key="/skills/langgraph-docs/SKILL.md",
|
||||
value=create_file_data(skill_content)
|
||||
)
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=backend,
|
||||
store=store,
|
||||
skills=["/skills/"],
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)] # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is langgraph?",
|
||||
}
|
||||
]
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
<SkillsUsageStorePy />
|
||||
</Tab>
|
||||
<Tab title="FilesystemBackend">
|
||||
```python
|
||||
from deepagents import create_deep_agent
|
||||
from langgraph.checkpoint.memory import MemorySaver
|
||||
from deepagents.backends.filesystem import FilesystemBackend
|
||||
from langchain_quickjs import CodeInterpreterMiddleware
|
||||
|
||||
# Checkpointer is REQUIRED for human-in-the-loop
|
||||
checkpointer = MemorySaver()
|
||||
backend = FilesystemBackend(root_dir="/Users/user/{project}")
|
||||
|
||||
agent = create_deep_agent(
|
||||
model="google_genai:gemini-3.1-pro-preview",
|
||||
backend=,
|
||||
skills=["/Users/user/{project}/skills/"],
|
||||
interrupt_on={
|
||||
"write_file": True, # Default: approve, edit, reject
|
||||
"read_file": False, # No interrupts needed
|
||||
"edit_file": True # Default: approve, edit, reject
|
||||
},
|
||||
checkpointer=checkpointer, # Required!
|
||||
middleware=[CodeInterpreterMiddleware(skills_backend=backend)] # for interpreter skills
|
||||
)
|
||||
|
||||
result = agent.invoke(
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is langgraph?",
|
||||
}
|
||||
]
|
||||
},
|
||||
config={"configurable": {"thread_id": "12345"}},
|
||||
)
|
||||
```
|
||||
<SkillsUsageFilesystemPy />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13.0, <4.0.0"
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.14'",
|
||||
"python_full_version < '3.14'",
|
||||
]
|
||||
|
||||
[manifest]
|
||||
overrides = [{ name = "pytest-codspeed", specifier = ">=3.1.0,<4.0.0" }]
|
||||
@@ -589,6 +593,7 @@ dependencies = [
|
||||
{ name = "langchain-daytona" },
|
||||
{ name = "langchain-google-genai" },
|
||||
{ name = "langchain-openai" },
|
||||
{ name = "langchain-quickjs" },
|
||||
{ name = "langgraph-checkpoint-postgres" },
|
||||
{ name = "markdownify" },
|
||||
{ name = "nbconvert" },
|
||||
@@ -625,6 +630,7 @@ requires-dist = [
|
||||
{ name = "langchain-daytona", specifier = ">=0.0.5" },
|
||||
{ name = "langchain-google-genai", specifier = ">=2.0.0" },
|
||||
{ name = "langchain-openai", specifier = ">=1.1.14" },
|
||||
{ name = "langchain-quickjs", specifier = ">=0.1.2" },
|
||||
{ name = "langgraph-checkpoint-postgres" },
|
||||
{ name = "markdownify", specifier = ">=0.13.0" },
|
||||
{ name = "nbconvert", specifier = ">=7.17.1" },
|
||||
|
||||
Reference in New Issue
Block a user