@nom-ai/sdk
Connect AI tool calls to React component props.
An agent loads data into components already in your application. You define the tools, validate their inputs and outputs, and map results to props — your app keeps the model, the fetching, the authorization, and the rendering.
Show sales and orders from July 1 to July 15
Sales
$340,326
2,697 orders · Jul 1–15
status: success
Orders
status: loading
You define the contract
A tool declares its input and output schemas, how to execute, and how the result becomes props. Validation runs at runtime even when a provider reports strict tool calling, and again in the browser before anything reaches a component.
Full walkthrough →const searchProducts = defineAgentTool({
key: "search-products",
inputSchema: z.object({ query: z.string() }),
outputSchema: z.object({ products: z.array(productSchema) }),
execute: ({ query }) => fetch(`/api/products?q=${query}`).then((r) => r.json()),
mapOutput: ({ products }) =>
products.length === 0
? { status: "empty" }
: { status: "success", props: { products } },
});Five states, not two
idle, loading, success, empty, and failure. “Matched nothing” is its own state, so you never infer it from a zero-length list.
Instances, not types
Two copies of the same component stay independently addressable. Duplicate IDs are rejected loudly rather than silently overwriting each other.
The model is not trusted
Mounting changes discoverability, not authorization. Component data reaches the model only through a projection you write.