glove-react

Complete API reference for the React bindings package. Provides a declarative, hook-based interface for building agent-powered applications.

GloveClient

Central configuration object. Created once and passed to GloveProvider. Holds defaults for system prompt, tools, model/store factories, compaction, and subscribers.

typescript
import { GloveClient } from "glove-react";

const client = new GloveClient({
  endpoint: "/api/chat",
  systemPrompt: "You are a helpful assistant.",
  tools: [/* ... */],
  compaction: {
    compaction_instructions: "Summarize the conversation so far.",
    max_turns: 20,
  },
  subscribers: [],
});

Constructor

new GloveClient(config: GloveClientConfig)

GloveClientConfig

PropertyTypeDescription
endpoint?stringURL of the chat endpoint. Used by the default createEndpointModel factory. Mutually exclusive with createModel.
createModel?() => ModelAdapterFactory function that returns a ModelAdapter. Overrides endpoint when provided.
createStore?(sessionId: string) => StoreAdapterFactory function that returns a StoreAdapter for a given session. Defaults to in-memory MemoryStore.
systemPrompt?stringDefault system prompt sent with every model request.
tools?ToolConfig[]Array of tool definitions available to the agent.
compaction?CompactionConfigConfiguration for context window compaction. See CompactionConfig.
subscribers?SubscriberAdapter[]Array of subscriber adapters that receive streaming events.

Instance Properties

PropertyTypeDescription
systemPrompt?stringThe system prompt provided at construction.
tools?ToolConfig[]Tool definitions provided at construction.
compaction?CompactionConfigCompaction configuration provided at construction.
subscribers?SubscriberAdapter[]Subscriber adapters provided at construction.

Methods

MethodReturnsDescription
resolveModel()ModelAdapterReturns the model adapter. Uses createModel factory if provided, otherwise creates an endpoint model from endpoint. Marked @internal.
resolveStore(sessionId)StoreAdapterReturns a store adapter for the given session ID. Uses createStore factory if provided, otherwise creates a MemoryStore. Marked @internal.

GloveProvider

React context provider that makes a GloveClient available to all descendant components via useGloveClient() and useGlove().

tsx
import { GloveProvider } from "glove-react";

function App() {
  return (
    <GloveProvider client={client}>
      <ChatInterface />
    </GloveProvider>
  );
}
PropTypeDescription
clientGloveClientThe GloveClient instance to provide to the component tree.
childrenReactNodeChild components that can access the client via hooks.

useGlove

The primary hook for interacting with a Glove agent. Returns the full agent state and action methods. Can be called with no arguments to inherit everything from the nearest GloveProvider, or with a config object to override specific fields.

tsx
import { useGlove } from "glove-react";

function Chat() {
  const {
    timeline,
    streamingText,
    busy,
    slots,
    tasks,
    stats,
    sendMessage,
    abort,
    renderSlot,
    resolveSlot,
    rejectSlot,
  } = useGlove();

  return (
    <div>
      {timeline.map((entry, i) => (
        <div key={i}>
          {entry.kind === "user" && <p>{entry.text}</p>}
          {entry.kind === "agent_text" && <p>{entry.text}</p>}
          {entry.kind === "tool" && <p>Tool: {entry.name}</p>}
        </div>
      ))}
      {streamingText && <p>{streamingText}</p>}
      {slots.map(renderSlot)}
    </div>
  );
}

Signature

typescript
function useGlove(config?: UseGloveConfig): UseGloveReturn

UseGloveConfig

All fields are optional. When omitted, values are inherited from the nearest GloveClient via context.

PropertyTypeDescription
endpoint?stringOverride the chat endpoint URL for this hook instance.
sessionId?stringSession identifier. Different IDs produce independent conversation histories.
store?StoreAdapterOverride the store adapter for this hook instance.
model?ModelAdapterOverride the model adapter for this hook instance.
systemPrompt?stringOverride the system prompt for this hook instance.
tools?ToolConfig[]Override the tool definitions for this hook instance.
compaction?CompactionConfigOverride compaction configuration for this hook instance.
subscribers?SubscriberAdapter[]Override subscribers for this hook instance.

