INTEGRITY Dokumentace

Client SDK

Připojte se k agentům z libovolného runtime JavaScriptu (prohlížeče, Node.js, Deno, Bun nebo edge funkce) pomocí WebSockets nebo HTTP. SDK poskytuje synchronizaci stavu v reálném čase, volání metod RPC a streamované odpovědi.

Přehled

Klientské SDK nabízí dva způsoby připojení přes WebSocket a jeden způsob odesílání požadavků HTTP.

Klient Případ použití
useAgent React hook s automatickým opětovným připojením a správou stavu
AgentClient Třída Vanilla JavaScript/TypeScript pro libovolné prostředí
agentFetch HTTP požadavky, když WebSocket není potřeba

Všichni klienti poskytují:

Rychlý start

React

import { useAgent } from "agents/react";

function Chat() {
	const agent = useAgent({
		agent: "ChatAgent",
		name: "room-123",
		onStateUpdate: (state) => {
			console.log("New state:", state);
		},
	});

	const sendMessage = async () => {
		const response = await agent.call("sendMessage", ["Hello!"]);
		console.log("Response:", response);
	};

	return <button onClick={sendMessage}>Send</button>;
}
import { useAgent } from "agents/react";

function Chat() {
	const agent = useAgent({
		agent: "ChatAgent",
		name: "room-123",
		onStateUpdate: (state) => {
			console.log("New state:", state);
		},
	});

	const sendMessage = async () => {
		const response = await agent.call("sendMessage", ["Hello!"]);
		console.log("Response:", response);
	};

	return <button onClick={sendMessage}>Send</button>;
}

Vanilla JavaScript

import { AgentClient } from "agents/client";

const client = new AgentClient({
	agent: "ChatAgent",
	name: "room-123",
	host: "your-worker.your-subdomain.workers.dev",
	onStateUpdate: (state) => {
		console.log("New state:", state);
	},
});

// Call a method
const response = await client.call("sendMessage", ["Hello!"]);
import { AgentClient } from "agents/client";

const client = new AgentClient({
	agent: "ChatAgent",
	name: "room-123",
	host: "your-worker.your-subdomain.workers.dev",
	onStateUpdate: (state) => {
		console.log("New state:", state);
	},
});

// Call a method
const response = await client.call("sendMessage", ["Hello!"]);

Připojování k agentům

Pojmenování agenta

agent parametr je název třídy vašeho agenta. Automaticky se převede z camelCase na kebab-case pro URL:

// These are equivalent:
useAgent({ agent: "ChatAgent" }); // → /agents/chat-agent/...
useAgent({ agent: "MyCustomAgent" }); // → /agents/my-custom-agent/...
useAgent({ agent: "LOUD_AGENT" }); // → /agents/loud-agent/...
// These are equivalent:
useAgent({ agent: "ChatAgent" }); // → /agents/chat-agent/...
useAgent({ agent: "MyCustomAgent" }); // → /agents/my-custom-agent/...
useAgent({ agent: "LOUD_AGENT" }); // → /agents/loud-agent/...

Názvy instancí

name parametr identifikuje konkrétní instanci agenta. Pokud je vynechán, výchozí hodnotou je "default":

// Connect to a specific chat room
useAgent({ agent: "ChatAgent", name: "room-123" });

// Connect to a user's personal agent
useAgent({ agent: "UserAgent", name: userId });

// Uses "default" instance
useAgent({ agent: "ChatAgent" });
// Connect to a specific chat room
useAgent({ agent: "ChatAgent", name: "room-123" });

// Connect to a user's personal agent
useAgent({ agent: "UserAgent", name: userId });

// Uses "default" instance
useAgent({ agent: "ChatAgent" });

Možnosti připojení

Obojí useAgent a AgentClient přijímají možnosti připojení:

