An open-source TypeScript framework for AI-powered apps. You define tools — things your app can do. An AI agent decides when to use them based on what users ask for.
Works with OpenAI, Anthropic, and more. Free and open source.
The idea
Traditional apps encode user flows in UI — pages, routes, navigation hierarchies. Glove replaces that wiring with an agent. The developer defines capabilities. The agent does the orchestration.
Every action your app can take — search, checkout, track an order — is a tool. The agent decides when to call them based on what the user asks for.
Product grids, forms, confirmation dialogs — they're all renderers on a display stack. Tools push them. The agent orchestrates which ones appear and when.
No routes, no page transitions, no navigation state machines. The user says what they want. The agent figures out the path to get there.
Tools can pause and wait for user input. Permission requests, form submissions, confirmations — all first-class primitives, not afterthoughts.
Architecture
Built on adapters — interfaces that decouple the runtime from specific implementations. Swap models, stores, or UI frameworks without changing application logic.
The display stack
A user asks to buy running shoes. Here's what happens inside the runtime — step by step.
“Find me running shoes under 100 bucks”
The agent interprets the intent and calls the search_products tool.
The search tool finds results and pushes a product grid to the display stack. The tool doesn't wait — it returns immediately.
pushAndForget({ renderer: "product_grid" })“Add the Nike ones to my cart and check out”
The agent calls add_to_cart, then checkout.
The checkout tool needs payment details. It pushes a payment form and waits. The tool's execution is suspended until the user submits.
pushAndWait({ renderer: "payment_form" })The form resolves with payment data. The checkout tool picks up where it left off, creates the order, and pushes a confirmation.
resolve(slot_id, paymentData)Developer experience
A tool is a function with a name and a schema. Register tools with .fold(). The agent figures out when to call them.
Simple — a weather tool
const client = new GloveClient({ endpoint: "/api/chat", systemPrompt: "You are a helpful weather assistant.", tools: [{ name: "get_weather", description: "Get current weather for a city", inputSchema: z.object({ city: z.string() }), async do(input) { return await fetchWeather(input.city); }, }], }); // That's a working AI app. // User says "weather in Tokyo" → agent calls get_weather → shows result.
Advanced — tools with interactive UI
const app = new Glove({ store, model, displayManager, systemPrompt: "You are a shopping assistant...", }) .fold({ name: "search_products", description: "Search the product catalog", inputSchema: z.object({ query: z.string() }), async do(input, display) { const results = await catalog.search(input.query); // Show a product grid — tool keeps running await display.pushAndForget({ renderer: "product_grid", input: results }); return results; }, }) .fold({ name: "checkout", description: "Start the checkout process", inputSchema: z.object({ cartId: z.string() }), async do(input, display) { const cart = await carts.get(input.cartId); // Show a payment form — tool PAUSES until user submits const payment = await display.pushAndWait({ renderer: "payment_form", input: cart }); return await orders.create(cart, payment); }, }) .build();
Adapters
Every layer is an interface. The runtime doesn't care what's behind it.
The AI provider. Anthropic, OpenAI, local models, or mocks for testing. Anything that takes messages and returns responses.
The persistence layer. Messages, tokens, turns. In-memory, SQLite, Postgres — wherever your state lives.
The UI state layer. Manages the display stack. Framework-agnostic — React, Vue, Svelte, terminal UI. Bind however you want.
The event bus. Logging, analytics, real-time streaming, debugging. Plug in whatever you need to observe.
Trade-offs
Glove is open source and ready to build on.