UNLEASH AI tools: how each one works
Contents
- First: what a tool actually is
- A. Semantic search: nine tools share one engine
- B.
agendaLookup: exact agenda questions - C.
badgesLookup: pass facts and verified prices - D.
pageDirectory: exact event pages and booking destinations - E.
recentArticles: recency is enforced by the query - F.
upcomingWebinars: future events, soonest first - G.
buildAgenda: a planner, not free-form model generation - H.
submitLead: the external enquiry handoff - I.
sendAgendaByEmail: validate the selection before dispatch - J.
eventFacts: complete, source-backed policy answers - Where to inspect or change each part
Updated 5 October 2026. The registry now contains 18 tools. October changes are locally tested, not deployed. Earlier extracts retain their September snapshot context; current extracts/evidence are in the fix record. This describes implementation, not verified live configuration. Examples below are illustrative tool inputs, not recorded executions.
First: what a tool actually is
A tool has a name, a description explaining when to use it, a typed input schema, and a server-side execute function. The conversational model requests a tool with arguments; the server executes the code and returns a structured result. The model can then explain that result or call another permitted tool. It does not gain arbitrary database, browser, or email access.
Jev chooses the workflow destination, not every individual tool. The conversational model normally chooses tools within that destination. Some paths use deterministic replies or force the appropriate handoff tool. A request is limited to eight model/tool steps.
Before generation, available tools are narrowed by event/surface, workflow destination, consent, and published Sanity switches. Prompt instructions are filtered too. A description saying “ALWAYS use this tool” is model guidance; registry filtering and execution-time permission checks are code enforcement.
A. Semantic search: nine tools share one engine
Common input: { "query": "Is there a cloakroom at the venue?" }.
The query is embedded, then searched against the selected Pinecone stores. The wrapper over-fetches candidates, removes known refusal-template text, caps repeated chunks from a page at two, and returns the best remaining results. Most search tools return up to six hits; agenda semantic search returns up to fourteen.
Each result exposes source text plus title, URL and FAQ question when present. Uploaded file chunks may have no page title or URL. Internal chunk/file identifiers are deliberately omitted so they are not mistaken for visitor-facing links.
This finds relevant passages, not a complete catalogue or the newest content. An empty result returns “No matches”; an exception returns an error with an empty results list. Neither authorizes the model to invent an answer.
| Tool | Exactly what it searches | Appropriate use |
|---|---|---|
unleashWorld |
Paris event knowledge, general FAQs, and indexed pages filtered to /events/unleash-paris. |
Paris venue, facilities, logistics and general event facts. |
unleashAmerica |
Miami event knowledge, general FAQs, and indexed pages filtered to /events/unleash-miami. |
The equivalent Miami questions. |
unleashWorldAgenda |
Paris agenda chunks plus Paris event knowledge/FAQ. | Discover sessions by meaning or explore stage themes; not exhaustive counts. |
unleashAmericaAgenda |
Miami agenda chunks plus Miami event knowledge/FAQ. | Equivalent Miami agenda discovery. |
generalKnowledge |
General knowledge, plus the selected event’s knowledge and indexed pages when scoped. | Brand/company FAQs and practical questions that may occur in either source. |
unleashSales |
The sales-agent knowledge store. |
Read-only commercial and partnership information. |
unleashSalesSpex |
The sales-agent-spex knowledge store. |
Read-only sponsor/exhibitor packages and logistics. |
mediaCatalogue |
The media index. | Podcasts, reports, videos, and explicitly requested archive content. Not newest-article ranking or upcoming-webinar authority. |
siteMap |
The sitemap index with page URLs and indexed event-page text. | Broad page discovery and page-content questions. Unlike event-specific search, this shared index is not itself an event-only directory. |
These tools perform no contact submission. Their freshness depends on the indexing/refresh pipeline, not just what the website says at the instant of the question.
const results = limitPerPage(
(await queryPineconeStores(stores, query, topK * 2)).filter(
(r) => !isRefusalTemplate(r.text),
),
topK,
)
if (results.length === 0) return { results: [], note: 'No matches.' }
return { results: results.map(toSearchResult) }
B. agendaLookup: exact agenda questions
Example input: { "event": "paris", "speaker": "Bersin" }.
Optional filters: event, stage/room, day (YYYY-MM-DD), keynotes-only, speaker, title and topics. Event can come from context; otherwise the tool returns an instruction to ask which show.
It loads the complete stored event session list and applies structured filtering/summarization. Results include the agenda-page URL, stage/session counts, days, and matching sessions with source times, rooms, format, speaker details and session URLs. Speaker matching handles case/diacritics; the helper checks the catalogue rather than a handful of similarity hits.
Exact stage matching avoids confusing Stage 1 with Stage 10; canonical session Format determines keynote status. Use it for “How many stages?”, “What is on Stage 2?”, “Is this person speaking?” and exact time questions. “Not listed” is relative to the loaded catalogue, not proof that the source will never change. No sessions or a failed load produce an explicit error. The warm agenda cache is ten minutes, in addition to ingestion freshness.
C. badgesLookup: pass facts and verified prices
Example input: { "event": "paris" }.
It resolves the event and loads badge/attend pages directly from Sanity. The returned lookup combines pass names, eligibility/inclusions, page links, related package information and structured pricing. It is intended for pass, ticket, pricing, eligibility and registration questions.
Numeric prices are sourced through the live-pricing resolver: published Sanity pass/product mappings and Inwink public products, with configured overrides/date bands where applicable. The configuration/product cache is 60 seconds; active date bands are re-evaluated when read. Mapping/source coverage matters—Paris coverage does not establish equivalent Miami coverage.
The important rule is use the structured price, never an old FAQ, SEO excerpt, or conversation number. Explorer is application-only and must be described as “Price on application.” Missing/conflicting pricing remains unavailable; it is not estimated. No published badge pages or a lookup exception returns an error.
This tool only retrieves facts. It does not sell, charge, reserve or issue a ticket.
D. pageDirectory: exact event pages and booking destinations
Example input: { "event": "paris" }.
It loads the published event-page catalogue, keeps the event root and descendants, and returns each page’s title, url, description, covers (headings/labels), and links (labeled external destinations). The directory cache is ten minutes.
This solves a different problem from siteMap: it presents the event’s full loaded directory so the assistant can choose the most specific page rather than hoping it appears in the top search hits.
For hotels, the assistant should lead with the actual external booking destination in links, not just the internal travel page. The URL comes from maintained page content; the tool does not browse arbitrary hotel sites or discover a booking link independently. Missing source links still need editorial repair.
links: Array.from(
p.content.matchAll(/^\[([^\n]+)\]\(<(https?:\/\/[^\s<>]+)>\)$/gm),
([, label, url]) => ({ label, url }),
),
E. recentArticles: recency is enforced by the query
Example input: { "topic": "AI" }; an empty topic means latest overall.
This queries published editorial documents directly in Sanity. It matches the short topic against title, excerpt or topic titles, excludes future publication dates, sorts all matches newest-first, then returns up to eight. Each item has title, URL, excerpt, publication date and topics.
Multiple interests should be searched separately. A broad natural-language question is not the intended topic format. An empty result should lead to a broader related topic, not unrelated recommendations. Fetch failure explicitly says recent articles are unavailable and older search results must not be presented as latest.
export const RECENT_ARTICLES_QUERY = `*[
_type in $types && defined(fullSlug) && defined(title) &&
(${RESOURCE_DATETIME_GROQ}) <= dateTime(now()) &&
($topic == "" || title match $topic || excerpt match $topic || topics[]->title match $topic)
] | order((${RESOURCE_DATETIME_GROQ}) desc, _id asc) [0...8] {
title, "url": fullSlug, excerpt,
"publishedAt": ${RESOURCE_DATE_RAW_GROQ},
"topics": topics[]->title
}`
F. upcomingWebinars: future events, soonest first
Input: no parameters ({}).
It directly queries Sanity webinar documents with a URL and a future event UTC timestamp. It sorts by start time ascending and returns up to ten, including title, URL, start time, excerpt and speaker name/role/company.
An empty successful query means no upcoming webinars are listed, so the assistant can offer /webinars for the on-demand catalogue. An error is a lookup failure, not evidence that no events exist. It does not use media similarity search, which can return past webinars.
G. buildAgenda: a planner, not free-form model generation
Example input: { "event": "paris", "topics": "AI, skills", "day": "2026-10-21" }.
The event is taken from resolved scope when available; topics are required, day is optional. It loads sessions and the agenda-page link, then runs createAgendaPlan:
- Exclude sessions without usable title, room, URL, or valid start/end times, and sessions marked private/invite/restricted.
- Split the topic string and score lexical matches in title, topics and track. This is simple matching, not an LLM ranking pass.
- Prefer higher scores, then earlier starts.
- Select unique, non-overlapping sessions with ten minutes between different rooms, at most six per day.
- Return selected sessions, up to six conflicting alternatives, and formatted plan text. Alternatives are labeled as replacements, not extra sessions to attend simultaneously.
The delivery layer uses this server-owned plan text, preserving source times and links. It offers email only if sendAgendaByEmail is enabled. No matches prompts for different interests; source failure says the agenda is temporarily unavailable.
const candidates = all
.filter((session) => usable(session) && (!day || session.day === day))
.map((session) => ({
session,
score: terms.filter((term) =>
`${session.title} ${session.topics} ${session.track}`
.toLowerCase()
.includes(term),
).length,
}))
.filter(({ score }) => score > 0)
.sort(
(a, b) =>
b.score - a.score || a.session.start.localeCompare(b.session.start),
)
const selected: AgendaPlanSession[] = []
H. submitLead: the external enquiry handoff
Inputs: name, email, enquiry summary and an allowed Salesforce intent; company and role are optional tool arguments. The surrounding workflow collects missing contact/booking fields and presents the current request summary before affirmative confirmation. Group quote enquiries can retain no selected pass; quantity ranges remain estimates.
Execution checks the resolved event, allowed intent, conversational consent, non-empty name and email shape. It normalizes escaped email characters, fills missing company/role/interests from the extracted profile, and sets the intent’s event suffix from resolved context. It then rechecks current published submission permissions and posts JSON to the configured Zapier webhook.
The result is { ok, error? }; the handoff outcome also drives the visitor-facing reply and workflow state. HTTP 2xx means the webhook accepted the request. A timeout, missing webhook configuration or non-success response is not a sent enquiry. Downstream CRM/email behavior is outside this tool’s confirmation.
The intended conversational sequence is request → missing details → summary/consent question → affirmative confirmation → tool. Saved contact details are not a send instruction, and a tool description alone does not enforce that sequence; workflow code and consent checks work together.
if (!eventScope) return { ok: false, error: 'Ask which event first.' }
if (!isLeadIntent(intent)) {
return { ok: false, error: 'Invalid or missing intent' }
}
if (!consentGiven) return CONSENT_REQUIRED
email = normalizeEmailEscapes(email).trim()
if (!name.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
return { ok: false, error: 'A name and valid email are required.' }
I. sendAgendaByEmail: validate the selection before dispatch
Inputs: name, email, selected session URLs, optional opt-in. Although an optional event field exists in the schema, execution uses resolved event scope. The description still contains legacy wording about passing full agenda text; the actual schema accepts session URLs and the server generates the text.
It requires conversational consent, name, valid email and known event. It reloads the catalogue and prefers selected-plan URLs recovered by the server over model-supplied URLs when available. validateAgendaSelection rejects empty lists, more than 30 entries, duplicate URLs, unknown/unusable sessions and overlapping sessions.
Only then does it rebuild the agenda text from source records, recheck published permissions, and submit to Zapier with event, visitor details and the agenda intent. It does not trust model-written session times or arbitrary email body text. Selection validation here checks overlaps; the planner’s separate ten-minute transfer rule is not independently repeated in this validator.
Failure to validate asks for the agenda to be rebuilt. Other verification failures return a retry message. An accepted request still does not independently confirm delivery to the recipient’s inbox. Optional marketing opt-in is distinct from permission to send the requested agenda.
if (!urls.length || urls.length > 30 || new Set(urls).size !== urls.length)
return null
const selected: AgendaPlanSession[] = []
for (const url of urls) {
const session = all.find(
(candidate) => candidate.url === url && usable(candidate),
)
if (!session) return null
const next = toPlanSession(session)
if (selected.some((s) => sessionsOverlap(s, next))) return null
selected.push(next)
}
return selected.sort((a, b) => a.start.localeCompare(b.start))
J. eventFacts: complete, source-backed policy answers
This is the eighteenth registered tool and is read-only. Its input is the resolved event and a supported topic identifier; event-dependent questions require clarification if scope is unknown. The current 23-topic union covers registration, ticket policies, eligibility, volunteering, exhibitor logistics, attendance and startup/Award questions.
The loader reads complete general/current-event FAQ documents and event-page bodies from existing Pinecone stores. Document reconstruction restores overlapping chunks; topic selection retains Q/A aliases and event scope. Results include matching answers, page evidence, a contact route and explicit grounding rules. There is no new FAQ application cache; indexing propagation remains source-dependent.
For supported narrow requests the API can emit a source-backed answer directly. Conditional availability, application requirements and published links remain intact. Missing volunteer teams, unpublished promotional prices or eligibility thresholds are not invented. Startup badge checkout and the separate Award application are distinguished; purchased-recording terms do not imply badge entitlement. The tool neither sends enquiries nor changes Pinecone/Sanity content.
It follows the shared Sanity tool switch and is independent of email-submission permission. The named room/document withdrawal guard separately checks current evidence for the same entity and field; it does not add a Jev answer validator or universally verify all knowledge responses.
Policy tests · withdrawal tests · final response/source evidence.