
Cloudbase Agent Ts
- 1 installs
- 417 repo stars
- Updated August 4, 2026
- tencentcloudbase/awesome-cloudbase-examples
Builds and deploys AI agents as HTTP services on CloudBase using the TypeScript AG-UI protocol SDK with LangGraph and LangChain adapters.
About
Deploys AI agents as AG-UI protocol HTTP services using @cloudbase/agent-server with LangGraph, LangChain, or custom adapters. A developer uses it when building agent backends and web or WeChat Mini Program UIs on CloudBase.
- Implements the AG-UI protocol with @cloudbase/agent-server
- Provides LangGraph and LangChain adapters plus web and Mini Program UI clients
Cloudbase Agent Ts by the numbers
- 1 all-time installs (skills.sh)
- Ranked #14,102 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/tencentcloudbase/awesome-cloudbase-examples --skill cloudbase-agent-tsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 417 |
| Last updated | August 4, 2026 |
| Repository | tencentcloudbase/awesome-cloudbase-examples ↗ |
What it does
Builds and deploys AI agents as HTTP services on CloudBase using the TypeScript AG-UI protocol SDK with LangGraph and LangChain adapters.
Files
Cloudbase Agent (TypeScript)
TypeScript SDK for deploying AI agents as HTTP services using the AG-UI protocol.
Note: This skill is for TypeScript/JavaScript projects only.
When to use this skill
Use this skill for AI agent development when you need to:
- Deploy AI agents as HTTP services with AG-UI protocol support
- Build agent backends using LangGraph or LangChain frameworks
- Create custom agent adapters implementing the AbstractAgent interface
- Understand AG-UI protocol events and message streaming
- Build web UI clients that connect to AG-UI compatible agents
- Build WeChat Mini Program UIs for AI agent interactions
Do NOT use for:
- Simple AI model calling without agent capabilities (use
ai-model-*skills) - CloudBase cloud functions (use
cloud-functionsskill) - CloudRun backend services without agent features (use
cloudrun-developmentskill)
How to use this skill (for a coding agent)
1. Choose the right adapter
- Use LangGraph adapter for stateful, graph-based workflows
- Use LangChain adapter for chain-based agent patterns
- Build custom adapter for specialized agent logic
2. Deploy the agent server
- Use
@cloudbase/agent-serverto expose HTTP endpoints - Configure CORS, logging, and observability as needed
- Deploy to CloudRun or any Node.js hosting environment
3. Build the UI client
- Use
@ag-ui/clientfor web applications - Use
@cloudbase/agent-ui-miniprogramfor WeChat Mini Programs - Connect to the agent server's
/send-messageor/aguiendpoints
4. Follow the routing table below to find detailed documentation for each task
Routing
| Task | Read |
|---|---|
| Deploy agent server (@cloudbase/agent-server) | server-quickstart |
| Use LangGraph adapter | adapter-langgraph |
| Use LangChain adapter | adapter-langchain |
| Build custom adapter | adapter-development |
| Understand AG-UI protocol | agui-protocol |
| Build UI client (Web or Mini Program) | ui-clients |
| Deep-dive @cloudbase/agent-ui-miniprogram | ui-miniprogram |
Quick Start
import { run } from "@cloudbase/agent-server";
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
run({
createAgent: () => ({ agent: new LanggraphAgent({ workflow }) }),
port: 9000,
});Building Custom Adapters
An adapter bridges your AI framework to the AG-UI protocol. It converts AG-UI input (messages, tools, state) into your framework's format, and converts your framework's streaming output into AG-UI events.
Prerequisites: Deep understanding of both your AI framework's API and the AG-UI protocol events.
When to build your own: No existing adapter for your framework (check AG-UI ecosystem first).
Extend AbstractAgent and implement run() that returns Observable<BaseEvent>.
Structure
import { AbstractAgent, RunAgentInput, BaseEvent, EventType } from "@ag-ui/client";
import { Observable, Subscriber } from "rxjs";
export class MyAdapter extends AbstractAgent {
run(input: RunAgentInput): Observable<BaseEvent> {
return new Observable((subscriber) => this._run(subscriber, input));
}
private async _run(subscriber: Subscriber<BaseEvent>, input: RunAgentInput) {
const { messages, runId, threadId, tools } = input;
subscriber.next({ type: EventType.RUN_STARTED, threadId, runId });
try {
// 1. Convert AG-UI input to your framework's format
// 2. Call your framework
// 3. Convert your framework's output to AG-UI events (see Event Sequence below)
subscriber.next({ type: EventType.RUN_FINISHED, threadId, runId });
} catch (error) {
subscriber.next({ type: EventType.RUN_ERROR, message: error.message });
}
subscriber.complete();
}
}Event Sequence (Brief)
Text: TEXT_MESSAGE_START → TEXT_MESSAGE_CONTENT (repeat) → TEXT_MESSAGE_END
Tool call: TOOL_CALL_START → TOOL_CALL_ARGS → TOOL_CALL_END
Tool result (server-executed tools only): TOOL_CALL_RESULT
Always emit full lifecycle. parentMessageId links tool calls to their parent message.
For complete event reference, see AG-UI Protocol.
@cloudbase/agent-adapter-langchain
Adapter that wraps LangChain's createAgent() as an AG-UI compatible agent. Provides LangchainAgent wrapper class and clientTools() middleware for client tools support.
Basic Usage
import { createAgent as createLangchainAgent } from "langchain";
import { MemorySaver } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { LangchainAgent, clientTools } from "@cloudbase/agent-adapter-langchain";
const model = new ChatOpenAI({ model: "gpt-4o" });
const checkpointer = new MemorySaver();
const lcAgent = createLangchainAgent({
model,
checkpointer,
middleware: [clientTools()],
});
const agent = new LangchainAgent({ agent: lcAgent });Checkpointer (Required)
LangchainAgent requires the agent to be created with a checkpointer.
MemorySaver (Development)
import { MemorySaver } from "@langchain/langgraph";
const lcAgent = createLangchainAgent({
model,
checkpointer: new MemorySaver(),
middleware: [clientTools()],
});CloudBaseSaver (Production)
Persistent storage using Tencent CloudBase document database. On CloudBase cloud function/cloudrun, requests are authenticated - extract user ID from the JWT in Authorization header.
import { run } from "@cloudbase/agent-server";
import { LangchainAgent, clientTools } from "@cloudbase/agent-adapter-langchain";
import { CloudBaseSaver } from "@cloudbase/agent-adapter-langgraph";
import { createAgent as createLangchainAgent } from "langchain";
import tcb from "@cloudbase/node-sdk";
const app = tcb.init({ env: process.env.CLOUDBASE_ENV_ID });
run({
createAgent: ({ request }) => {
// Extract user ID from JWT (sub field)
const token = request.headers.get("Authorization")?.slice(7);
const payload = JSON.parse(atob(token.split(".")[1]));
const userId = payload.sub;
const checkpointer = new CloudBaseSaver({
db: app.database(),
userId, // Multi-tenant isolation
});
const lcAgent = createLangchainAgent({
model,
checkpointer,
middleware: [clientTools()],
});
return { agent: new LangchainAgent({ agent: lcAgent }) };
},
port: 9000,
});With @cloudbase/agent-server
import { run } from "@cloudbase/agent-server";
run({
createAgent: () => ({ agent }),
port: 9000,
});clientTools() Middleware
Enables client-defined tools in your LangChain agent:
- Injects client tools - Adds client tools to the LLM's available tool list
- Routes to END - When a client tool is called, skips ToolNode and routes to END so client can execute
@cloudbase/agent-adapter-langgraph
Adapter that wraps a compiled LangGraph StateGraph workflow as an AG-UI compatible agent. Provides ClientStateAnnotation with pre-wired messages and client.tools fields for seamless AG-UI protocol integration.
Installation
npm install @cloudbase/agent-adapter-langgraph @langchain/langgraph @langchain/openaiExports
import {
LanggraphAgent,
ClientStateAnnotation,
ClientState,
CloudBaseSaver // Tencent CloudBase checkpointer
} from "@cloudbase/agent-adapter-langgraph";Basic Usage
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
const agent = new LanggraphAgent({
compiledWorkflow: graph, // compiled StateGraph (required)
logger: myLogger, // optional
});Checkpointer (Required)
LanggraphAgent requires the workflow to be compiled with a checkpointer.
MemorySaver (Development)
import { MemorySaver } from "@langchain/langgraph";
const graph = workflow.compile({ checkpointer: new MemorySaver() });CloudBaseSaver (Production)
Persistent storage using Tencent CloudBase document database. On CloudBase cloud function/cloudrun, requests are authenticated - extract user ID from the JWT in Authorization header.
import { run } from "@cloudbase/agent-server";
import { CloudBaseSaver, LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
import tcb from "@cloudbase/node-sdk";
const app = tcb.init({ env: process.env.CLOUDBASE_ENV_ID });
run({
createAgent: ({ request }) => {
// Extract user ID from JWT (sub field)
const token = request.headers.get("Authorization")?.slice(7);
const payload = JSON.parse(atob(token.split(".")[1]));
const userId = payload.sub;
const checkpointer = new CloudBaseSaver({
db: app.database(),
userId, // Multi-tenant isolation
});
const graph = workflow.compile({ checkpointer });
return { agent: new LanggraphAgent({ compiledWorkflow: graph }) };
},
port: 9000,
});Client Tools
Client tools are tools defined by the client, not the server. They let the agent request actions only the client can perform (e.g., show modal, navigate, access local storage). The flow:
1. Client defines tools with handlers and sends them in request 2. Server binds client tools alongside server tools, LLM can call any 3. Server detects client tool call → routes to END (doesn't execute) 4. Client receives TOOL_CALL_* events, executes handler locally 5. Client sends tool result back, agent resumes
Server Side: Bind and Route
import { ClientState } from "@cloudbase/agent-adapter-langgraph";
// 1. Bind client tools to model (alongside server tools)
async function chatNode(state: ClientState) {
const clientTools = state.client?.tools || [];
const modelWithTools = model.bindTools([...clientTools, ...serverTools]);
// ...
}
// 2. Route client tool calls to END (let client handle)
function shouldContinue(state: ClientState): "tools" | "end" {
const lastMessage = state.messages[state.messages.length - 1];
if (lastMessage.tool_calls?.length > 0) {
const hasServerToolCall = lastMessage.tool_calls.some(tc => serverToolNames.has(tc.name));
if (hasServerToolCall) return "tools"; // Server executes
}
return "end"; // Client tool or no tool → end, client handles
}Complete Workflow Pattern
import { StateGraph, START, END, Command } from "@langchain/langgraph";
import { ClientStateAnnotation, ClientState } from "@cloudbase/agent-adapter-langgraph";
import { MemorySaver } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { SystemMessage } from "@langchain/core/messages";
import { RunnableConfig } from "@langchain/core/runnables";
async function chatNode(state: ClientState, config?: RunnableConfig) {
const model = new ChatOpenAI({ model: "gpt-4o" });
const modelWithTools = model.bindTools([...(state.client?.tools || [])], {
parallel_tool_calls: false, // Recommended: avoid race conditions
});
const response = await modelWithTools.invoke([
new SystemMessage({ content: "You are a helpful assistant." }),
...state.messages,
], config);
return new Command({ goto: END, update: { messages: [response] } });
}
const workflow = new StateGraph(ClientStateAnnotation)
.addNode("chat_node", chatNode)
.addEdge(START, "chat_node");
export const graph = workflow.compile({ checkpointer: new MemorySaver() });With @cloudbase/agent-server
Deploy your LangGraph workflow as an HTTP endpoint that speaks the AG-UI protocol. Clients can connect via SSE to stream events.
import { run } from "@cloudbase/agent-server";
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
run({
createAgent: () => ({
agent: new LanggraphAgent({ compiledWorkflow: graph })
}),
port: 3000
});AG-UI Protocol
Open, event-based protocol for agent-UI communication. Server streams events to client via SSE.
Event Patterns
Start-Content-End: For streaming content
TEXT_MESSAGE_START → TEXT_MESSAGE_CONTENT (repeat) → TEXT_MESSAGE_END
TOOL_CALL_START → TOOL_CALL_ARGS (repeat) → TOOL_CALL_ENDLifecycle: Wraps every agent run
RUN_STARTED → [events] → RUN_FINISHED | RUN_ERRORSnapshot-Delta: For state sync
STATE_SNAPSHOT (full state) → STATE_DELTA (JSON Patch updates)Core Events
| Event | Key Fields |
|---|---|
RUN_STARTED | threadId, runId |
RUN_FINISHED | threadId, runId |
RUN_ERROR | message, code? |
TEXT_MESSAGE_START | messageId, role |
TEXT_MESSAGE_CONTENT | messageId, delta |
TEXT_MESSAGE_END | messageId |
TOOL_CALL_START | toolCallId, toolCallName, parentMessageId? |
TOOL_CALL_ARGS | toolCallId, delta |
TOOL_CALL_END | toolCallId |
TOOL_CALL_RESULT | toolCallId, messageId, content |
STATE_SNAPSHOT | snapshot |
STATE_DELTA | delta (RFC 6902 JSON Patch) |
MESSAGES_SNAPSHOT | messages[] |
Input Types
interface RunAgentInput {
threadId: string;
runId: string;
messages: Message[];
tools: Tool[];
state?: unknown;
context?: Context[];
forwardedProps?: Record<string, unknown>;
}
interface Message {
id: string;
role: "user" | "assistant" | "system" | "tool";
content: string;
name?: string; // for tool messages
toolCalls?: ToolCall[]; // for assistant messages
toolCallId?: string; // for tool messages
}
interface ToolCall {
id: string;
type: "function";
function: { name: string; arguments: string };
}
interface Tool {
name: string;
description: string;
parameters?: JSONSchema;
}Tool Execution Flow
Server-executed tools: 1. Agent emits TOOL_CALL_START/ARGS/END 2. Server executes tool 3. Server emits TOOL_CALL_RESULT 4. Agent continues with result
Client tools: 1. Agent emits TOOL_CALL_START/ARGS/END 2. Server emits RUN_FINISHED (run pauses) 3. Client executes tool locally 4. Client sends new request with tool result in messages 5. Agent continues
Full Reference
For complete protocol specification: https://docs.ag-ui.com/concepts/events
@cloudbase/agent-server
Deploy AG-UI compatible agents as HTTP servers.
Deployment Methods
run() - Standalone
import { run } from "@cloudbase/agent-server";
run({ createAgent: () => ({ agent }), port: 9000 });createExpressServer() - Get App
import { createExpressServer } from "@cloudbase/agent-server";
const app = createExpressServer({ createAgent: () => ({ agent }) });
app.listen(9000);createExpressRoutes() - Add to Existing
import { createExpressRoutes } from "@cloudbase/agent-server";
createExpressRoutes({ createAgent: () => ({ agent }), express: app, basePath: "/api/" });Endpoints Created
| Endpoint | Purpose |
|---|---|
/agui | CopilotKit RPC endpoint |
/send-message | AG-UI endpoint (SSE) |
/healthz | Health check |
/chat/completions | OpenAI-compatible endpoint |
/v1/aibot/bots/:agentId/... | Same endpoints with bot ID (when no basePath) |
AgentCreatorContext
interface AgentCreatorContext {
request: Request; // Web Standard Request
logger?: Logger; // Pino-style logger (AGUI routes only)
requestId?: string; // Unique request ID (AGUI routes only)
}
createAgent: (ctx: AgentCreatorContext) => ({
agent, // Your adapter instance
cleanup?: () => void // Called when request ends
})Cleanup Pattern
createAgent: (ctx) => {
const db = connectToDatabase();
ctx.logger?.info("Connected to database");
return {
agent: new LanggraphAgent({ workflow }),
cleanup: () => db.close()
};
}All Options
run({
createAgent,
port: 9000,
basePath: "/api/", // Custom base path (default: dual endpoints)
cors: true, // or { origin: "https://..." }
useAGUI: true, // Enable /agui endpoint (default: true)
aguiOptions: {
runtimeOptions: {}, // CopilotRuntimeOptions
endpointOptions: {} // CreateCopilotRuntimeServerOptions
},
logger: createConsoleLogger("debug"),
observability: { type: "otlp", url: "...", headers: {...} }
});Logger Exports
import {
noopLogger, // Silent logger (default)
createConsoleLogger, // Console logger
generateRequestId,
extractRequestId,
getOrGenerateRequestId
} from "@cloudbase/agent-server";
// Custom logger (Pino-style interface)
const logger = {
info: (obj, msg) => console.log(msg, obj),
error: (obj, msg) => console.error(msg, obj),
debug: (obj, msg) => console.debug(msg, obj),
child: (bindings) => ({ ...logger })
};Observability
Requires @cloudbase/agent-observability package:
run({
createAgent,
observability: { type: "console" } // Logs traces to stdout
});
// OTLP exporter (Langfuse, Jaeger, etc.)
run({
createAgent,
observability: {
type: "otlp",
url: "https://cloud.langfuse.com/api/public/otlp/v1/traces",
headers: { Authorization: "Basic xxx" }
}
});
// Multiple exporters
run({
createAgent,
observability: [
{ type: "console" },
{ type: "otlp", url: "http://localhost:4318/v1/traces" }
]
});Error Handling
import { ErrorCode, isErrorWithCode } from "@cloudbase/agent-server";
// ErrorCode enum values for error handlingBuilding UI Clients
Connect your UI to AG-UI endpoints served by @cloudbase/agent-server.
Web Applications
Use @ag-ui/client (official AG-UI SDK):
npm install @ag-ui/clientimport { HttpAgent } from "@ag-ui/client";
const agent = new HttpAgent({ url: "http://localhost:9000/send-message" });
for await (const event of agent.run({
threadId: "thread-1",
runId: "run-1",
messages: [{ id: "m1", role: "user", content: "Hello" }]
})) {
console.log(event.type, event);
}See AG-UI documentation for full API: https://docs.ag-ui.com
WeChat Mini Program
Use @cloudbase/agent-ui-miniprogram (headless behavior mixin):
npm install @cloudbase/agent-ui-miniprogramimport { createAGUIBehavior, CloudbaseTransport } from "@cloudbase/agent-ui-miniprogram";
Component({
behaviors: [createAGUIBehavior({
transport: new CloudbaseTransport({ botId: "your-bot-id" })
})],
methods: {
onSend() {
this.agui.sendMessage(this.data.inputText);
}
}
});
// State: this.data.agui.uiMessages, this.data.agui.isRunningBeyond basic usage, the package offers more createAGUIBehavior options, this.agui.* namespace methods, state getters, and UIMessage format for rendering.
@cloudbase/agent-ui-miniprogram
WeChat Mini Program SDK for AG-UI protocol. Headless behavior mixin pattern.
Installation
npm install @cloudbase/agent-ui-miniprogramBasic Usage
import { createAGUIBehavior, CloudbaseTransport } from "@cloudbase/agent-ui-miniprogram";
const transport = new CloudbaseTransport({ botId: "your-bot-id" });
Component({
behaviors: [createAGUIBehavior({ transport })],
methods: {
onSend() {
this.agui.sendMessage(this.data.inputText);
}
}
});createAGUIBehavior Options
createAGUIBehavior({
transport, // Transport instance (CloudbaseTransport)
messages: [], // Initial message history
tools: [{ // Client tools the agent can invoke
name: "get_weather",
description: "Get weather",
parameters: { type: "object", properties: { city: { type: "string" } } },
handler: async ({ args }) => ({ temp: 72 })
}],
threadId: "custom-id", // Custom thread ID (auto-generated if omitted)
contexts: [], // Additional context objects
onRawEvent: (event) => {} // Callback for each raw AG-UI event
})Namespace Methods (this.agui.*)
| Method | Description |
|---|---|
init({ transport, threadId? }) | Initialize transport at runtime |
| `sendMessage(text \ | Message[])` |
appendMessage(message) | Add message without running agent |
setMessages(messages) | Replace entire message history |
reset() | Reset to initial state |
setThreadId(id) | Change thread ID |
addTool(tool) | Register a client tool |
removeTool(name) | Remove tool by name |
updateTool(name, updates) | Update tool properties |
clearTools() | Remove all tools |
State Getters (this.agui. or this.data.agui.)
| Property | Type | Description |
|---|---|---|
messages | Message[] | Raw message history |
uiMessages | UIMessage[] | Messages formatted for UI rendering |
isRunning | boolean | Agent is processing |
runId | `string \ | null` |
activeToolCalls | ToolCallState[] | Tool calls in progress |
error | `AGUIClientError \ | null` |
threadId | string | Current thread ID |
tools | Tool[] | Registered tools (definitions only) |
contexts | Context[] | Context objects |
config | CreateAGUIBehaviorOptions | Current configuration |
CloudbaseTransport
Production transport for WeChat Cloud Development:
import { CloudbaseTransport } from "@cloudbase/agent-ui-miniprogram";
const transport = new CloudbaseTransport({
botId: "bot-xxxxxx" // From Cloud Development console
});Requires wx.cloud.extend.AI.bot.sendMessage API.
Imperative Pattern
Use aguiBehavior (no static config) for runtime-only initialization:
import { aguiBehavior, CloudbaseTransport } from "@cloudbase/agent-ui-miniprogram";
Component({
behaviors: [aguiBehavior],
lifetimes: {
attached() {
this.agui.init({
transport: new CloudbaseTransport({ botId: "my-bot" })
});
}
}
});Client Tool Example
Component({
behaviors: [createAGUIBehavior({ transport })],
lifetimes: {
attached() {
this.agui.addTool({
name: "show_toast",
description: "Show a toast message",
parameters: {
type: "object",
properties: { title: { type: "string" } },
required: ["title"]
},
handler: async ({ args }) => {
wx.showToast({ title: args.title });
return { success: true };
}
});
}
}
});UIMessage Format
uiMessages groups consecutive same-role messages with parts:
interface UIMessage {
id: string;
role: "user" | "assistant";
parts: (TextPart | ToolPart)[];
}
interface TextPart { type: "text"; text: string; }
interface ToolPart {
type: "tool";
toolCallId: string;
name: string;
args?: Record<string, unknown>;
status: "pending" | "ready" | "executing" | "completed" | "failed";
result?: unknown;
error?: AGUIClientError;
}