Your LLM agent sends links instead of reading them out
November 1, 2026 · release
@voicethere/agent 0.22.0 · @voicethere/client 0.18.0
Ask a docs assistant where pricing is explained and a good answer includes the page. Spoken, that page comes out as "https colon slash slash" and a string of dots, which nobody on a call can use. So the agent used to be told to describe the address in words, and the caller still had to type it.
With @voicethere/agent 0.22.0 the agent takes every URL out of the reply before it goes to speech. The caller hears the sentence; the client gets each https link once, as an assistant_content message with the same turnId as the reply, before that turn's assistant_done. A markdown link keeps its label in the sentence and sends it along as label. Plain http:// links are removed and never sent.
Two settings shape which links go out:
links.requireToolSource: truesends only URLs that appeared in a tool result of the same turn, so a docs assistant cannot link to a page it made up.ctx.sendContent({ kind: "link", url, label })lets a hook or tool send a link of its own through the same path.
A docs assistant gets the most from this with toolChoice: "required-first-round", which makes the first model call of every turn search before it answers, so there is a real page to link to. It needs tools.maxRounds of 2 or more.
On the browser side, @voicethere/client 0.18.0 calls onAgentContent with { turnId, spoken, content } for each link and parseAgentContentEvent checks a raw message the same way. The embed widget shows links in its transcript, and the assistant chat on our landing page shows the link under the answer it belongs to.
The message format and settings are in LLM agents: links in replies. For a docs search agent, Docs knowledge base (RAG) shows how search results become links.