UseGloveReturn

Extends GloveState with action methods.

PropertyTypeDescription
busybooleanTrue while the agent is processing a request (prompting the model or executing tools).
timelineTimelineEntry[]Ordered list of conversation entries: user messages, agent text responses, and tool invocations.
streamingTextstringAccumulated text from the current streaming model response. Empty string when not streaming.
tasksTask[]Current task list managed by the agent via the built-in task tool.
slotsSlot<unknown>[]Active display stack slots pushed by tools via pushAndWait or pushAndForget.
statsGloveStatsCumulative usage statistics for the current session.
sendMessage(text, images?)voidSend a user message to the agent. Optionally include images as Array<{ data: string; media_type: string }>. No-op if busy is true.
abort()voidAbort the current agent request. Triggers AbortError in the agent loop.
resolveSlot(slotId, value)voidResolve a pushAndWait slot with a value, unblocking the tool that created it.
rejectSlot(slotId, reason?)voidReject a pushAndWait slot with an optional reason string, causing the tool's pushAndWait call to throw.
renderSlot(slot)ReactNodeRender a slot using its associated renderer. Returns null if no renderer is registered for the slot's renderer key.

useGloveClient

Returns the nearest GloveClient from context, or null if no GloveProvider is present. This is an internal hook used by useGlove.

tsx
import { useGloveClient } from "glove-react";

function DebugPanel() {
  const client = useGloveClient();
  if (!client) return <p>No GloveProvider found.</p>;
  return <pre>{client.systemPrompt}</pre>;
}

Signature

typescript
function useGloveClient(): GloveClient | null

ToolConfig

Defines a tool that the agent can invoke. Combines the schema (for the model) with the implementation (for the runtime) and an optional React renderer (for the display stack).

PropertyTypeDescription
namestringUnique tool name. The model uses this to identify which tool to call.
descriptionstringHuman-readable description of what the tool does. The model reads this to decide when to use the tool.
inputSchemaz.ZodType<I>Zod schema defining the tool's input shape. Converted to JSON Schema for the model and used for runtime validation.
do(input: I, display: ToolDisplay) => Promise<unknown>The tool's implementation. Receives validated input and a display adapter for pushing UI slots. Return value is sent back to the model as the tool result.
render?(props: SlotRenderProps) => ReactNodeOptional React component for rendering this tool's display slots. When provided, the framework auto-registers a renderer keyed by the tool name.
requiresPermission?booleanWhen true, the agent will check the store for permission before executing this tool. Defaults to false.
typescript
import { z } from "zod";
import type { ToolConfig } from "glove-react";

const weatherTool: ToolConfig<{ city: string }> = {
  name: "get_weather",
  description: "Get current weather for a city.",
  inputSchema: z.object({ city: z.string() }),
  async do(input) {
    const res = await fetch(`https://api.weather.example/v1?city=${input.city}`);
    return res.json();
  },
};

ToolDisplay

The display adapter passed as the second argument to a tool's do function. Provides methods to push UI slots onto the display stack.

MethodReturnsDescription
pushAndWait<I, O>(slot)Promise<O>Push a slot onto the display stack and block until the user resolves or rejects it. The slot object has optional renderer (string) and required input (I). Returns the resolved value of type O.
pushAndForget<I>(slot)Promise<string>Push a slot onto the display stack without blocking. Returns the slot ID. The slot object has optional renderer (string) and required input (I).
tsx
const confirmTool: ToolConfig<{ message: string }> = {
  name: "confirm",
  description: "Ask the user to confirm an action.",
  inputSchema: z.object({ message: z.string() }),
  async do(input, display) {
    const confirmed = await display.pushAndWait<{ message: string }, boolean>({
      input,
    });
    return confirmed ? "User confirmed." : "User declined.";
  },
  render({ data, resolve }) {
    return (
      <div>
        <p>{data.message}</p>
        <button onClick={() => resolve(true)}>Yes</button>
        <button onClick={() => resolve(false)}>No</button>
      </div>
    );
  },
};

