Integrations
CrewLayer integrates with the most popular AI orchestration frameworks. Install the extras and drop in the adapters — your agent gets persistent memory and action logging with no changes to your core logic.
LangChain
Installation
pip install crewlayer[langchain]CrewLayerMemory
CrewLayerMemory is a LangChain BaseMemory subclass that transparently saves and recalls conversation history through CrewLayer's long-term memory.
from langchain_anthropic import ChatAnthropic
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from crewlayer.integrations.langchain import CrewLayerMemory, CrewLayerCallbackHandler
# Initialize memory and callback handler
memory = CrewLayerMemory(
agent_id="agt_langchain_001",
api_key="crwl_...",
base_url="http://localhost:8000",
top_k=5, # memories recalled per turn
auto_extract=True, # extract facts automatically after each turn
)
handler = CrewLayerCallbackHandler(
agent_id="agt_langchain_001",
api_key="crwl_...",
base_url="http://localhost:8000",
)
# Build LangChain agent
llm = ChatAnthropic(model="claude-opus-4-8")
tools = [...] # your tools here
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant. Relevant memories: {crewlayer_memory}"),
("placeholder", "{chat_history}"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory,
callbacks=[handler],
verbose=True,
)
# Run — memory is saved and recalled automatically
result = executor.invoke({"input": "What's the capital of France?"})
print(result["output"])CrewLayerCallbackHandler
CrewLayerCallbackHandler logs every LLM call, tool call, and chain run to CrewLayer's action log. Pass it to AgentExecutor via callbacks.
from crewlayer.integrations.langchain import CrewLayerCallbackHandler
handler = CrewLayerCallbackHandler(
agent_id="agt_langchain_001",
api_key="crwl_...",
base_url="http://localhost:8000",
log_llm_calls=True, # log LLM start/end
log_tool_calls=True, # log tool calls
log_chain_runs=False, # skip internal chain events
)
# Pass to any LangChain component
executor = AgentExecutor(..., callbacks=[handler])
# Or to a specific chain
chain.invoke({"input": "..."}, config={"callbacks": [handler]})AutoGen
Installation
pip install crewlayer[autogen]CrewLayerMemoryMixin
CrewLayerMemoryMixin injects persistent memory into any AutoGen ConversableAgent subclass. It overrides process_last_received_message to recall memories before each response and saves new memories after each reply.
import autogen
from crewlayer.integrations.autogen import CrewLayerMemoryMixin
# Mix CrewLayer into any AutoGen agent
class CrewLayerAssistant(CrewLayerMemoryMixin, autogen.AssistantAgent):
pass
class CrewLayerUser(CrewLayerMemoryMixin, autogen.UserProxyAgent):
pass
assistant = CrewLayerAssistant(
name="assistant",
crewlayer_agent_id="agt_autogen_assistant",
crewlayer_api_key="crwl_...",
crewlayer_base_url="http://localhost:8000",
system_message="You are a helpful assistant with persistent memory.",
llm_config={"model": "claude-opus-4-8", ...},
)
user_proxy = CrewLayerUser(
name="user_proxy",
crewlayer_agent_id="agt_autogen_user",
crewlayer_api_key="crwl_...",
crewlayer_base_url="http://localhost:8000",
human_input_mode="NEVER",
max_consecutive_auto_reply=5,
)
# Run multi-turn conversation with shared persistent memory
user_proxy.initiate_chat(
assistant,
message="Summarize what we discussed last time.",
)Shared Blackboard with GroupChatManager
Multiple agents in a GroupChat can share state via the CrewLayer blackboard. Any agent can write to a shared namespace; all agents see updates immediately via SSE.
import autogen
from crewlayer import CrewLayerClient
cl = CrewLayerClient(api_key="crwl_...", base_url="http://localhost:8000")
SHARED_NS = "project_alpha"
def write_to_blackboard(key: str, value: str) -> str:
"""Write a value to the shared blackboard."""
cl.context.write(namespace=SHARED_NS, key=key, value=value)
return f"Written {key} = {value}"
def read_from_blackboard(key: str) -> str:
"""Read a value from the shared blackboard."""
entry = cl.context.read(namespace=SHARED_NS, key=key)
return entry["value"] if entry else "Not found"
researcher = autogen.AssistantAgent(
name="researcher",
system_message="Research agent. Use write_to_blackboard to share findings.",
llm_config={
"model": "claude-opus-4-8",
"functions": [
{"name": "write_to_blackboard", "description": "...", "parameters": {...}},
{"name": "read_from_blackboard", "description": "...", "parameters": {...}},
],
},
)
writer = autogen.AssistantAgent(
name="writer",
system_message="Writer agent. Use read_from_blackboard to get research findings.",
llm_config={"model": "claude-opus-4-8", ...},
)
group_chat = autogen.GroupChat(
agents=[researcher, writer],
messages=[],
max_round=10,
)
manager = autogen.GroupChatManager(groupchat=group_chat, llm_config={...})
researcher.initiate_chat(manager, message="Research the latest trends in AI memory.")LlamaIndex
Installation
pip install crewlayer[llamaindex]CrewLayerVectorIndex
CrewLayerVectorIndex wraps CrewLayer's semantic memory as a LlamaIndex VectorStoreIndex. Documents inserted go into the agent's long-term memory; queries use cosine similarity over pgvector embeddings.
from llama_index.core import Document
from crewlayer.integrations.llamaindex import CrewLayerVectorIndex
# Create a vector index backed by CrewLayer's long-term memory
index = CrewLayerVectorIndex(
agent_id="agt_llama_001",
api_key="crwl_...",
base_url="http://localhost:8000",
top_k=5, # number of results to return on query
)
# Insert documents — stored as memories with auto-generated embeddings
docs = [
Document(text="CrewLayer provides persistent memory for AI agents."),
Document(text="It supports PostgreSQL with pgvector for semantic search."),
Document(text="Agents can share state via the blackboard (context namespace)."),
]
index.insert_documents(docs)
# Query — performs semantic recall from CrewLayer memory
query_engine = index.as_query_engine()
response = query_engine.query("How does CrewLayer handle memory?")
print(str(response))CrewLayerCallbackManager
Log all LlamaIndex query and retrieval events to CrewLayer's action log:
from llama_index.core import Settings
from crewlayer.integrations.llamaindex import CrewLayerCallbackHandler
handler = CrewLayerCallbackHandler(
agent_id="agt_llama_001",
api_key="crwl_...",
base_url="http://localhost:8000",
)
Settings.callback_manager.add_handler(handler)
# All subsequent LlamaIndex calls are now logged to CrewLayer
query_engine = index.as_query_engine()
response = query_engine.query("Tell me about memory management.")Vercel AI SDK
Installation
npm install crewlayer @ai-sdk/anthropic aiwithCrewLayerMemory
withCrewLayerMemory is a Vercel AI middleware that recalls relevant memories before the LLM call and saves new memories after. Drop it into any streamText or generateText call.
import { streamText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { withCrewLayerMemory } from "crewlayer/vercel-ai";
import { NextRequest } from "next/server";
const crewlayerMiddleware = withCrewLayerMemory({
agentId: "agt_vercel_001",
apiKey: process.env.CREWLAYER_API_KEY!,
baseUrl: process.env.CREWLAYER_BASE_URL ?? "http://localhost:8000",
topK: 5,
autoExtract: true, // extract facts from each response and save as memories
});
export async function POST(req: NextRequest) {
const { messages } = await req.json();
const result = streamText({
model: anthropic("claude-opus-4-8"),
system: "You are a helpful assistant with persistent memory.",
messages,
experimental_providerMetadata: {
crewlayer: { middleware: crewlayerMiddleware },
},
});
return result.toDataStreamResponse();
}Client-side Chat UI
"use client";
import { useChat } from "ai/react";
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: "/api/chat",
});
return (
<div>
{messages.map((m) => (
<div key={m.id}>
<span>{m.role === "user" ? "You" : "AI"}: </span>
{m.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input
value={input}
onChange={handleInputChange}
placeholder="Say something..."
disabled={isLoading}
/>
<button type="submit" disabled={isLoading}>Send</button>
</form>
</div>
);
}Streaming Blackboard Updates
Display live context updates from the blackboard in your Next.js app using the TypeScript SDK's SSE stream:
"use client";
import { useEffect, useState } from "react";
import { CrewLayerClient } from "crewlayer";
const client = new CrewLayerClient({
apiKey: process.env.NEXT_PUBLIC_CREWLAYER_KEY!,
baseUrl: process.env.NEXT_PUBLIC_CREWLAYER_URL ?? "http://localhost:8000",
});
export function StatusPanel({ namespace }: { namespace: string }) {
const [entries, setEntries] = useState<Record<string, string>>({});
useEffect(() => {
const stream = client.context.subscribe(namespace);
stream.on("update", (event) => {
setEntries((prev) => ({ ...prev, [event.key]: event.value }));
});
return () => stream.close();
}, [namespace]);
return (
<ul>
{Object.entries(entries).map(([k, v]) => (
<li key={k}><strong>{k}</strong>: {v}</li>
))}
</ul>
);
}