pinecall personas
The simulated callers: Pinecall's library switched on or off, your own written or generated, each with what it expects.
pinecall personas [list] | show <name> | try <name> | on <name> | off <name>
pinecall personas add <name> --goal '…' --style '…' [--about '…'] [--fact 'what=said']… [--expect '…']…
pinecall personas edit <name> [--goal '…'] [--style '…'] [--about '…'] [--fact 'what=said']… [--rename <name>]
… add and edit also take [--llm x] [--tts x] [--voice x] [--tag x]… [--interrupts 0-1] [--pause s]
pinecall personas generate [N] [--about '…'] [--from-call <call>] [--template <name>] [--save]
pinecall personas rm <name> · pinecall personas push [--from test/<agent>/personas]
… any of them with --json, --prod in production, and --agent <name> or
--file agent.tsx when the project holds more than one agent
The callers are the AGENT's, kept by the gateway — one list per agent, the same in both environments: the patient who cancels is the clinic's, and another agent of the org has callers of its own, even under the same name. So the console shows the same ones this verb does, a caller written here needs no deploy, and a project holds none of them in its repository.
Pinecall's library comes first, each one off until pinecall personas on <name> switches it
on for the agent (the nightly plays what is on): realism — in-a-hurry, wrong-number,
non-native, interrupts, changes-mind, elderly-slow, angry-repeat-caller,
asks-for-a-person — and a red team — prompt-leak, data-leak, off-task, harmful,
unauthorized-action. One of them is never dropped (rm says to switch it off) nor written: write
your own under another name.
$ pinecall personas
in-a-hurry pinecall off A caller with two minutes who wants it done.
prompt-leak pinecall on A caller who tries to get the agent's instructions.
…
hurried yours move the appointment to Tuesday
suspicious yours find out the price of a crown
$ pinecall personas add price-shopper --goal "get a price for a deep clean" \
--style "blunt, impatient" --fact "their name=Tom Baker"
price-shopper written · 3 persona(s)
add writes one whole; edit changes what is named and leaves the rest, and --rename moves it
to another name. --llm, --tts and --voice say how the caller is played, in the words
agent set takes for the agent — the model that improvises it, the vendor and the voice its lines
are read in — and a vendor or a voice the platform does not have is refused when it is written. Unset,
the runtime chooses: its default model, and a voice the agent does not have; edit --voice ''
clears one back. --expect '…', repeated, is what the caller expects of the agent, one verifiable
line each, written "The agent should …": the expected-outcome judge holds every call of theirs to
them at hang-up, and the model playing them is never told. --interrupts 0.4 makes a spoken caller
talk over that share of the agent's answers, some way into them — so the agent's barge-in is tested
for real — and --pause 2 leaves two seconds of silence before each of their lines. show prints
what they expect and how they act, and says so when they expect nothing. show prints one with every fact; rm drops it; try puts it on the class in
this directory, which is simulate without the judge. A name is lower-case letters and digits
joined by hyphens, as --persona takes it — anything else is refused here, with exit 2, before it
travels. A caller nobody wrote is the same sentence and the same exit 2 from show, edit,
rm and try.
Every verb names the agent whose callers it reads and writes: the project's one agent, by the
slug its folder's name, or the one --agent names (--file names the class
by its path). A project of several with nobody named is refused with the names, and an agent the
project does not have is refused before the gateway is asked. try calls that agent as the
caller, and push sends that agent's files as its callers. --json prints what
the gateway answered — the caller for show, the roster ({"personas": […]}) for list, add,
edit, rm and push; try prints a call as it happens, has no answer to print, and refuses the
flag with exit 2.
generate asks the judge model to write callers for the agent — N of them (3 unless said,
up to 10) — from its prompt, its tools and its knowledge; --about steers them, --from-call makes
them like a real call's caller, --template writes one of the library's again for this agent. Each
comes with what it expects. They are printed and saved nowhere; --save keeps every one as the
agent's own. Each caller written is one eval, none when your judges run on your own key.
push is the migration, run once per project: the personas a project still keeps as files —
test/<agent>/personas/*.ts — are sent to the gateway, evaluated as they load, so a file that
computed its state from lib/ lands as the value it produced. The files are yours to delete
afterwards; the verb never touches them. A caller the gateway refuses stops the push where it
stands: what landed and what is still only a file are both named, and it exits 2 — nothing is
undone, and pushing again once it is fixed finishes the migration.