useAgent({
	agent: "ChatAgent",
	name: "room-123",

	// Connection settings
	host: "my-worker.workers.dev", // Custom host (defaults to current origin)
	path: "/custom/path", // Custom path prefix

	// Query parameters (sent on connection)
	query: {
		token: "abc123",
		version: "2",
	},

	// Event handlers
	onOpen: () => console.log("Connected"),
	onClose: () => console.log("Disconnected"),
	onError: (error) => console.error("Error:", error),
});
useAgent({
	agent: "ChatAgent",
	name: "room-123",

	// Connection settings
	host: "my-worker.workers.dev", // Custom host (defaults to current origin)
	path: "/custom/path", // Custom path prefix

	// Query parameters (sent on connection)
	query: {
		token: "abc123",
		version: "2",
	},

	// Event handlers
	onOpen: () => console.log("Connected"),
	onClose: () => console.log("Disconnected"),
	onError: (error) => console.error("Error:", error),
});

Asynchronní parametry dotazu

Pro autentizační tokeny nebo jiná asynchronní data předejte funkci, která vrací Promise:

useAgent({
	agent: "ChatAgent",
	name: "room-123",

	// Async query - called before connecting
	query: async () => {
		const token = await getAuthToken();
		return { token };
	},

	// Dependencies that trigger re-fetching the query
	queryDeps: [userId],

	// Cache TTL for the query result (default: 5 minutes)
	cacheTtl: 60 * 1000, // 1 minute
});
useAgent({
	agent: "ChatAgent",
	name: "room-123",

	// Async query - called before connecting
	query: async () => {
		const token = await getAuthToken();
		return { token };
	},

	// Dependencies that trigger re-fetching the query
	queryDeps: [userId],

	// Cache TTL for the query result (default: 5 minutes)
	cacheTtl: 60 * 1000, // 1 minute
});

Funkce query je kešovaná a znovu se volá pouze když:

Synchronizace stavu

Agents mohou udržovat stav, který se obousměrně synchronizuje se všemi připojenými klienty.

Čtení aktuálního stavu

Obojí useAgent a AgentClient zpřístupní state vlastnost, která odráží aktuální stav agenta. Zpočátku je undefined dokud není ze serveru přijata první stavová zpráva.

const agent = useAgent({ agent: "GameAgent", name: "game-123" });

// Read the current state at any time
console.log("Current score:", agent.state?.score);
const agent = useAgent({ agent: "GameAgent", name: "game-123" });

// Read the current state at any time
console.log("Current score:", agent.state?.score);

S useAgent, aktualizace stavu spustí nové vykreslení Reactu, takže agent.state vždy odráží nejnovější hodnotu ve vašem JSX. S AgentClient, state pole se aktualizuje synchronně při každém příchozím vysílání ze serveru nebo setState volání.

Přijímání aktualizací stavu

const agent = useAgent({
	agent: "GameAgent",
	name: "game-123",
	onStateUpdate: (state, source) => {
		// state: The new state from the agent
		// source: "server" (agent pushed) or "client" (you pushed)
		console.log(`State updated from ${source}:`, state);
		setGameState(state);
	},
});
const agent = useAgent({
	agent: "GameAgent",
	name: "game-123",
	onStateUpdate: (state, source) => {
		// state: The new state from the agent
		// source: "server" (agent pushed) or "client" (you pushed)
		console.log(`State updated from ${source}:`, state);
		setGameState(state);
	},
});

Odesílání aktualizací stavu

// Update the agent's state from the client
agent.setState({ score: 100, level: 5 });
// Update the agent's state from the client
agent.setState({ score: 100, level: 5 });

Když zavoláte setState():

  1. Stav se agentovi odesílá přes WebSocket
  2. Agentův onStateChanged() metoda se volá
  3. Agent vysílá nový stav všem připojeným klientům
  4. Váš onStateUpdate callback se spustí s source: "client"

Stavový tok

sequenceDiagram
    participant Client
    participant Agent
    Client->>Agent: setState()
    Agent-->>Client: onStateUpdate (broadcast)

Volání metod agenta (RPC)

