Skip to content

React Hooks

Import browser hooks from @uclaw/sdk/react.

tsx
import { useApp, useAgent } from "@uclaw/sdk/react";

Use short-lived client tokens in browser code. Never expose a uc_live_ API key to the client.

useApp

useApp connects to the app directory and exposes app-level management.

tsx
const app = useApp({
  appId: "default",
});

// Note: By default, getToken will automatically fetch from `/api/uclaw/client-tokens`.
// If you need custom auth logic, you can specify it:
// const app = useApp({ getToken: () => fetchToken() });

Options

ts
interface UseAppOptions {
  url?: string;
  token?: string;
  /** Fetches a short-lived client token. Defaults to fetching from `/api/uclaw/client-tokens` (or `api.uclaw.dev` on *.uclaw.dev domains). */
  getToken?: () => Promise<string>;
  appId?: string;
}

Return Value

ts
interface UseAppReturn {
  agents: AgentSummary[];
  createAgent: (opts?: CreateAgentInput) => Promise<AgentSummary>;
  deleteAgent: (id: string) => Promise<void>;
  renameAgent: (id: string, title: string) => Promise<void>;
  status: "connecting" | "connected" | "disconnected";
  generateText: (prompt: string, opts?: TextGenerationOptions) => Promise<string>;
  streamText: (prompt: string, opts?: TextGenerationOptions) => AsyncGenerator<string>;
  error: Error | null;
}

useAgent

useAgent connects to one active agent and exposes chat plus configuration RPCs.

tsx
function Chat({ agentId }: { agentId: string }) {
  const { chat, status } = useAgent({
    agentId,
  });

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        chat.sendMessage({
          role: "user",
          parts: [{ type: "text", text: "Hello!" }],
        });
      }}
    >
      <p>Status: {status}</p>
      <button disabled={chat.isStreaming}>Send</button>
    </form>
  );
}

Options

ts
interface UseAgentOptions {
  url?: string;
  agentId: string;
  token?: string;
  /** Fetches a short-lived client token. Defaults to fetching from `/api/uclaw/client-tokens` (or `api.uclaw.dev` on *.uclaw.dev domains). */
  getToken?: () => Promise<string>;
  appId?: string;
  config?: AgentConfig;
}

Return Value

ts
interface UseAgentReturn {
  chat: ReturnType<typeof useAgentChat>;
  status: "connecting" | "connected" | "disconnected";
  error: Error | null;
  updateConfig: (config: AgentConfig) => Promise<void>;
  currentConfig: () => Promise<AgentConfig>;
}

Creating and Opening an Agent

tsx
const { agents, createAgent } = useApp({});

async function newAgent() {
  const summary = await createAgent({
    title: "Support assistant",
    config: {
      instructions: "Answer customer support questions.",
      modelTier: "fast",
    },
  });
  setAgentId(summary.id);
}

Then pass agentId to useAgent.