SlotRenderProps

Props passed to a tool's render function when rendering a display slot.

PropertyTypeDescription
dataTThe input data that was passed to pushAndWait or pushAndForget.
resolve(value: unknown) => voidCall this to resolve the slot. For pushAndWait slots, the value is returned to the tool. For pushAndForget slots, this removes the slot from the stack.

TimelineEntry

A discriminated union representing one entry in the conversation timeline. The kind field determines the shape.

typescript
type TimelineEntry =
  | { kind: "user"; text: string; images?: string[] }
  | { kind: "agent_text"; text: string }
  | { kind: "tool"; id: string; name: string; input: unknown; status: "running" | "success" | "error"; output?: string };
KindFieldsDescription
"user"text, images?A user message. May include optional image data URLs (string[]).
"agent_text"textA text response from the agent (model output).
"tool"id, name, input, status, output?A tool invocation. Shows the tool name, its input arguments, execution status, and optional output.

GloveState

The reactive state object that drives the UI. All properties in UseGloveReturn are inherited from this type plus the action methods.

PropertyTypeDescription
busybooleanWhether the agent is currently processing a request.
timelineTimelineEntry[]Full conversation timeline for rendering.
streamingTextstringCurrent streaming text buffer. Empty when idle.
tasksTask[]Current task list maintained by the agent.
slotsSlot<unknown>[]Active display stack slots awaiting render.
statsGloveStatsCumulative session statistics: turns, tokens in, tokens out.

GloveStats

PropertyTypeDescription
turnsnumberNumber of completed agent turns in this session.
tokens_innumberTotal input tokens consumed across all model calls.
tokens_outnumberTotal output tokens generated across all model calls.

CompactionConfig

Controls automatic context window compaction. When the conversation exceeds limits, it is summarized and the history is replaced with the summary to free up context space.

PropertyTypeDescription
compaction_instructionsstringInstructions given to the model when summarizing the conversation. Required.
max_turns?numberMaximum number of turns before compaction is triggered.
compaction_context_limit?numberMaximum token count before compaction is triggered.

MemoryStore

An in-memory implementation of StoreAdapter. Data is lost when the page is refreshed. Useful for prototyping and ephemeral sessions.

typescript
import { MemoryStore } from "glove-react";

const store = new MemoryStore("session-1");
PropertyTypeDescription
identifierstringThe session identifier passed to the constructor.

Implements the full StoreAdapter interface: messages, token counts, turn counts, tasks, and permissions are all stored in memory.

createRemoteStore

Factory function that creates a StoreAdapter backed by remote async functions. Delegates every store operation to user-provided action functions, enabling persistence on any backend.

typescript
import { createRemoteStore } from "glove-react";

const store = createRemoteStore("session-123", {
  async getMessages(sessionId) {
    const res = await fetch(`/api/sessions/${sessionId}/messages`);
    return res.json();
  },
  async appendMessages(sessionId, messages) {
    await fetch(`/api/sessions/${sessionId}/messages`, {
      method: "POST",
      body: JSON.stringify(messages),
    });
  },
});

Signature

typescript
function createRemoteStore(
  sessionId: string,
  actions: RemoteStoreActions
): StoreAdapter

RemoteStoreActions

MethodTypeDescription
getMessages(sessionId: string) => Promise<Message[]>Fetch all messages for the session. Required.
appendMessages(sessionId: string, msgs: Message[]) => Promise<void>Append new messages to the session history. Required.
getTokenCount?(sessionId: string) => Promise<number>Get the current token count for the session.
addTokens?(sessionId: string, count: number) => Promise<void>Add to the cumulative token count.
getTurnCount?(sessionId: string) => Promise<number>Get the current turn count.
incrementTurn?(sessionId: string) => Promise<void>Increment the turn counter by one.
resetHistory?(sessionId: string) => Promise<void>Clear the conversation history (used during compaction).
getTasks?(sessionId: string) => Promise<Task[]>Fetch all tasks for the session.
addTasks?(sessionId: string, tasks: Task[]) => Promise<void>Add new tasks to the session.
updateTask?(sessionId: string, taskId: string, updates: Partial<Task>) => Promise<void>Update a specific task by ID.
getPermission?(sessionId: string, toolName: string) => Promise<PermissionStatus>Check the permission status for a tool.
setPermission?(sessionId: string, toolName: string, status: PermissionStatus) => Promise<void>Set the permission status for a tool.