Volejte metody svého agenta označené dekorátorem @callable().

Používání call()

// Basic call
const result = await agent.call("getUser", [userId]);

// Call with multiple arguments
const result = await agent.call("createPost", [title, content, tags]);

// Call with no arguments
const result = await agent.call("getStats");
// Basic call
const result = await agent.call("getUser", [userId]);

// Call with multiple arguments
const result = await agent.call("createPost", [title, content, tags]);

// Call with no arguments
const result = await agent.call("getStats");

Používání stub proxy

stub vlastnost poskytuje přehlednější syntaxi pro volání metod:

// Instead of:
const user = await agent.call("getUser", ["user-123"]);

// You can write:
const user = await agent.stub.getUser("user-123");

// Multiple arguments work naturally:
const post = await agent.stub.createPost(title, content, tags);
// Instead of:
const user = await agent.call("getUser", ["user-123"]);

// You can write:
const user = await agent.stub.getUser("user-123");

// Multiple arguments work naturally:
const post = await agent.stub.createPost(title, content, tags);

Integrace TypeScript

Pro plnou typovou bezpečnost předejte svou třídu Agent jako typový parametr:

const agent = useAgent({
	agent: "MyAgent",
	name: "instance-1",
});

// Now stub methods are fully typed
const result = await agent.stub.processData({ input: "test" });
import type { MyAgent } from "./agents/my-agent";

const agent = useAgent<MyAgent>({
	agent: "MyAgent",
	name: "instance-1",
});

// Now stub methods are fully typed
const result = await agent.stub.processData({ input: "test" });

Streamované odpovědi

Označit volatelnou metodu jako streamovací. Framework předá StreamingResponse jako první argument:

// Agent-side
import { Agent, callable } from "agents";

class MyAgent extends Agent {
	@callable({ streaming: true })
	async generateText(stream, prompt) {
		for await (const chunk of llm.stream(prompt)) {
			stream.send(chunk);
		}
		stream.end();
	}
}

// Client-side
await agent.call("generateText", [prompt], {
	onChunk: (chunk) => {
		// Called for each chunk
		appendToOutput(chunk);
	},
	onDone: (finalResult) => {
		// Called when stream completes
		console.log("Complete:", finalResult);
	},
	onError: (error) => {
		// Called if streaming fails
		console.error("Stream error:", error);
	},
});
// Agent-side
import { Agent, callable, type StreamingResponse } from "agents";

class MyAgent extends Agent {
	@callable({ streaming: true })
	async generateText(stream: StreamingResponse, prompt: string) {
		for await (const chunk of llm.stream(prompt)) {
			stream.send(chunk);
		}
		stream.end();
	}
}

// Client-side
await agent.call("generateText", [prompt], {
	onChunk: (chunk) => {
		// Called for each chunk
		appendToOutput(chunk);
	},
	onDone: (finalResult) => {
		// Called when stream completes
		console.log("Complete:", finalResult);
	},
	onError: (error) => {
		// Called if streaming fails
		console.error("Stream error:", error);
	},
});

HTTP požadavky pomocí agentFetch

Pro jednorázové požadavky bez udržování připojení WebSocket:

import { agentFetch } from "agents/client";

// GET request
const response = await agentFetch({
	agent: "DataAgent",
	name: "instance-1",
	host: "my-worker.workers.dev",
});

const data = await response.json();

// POST request with body
const response = await agentFetch(
	{
		agent: "DataAgent",
		name: "instance-1",
		host: "my-worker.workers.dev",
	},
	{
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ action: "process" }),
	},
);
import { agentFetch } from "agents/client";

// GET request
const response = await agentFetch({
	agent: "DataAgent",
	name: "instance-1",
	host: "my-worker.workers.dev",
});

const data = await response.json();

// POST request with body
const response = await agentFetch(
	{
		agent: "DataAgent",
		name: "instance-1",
		host: "my-worker.workers.dev",
	},
	{
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ action: "process" }),
	},
);

