@vendoai/agents is Vendo’s agent runtime on its own: your tools, one guard,
one store, and a brain — with none of the umbrella’s client surface. You
compose it once and reach it through exactly two verbs.
Everything else — approvals, risk grading, audit, threads — is the same guard
the rest of Vendo runs through. There is no second authority path.
Install
vendo init writes .vendo/tools.json — your API read into tool definitions,
each with a schema, a risk grade, and its dispatch binding — which is what
api() serves. Full inventory: vendo init.
Compose it
Seven lines, and onlyname is required:
harness is optional and defaults to vendo(), the in-process loop. Pass
claudeCode() instead when you want Claude Code thinking on a sandbox machine
— see Reference.
Answer a person
respond() is one turn: an AI-SDK UI-message-stream Response, ready to
return from a route as-is.
x-vendo-thread-id. Send it back as threadId on the
next turn and the conversation continues — see
Converse.
Two credential paths
Pick one. They are the same ladder everywhere in Vendo: what you pass always wins, andVENDO_API_KEY fills only the slots you left unset.
Vendo Cloud — vendo login
VENDO_API_KEY into .env.local — never printed. It fills the
model seat (through the Cloud gateway) and the sandbox. The store is not
one of them: there is no Cloud store rung today, so with a key set you
pass one — store: postgres(url) — or agent() refuses to boot.No Vendo key — bring your own
store and you get the embedded one instead. ANTHROPIC_API_KEY is what
the provider you construct authenticates with. It selects nothing on its
own.model is the default seat the built-in vendo() harness thinks with.
claudeCode() brings its own brain and ignores it.
Testing
Swap the brain for a scripted one.defineHarness is the same authoring seam
a real harness uses, so nothing else in the composition changes — the guard,
the tools, and the store are all the ones that ship.
defineHarness lives in @vendoai/harnesses. Add it as a devDependency —
under strict package linking, importing from a package you have not declared
is a TS2307.The three jobs
Converse with a user
respond() behind a chat route, with your API as tools and a risk-labeled
write of your own.Call it like a function
run() with an output schema returns typed data, and usage is what you
meter on.Ship it as a product surface
Forward
run.events to your own UI over SSE and end on the report.Reference
Every option, every field, every exported name.
Tools and safety
Risk labels, approvals, grants, and the audit trail behind both verbs.