Hosted AI agents for SaaS products

The agent in your product should just work.

Tabs close, deploys ship, and people take a while to answer. Nvoken runs the model-and-tool loop for every customer, keeps their conversation and memory, waits for the person, and picks up exactly where it was. You write the instructions and the tools.

Start buildingv0.32.0
  • try it free
  • provider price + 5.5%
  • no plans, no other fees
models from
define the Agent, start a Turn
import { Client } from "@deepnoodle/nvoken";
import { lookupOrder, updateAddress, handlers } from "./tools";

const client = new Client();

const support = await client.agents.create({
  key: "support",
  instructions: "Help customers with their orders.",
  model: "anthropic/claude-sonnet-5",
  tools: [lookupOrder, updateAddress],
});

// In your request handler. One Turn per message.
const turn = await support
  .bindTools(handlers)
  .start(message, { tenant: customer.id, user: viewer.id });

for await (const { snapshot } of turn.updates()) {
  send(snapshot.status, snapshot.text);
}
import { defineHostTool, defineJsonSchema } from "@deepnoodle/nvoken";
import { db } from "./db";

export const lookupOrder = defineHostTool({
  mode: "host",
  name: "lookup_order",
  description: "Look up one order by ID.",
  inputSchema: defineJsonSchema({
    type: "object",
    properties: { orderId: { type: "string" } },
    required: ["orderId"],
    additionalProperties: false,
  }),
});

// updateAddress is declared the same way.
// Handlers run in your backend. Nvoken never sees your database.
export const handlers = {
  lookup_order: ({ orderId }) => db.orders.get(orderId),
  update_shipping_address: ({ orderId, address }, ctx) =>
    db.orders.reship(orderId, address, { key: ctx.toolCallId }),
};
model anthropic/claude-sonnet-5Open the quickstart

anatomy of an agent

HARNESS

The part that makes an agent reliable.

A model answers a prompt. An agent remembers the customer, calls your product's tools, works through several steps, and returns a result. The harness is everything around the model call that makes that hold up for real customers: the tool loop, the conversation, the memory, the retries, the waiting, the bill. Nvoken is that harness, hosted.

  • Your tools, your data

    Declare a tool. Nvoken relays each call to your backend, over the SDK or a signed callback. Your function, your database.

    mode: "host"
  • Conversations and memory

    Nvoken keeps each customer's conversation and memory between Turns. Your app sends the message, not the history.

    memory: { scope: "user" }
  • Keeps going, waits for people

    A Turn runs through your deploys and restarts, and waits for a person without holding anything open. Reconnect by ID and pick up where it was.

    client.turn(id, { tenant })
  • Every customer, accounted for

    Each Turn names its tenant. See what every customer spent, and set a spending limit per customer.

    tenant: customer.id

get started

Three steps to a working agent.

Read the full quickstart
  1. 01

    Create an App

    Sign up, create an App in the console, and issue an App key.

  2. 02

    Install the SDK

    One package for the Agent, its tools, Turns, streaming, and recovery. TypeScript, end to end.

  3. 03

    Send the first message

    Create the Agent and send it a message. The reply, tool calls, usage, and timing land in the console as one Turn.

You pay the provider's price plus 5.5%, and that is the whole bill. No plans, no other fees.

What stays in your app, what Nvoken runs

Ship the agent, not the harness.

Sign up, run the quickstart, and watch the first reply land in the console. The harness is already running underneath it.

  • try it free
  • provider price + 5.5%
  • no plans, no other fees
  • self-hosting on request