Kdy použít agentFetch vs WebSocket:

Použijte agentFetch Použijte useAgent/AgentClient
Jednorázové požadavky Potřeba aktualizací v reálném čase
Volání mezi servery Obousměrná komunikace
Jednoduché REST API Synchronizace stavu
Není potřeba trvalé připojení Více volání RPC

Integrace serveru MCP

Pokud váš agent používá servery MCP (Model Context Protocol), můžete dostávat aktualizace o jejich stavu:

const agent = useAgent({
	agent: "AssistantAgent",
	name: "session-123",
	onMcpUpdate: (mcpServers) => {
		// mcpServers is a record of server states
		for (const [serverId, server] of Object.entries(mcpServers)) {
			console.log(`${serverId}: ${server.connectionState}`);
			console.log(`Tools: ${server.tools?.map((t) => t.name).join(", ")}`);
		}
	},
});
const agent = useAgent({
	agent: "AssistantAgent",
	name: "session-123",
	onMcpUpdate: (mcpServers) => {
		// mcpServers is a record of server states
		for (const [serverId, server] of Object.entries(mcpServers)) {
			console.log(`${serverId}: ${server.connectionState}`);
			console.log(`Tools: ${server.tools?.map((t) => t.name).join(", ")}`);
		}
	},
});

Zpracování chyb

Chyby připojení

const agent = useAgent({
	agent: "MyAgent",
	onError: (error) => {
		console.error("WebSocket error:", error);
	},
	onClose: () => {
		console.log("Connection closed, will auto-reconnect...");
	},
});
const agent = useAgent({
	agent: "MyAgent",
	onError: (error) => {
		console.error("WebSocket error:", error);
	},
	onClose: () => {
		console.log("Connection closed, will auto-reconnect...");
	},
});

Chyby RPC

try {
	const result = await agent.call("riskyMethod", [data]);
} catch (error) {
	// Error thrown by the agent method
	console.error("RPC failed:", error.message);
}
try {
	const result = await agent.call("riskyMethod", [data]);
} catch (error) {
	// Error thrown by the agent method
	console.error("RPC failed:", error.message);
}

Chyby streamování

await agent.call("streamingMethod", [data], {
	onChunk: (chunk) => handleChunk(chunk),
	onError: (errorMessage) => {
		// Stream-specific error handling
		console.error("Stream error:", errorMessage);
	},
});
await agent.call("streamingMethod", [data], {
	onChunk: (chunk) => handleChunk(chunk),
	onError: (errorMessage) => {
		// Stream-specific error handling
		console.error("Stream error:", errorMessage);
	},
});

Osvědčené postupy

1. Používejte typované stuby

// Prefer this:
const user = await agent.stub.getUser(id);

// Over this:
const user = await agent.call("getUser", [id]);
// Prefer this:
const user = await agent.stub.getUser(id);

// Over this:
const user = await agent.call("getUser", [id]);

2. Opětovné připojení probíhá automaticky

Klient se automaticky znovu připojuje a agent při každém připojení automaticky odešle aktuální stav. Váš onStateUpdate callback se spustí s nejnovějším stavem, není potřeba žádná ruční resynchronizace. Pokud použijete asynchronní query funkce pro autentizaci se cache při odpojení automaticky zneplatní, což zajistí, že se při opětovném připojení načtou nové tokeny.

3. Optimalizujte ukládání dotazů do mezipaměti

// For auth tokens that expire hourly:
useAgent({
	query: async () => ({ token: await getToken() }),
	cacheTtl: 55 * 60 * 1000, // Refresh 5 min before expiry
	queryDeps: [userId], // Refresh if user changes
});
// For auth tokens that expire hourly:
useAgent({
	query: async () => ({ token: await getToken() }),
	cacheTtl: 55 * 60 * 1000, // Refresh 5 min before expiry
	queryDeps: [userId], // Refresh if user changes
});

4. Vyčistěte připojení

V čistém JS zavřete spojení po dokončení:

const client = new AgentClient({ agent: "MyAgent", host: "..." });

// When done:
client.close();
const client = new AgentClient({ agent: "MyAgent", host: "..." });

// When done:
client.close();

React useAgent automaticky zajišťuje úklid při odpojení komponenty.

Reference React hooku

UseAgentOptions

type UseAgentOptions<State> = {
	// Required
	agent: string; // Agent class name

	// Optional
	name?: string; // Instance name (default: "default")
	host?: string; // Custom host
	path?: string; // Custom path prefix

	// Query parameters
	query?: Record<string, string> | (() => Promise<Record<string, string>>);
	queryDeps?: unknown[]; // Dependencies for async query
	cacheTtl?: number; // Query cache TTL in ms (default: 5 min)

	// Callbacks
	onStateUpdate?: (state: State, source: "server" | "client") => void;
	onMcpUpdate?: (mcpServers: MCPServersState) => void;
	onOpen?: () => void;
	onClose?: () => void;
	onError?: (error: Event) => void;
	onMessage?: (message: MessageEvent) => void;
};

Návratová hodnota

useAgent hook vrací objekt s následujícími vlastnostmi a metodami:

Vlastnost/metoda Typ Popis
agent string Název agenta ve stylu kebab-case
name string Název instance
setState(state) void Odeslání stavu agentovi
call(method, args?, options?) Promise Volání metody agenta
stub Proxy Typovaná volání metod
send(data) void Odeslat nezpracovanou zprávu WebSocket
close() void Zavřít připojení
reconnect() void Vynucení opětovného připojení

Referenční dokumentace Vanilla JS

AgentClientOptions

type AgentClientOptions<State> = {
	// Required
	agent: string; // Agent class name
	host: string; // Worker host

	// Optional
	name?: string; // Instance name (default: "default")
	path?: string; // Custom path prefix
	query?: Record<string, string>;

	// Callbacks
	onStateUpdate?: (state: State, source: "server" | "client") => void;
};

Metody AgentClient

Vlastnost/metoda Typ Popis
agent string Název agenta ve stylu kebab-case
name string Název instance
setState(state) void Odeslání stavu agentovi
call(method, args?, options?) Promise Volání metody agenta
send(data) void Odeslat nezpracovanou zprávu WebSocket
close() void Zavřít připojení
reconnect() void Vynucení opětovného připojení

Klient navíc podporuje posluchače událostí WebSocket:

client.addEventListener("open", () => {});
client.addEventListener("close", () => {});
client.addEventListener("error", () => {});
client.addEventListener("message", () => {});
client.addEventListener("open", () => {});
client.addEventListener("close", () => {});
client.addEventListener("error", () => {});
client.addEventListener("message", () => {});

Události nástrojů agenta

Pokud vaše chatovací UI vykresluje uchované běhy potomků z Agents jako nástroje, použijte useAgentToolEvents() společně s useAgent() a useAgentChat(). Hook se přihlásí k odběru nadřazeného připojení, přehraje uchované časové osy podřízených procesů a seskupí běhy podle ID volání nadřazeného nástroje.

import { useAgent, useAgentToolEvents } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";

const agent = useAgent({ agent: "Assistant", name: userId });
const { messages } = useAgentChat({ agent });
const agentTools = useAgentToolEvents({ agent });
import { useAgent, useAgentToolEvents } from "agents/react";
import { useAgentChat } from "@cloudflare/ai-chat/react";

const agent = useAgent({ agent: "Assistant", name: userId });
const { messages } = useAgentChat({ agent });
const agentTools = useAgentToolEvents({ agent });

Další kroky

Směrování

Vzory URL adres a možnosti vlastního směrování.

Volatelné metody

RPC přes WebSocket pro volání metod mezi klientem a serverem.

Autentizace mezi doménami

Zabezpečte WebSocket připojení napříč doménami.

Sestavte chatovacího agenta

Kompletní integrace klienta s AI chatem.