createRemoteModel

Factory function that creates a ModelAdapter backed by user-provided async functions. Enables calling any model backend, whether it is a custom server, a proxy, or a third-party API.

typescript
import { createRemoteModel } from "glove-react";

const model = createRemoteModel("my-model", {
  async prompt(request) {
    const res = await fetch("/api/custom-llm", {
      method: "POST",
      body: JSON.stringify(request),
    });
    return res.json();
  },
});

Signature

typescript
function createRemoteModel(
  name: string,
  actions: RemoteModelActions
): ModelAdapter

RemoteModelActions

MethodTypeDescription
prompt(request: RemotePromptRequest, signal?: AbortSignal) => Promise<RemotePromptResponse>Send a prompt to the model and receive a complete response. Required.
promptStream?(request: RemotePromptRequest, signal?: AbortSignal) => AsyncIterable<RemoteStreamEvent>Send a prompt and receive a stream of events. When provided, the adapter uses streaming for real-time text output.

RemotePromptRequest

PropertyTypeDescription
systemPromptstringThe system prompt for this request.
messagesMessage[]The conversation history to send to the model.
tools?SerializedTool[]Tool definitions serialized as JSON Schema objects.

RemotePromptResponse

PropertyTypeDescription
messageMessageThe model's response message, including any tool calls.
tokens_innumberNumber of input tokens consumed by this request.
tokens_outnumberNumber of output tokens generated by this request.

RemoteStreamEvent

A discriminated union of server-sent event types. The type field determines the payload shape.

typescript
type RemoteStreamEvent =
  | { type: "text_delta"; text: string }
  | { type: "tool_use"; id: string; name: string; input: unknown }
  | { type: "done"; message: Message; tokens_in: number; tokens_out: number };
TypeFieldsDescription
"text_delta"textA chunk of streaming text from the model.
"tool_use"id, name, inputThe model is invoking a tool with the given name and input arguments.
"done"message, tokens_in, tokens_outThe stream is complete. Includes the final Message object and token counts.

SerializedTool

PropertyTypeDescription
namestringThe tool name.
descriptionstringThe tool description.
parametersRecord<string, unknown>JSON Schema representation of the tool's input parameters.

createEndpointModel

Creates a ModelAdapter that communicates with a server endpoint via SSE (Server-Sent Events). This is the default model adapter when using GloveClient with an endpoint URL. Compatible with endpoints created by glove-next's createChatHandler.

typescript
import { createEndpointModel } from "glove-react";

const model = createEndpointModel("/api/chat");

Signature

typescript
function createEndpointModel(endpoint: string): ModelAdapter

parseSSEStream

Utility function that parses a Response object containing SSE data into an async iterable of RemoteStreamEvent objects. Used internally by createEndpointModel and available for custom streaming implementations.

typescript
import { parseSSEStream } from "glove-react";

const response = await fetch("/api/chat", { method: "POST", body: "..." });

for await (const event of parseSSEStream(response)) {
  if (event.type === "text_delta") {
    process.stdout.write(event.text);
  }
}

Signature

typescript
function parseSSEStream(response: Response): AsyncIterable<RemoteStreamEvent>

Re-exported Types

The following types are re-exported from glove-core for convenience. See the glove-core reference for full details.

TypeSourceDescription
Taskglove-coreA tracked task with id, content, activeForm, and status.
ContentPartglove-coreA multimodal content part (text, image, video, document).
Slotdisplay-managerA display stack slot with id, renderer key, and input data.
StoreAdapterglove-coreInterface for conversation persistence backends.
ModelAdapterglove-coreInterface for language model providers.
SubscriberAdapterglove-coreInterface for event observers (logging, streaming, analytics).