respond() is one turn of that conversation: an
AI-SDK UI-message-stream Response you return from a route unchanged.
Give it hands
api() is your own API — .vendo/tools.json, layered overrides, and
present-user header forwarding. tool() is anything you would rather write
yourself, with its own auth model.
read, write, or destructive — your label is final,
and it is what decides whether a call runs or stops for the person. Leave it
off and the tool is ungraded, which the guard treats like destructive and
asks about every time. Details:
Tools and safety.
Scope it to the caller. The orderId came from the model; ctx.principal
is who the turn acts as. Bind the two yourself — api() forwards the caller’s
credentials for you, but a hand-written tool() reaches your data on its own
terms, and an unscoped lookup will act on someone else’s order no matter how
the approval card was answered.
The route
user.idis the subject. Every thread, every workspace file, and every audit row is scoped to it. Vendo mints no identity of its own.headers: req.headersforwards the caller’s own credentials, so a tool call reaches your API as the person who is signed in — not as the agent.useris server-trusted identity the model may read ([User]in the prompt). It is facts, not instructions. Free-form background the model should treat as observation goes incontextinstead.
Continue the conversation
The response carries the thread id inx-vendo-thread-id. Keep it and hand it
back:
threadId is checked against the same subject that owns it. Someone else’s
thread — or one that never existed — is not-found, never a silent new
conversation.
Approvals, with a person present
An interactive turn can stop for the human. Adestructive or ungraded call
raises an approval, the stream carries the card, and the turn waits about 90
seconds for a decision. Approve and the call re-dispatches byte-for-byte; deny
and the model is told so and carries on.
Call it like a function
The same agent, unattended, through the other verb.
Reference
Every
RespondOptions key and its type.