Skip to content
OpenComputer
Concepts

Reactive agents

Render instructions and capabilities from the current input

An agent is a synchronous TypeScript function that returns instructions. The OpenComputer runtime owns the durable conversation, streaming model calls, tool loop, and continuation. Your function calculates the agent configuration for the current render.

export default function Agent() {
  return "You are a helpful assistant.";
}

This keeps ordinary TypeScript control flow available. Hooks may be called conditionally, so a capability can be attached only when the current request needs it.

Hooks

HookCurrent value or effect
useInput()Reads the current source, text, and optional structured payload
useCurrentInput()Alias for useInput()
useModel(model)Selects a model using provider/model notation
useTool(tool)Makes a named or code-defined tool available
useMcpServer(server)Attaches a managed HTTPS MCP server
useSessionData(key)Reads a value previously stored in the current session
useMemory(memory)Reads bound memory and selects its permitted tools

useInput() is not a human-in-the-loop prompt. It describes the input that caused the current render. See Inputs for its text, payload, and source metadata.

Conditional configuration

import {
  useInput,
  useModel,
  useTool,
} from "@opencomputer/agent";

export default function Agent() {
  const input = useInput();
  useModel("anthropic/claude-sonnet-4.6");

  if (input.text?.includes("research")) {
    useTool("web-search");
  }

  return "Answer directly. Research and verify when those capabilities exist.";
}

The hook calls describe capabilities for the next model step; they do not run the model or tool themselves.

Define a tool

Tools are TypeScript values with JSON Schema inputs and an asynchronous or synchronous run function. Put the implementation beside the agent, for example at opencomputer/agents/hello-world/tools/hacker-news.ts:

import { defineTool } from "@opencomputer/agent";

export const latestStories = defineTool({
  name: "latest_hacker_news_stories",
  description: "Fetch the current top Hacker News stories",
  input: {
    type: "object",
    properties: { limit: { type: "number" } },
  },
  async run({ input, signal, reportProgress }) {
    await reportProgress({ status: "fetching" });
    const limit = Number(input.limit ?? 10);
    const ids = await fetch(
      "https://hacker-news.firebaseio.com/v0/topstories.json",
      { signal },
    ).then((response) => response.json() as Promise<number[]>);
    return ids.slice(0, limit);
  },
});

Import and attach it from agent.ts:

import { useTool } from "@opencomputer/agent";
import { latestStories } from "./tools/hacker-news";

export default function Agent() {
  useTool(latestStories);
  return "Use the Hacker News tool when the user asks for current stories.";
}

Tool names may contain letters, numbers, underscores, and hyphens. Tool code runs in the managed agent runtime, not in the browser.

Skills

Skills are reusable instruction bundles. Add a skill only when an agent needs one:

opencomputer/agents/hello-world/skills/code-review/SKILL.md

Skills in an agent’s skills/ directory are packaged with that agent and can be loaded by the runtime when their description matches the task. Unlike tools, skills provide instructions and supporting resources rather than a callable JSON Schema function.

Models

Use provider/model strings:

useModel("anthropic/claude-sonnet-4.6");

An object form is also supported:

useModel({ provider: "anthropic", model: "claude-sonnet-4.6" });

Provider credentials are managed by OpenComputer and are not placed in agent source or the React application.

Continue with Agent hooks, then use the focused guides for inputs, models, tools, MCP servers, skills, and session data.