Call for any reason a contact's record may be out of date: a direct request, a report
that the person changed jobs or left, or a doubt about whether their details are
current. Queues a re-pull of the existing contact's details to update their record on
file; the update finishes after the tool returns `started`. Unless the user asked for
the refresh outright, the tool returns `needs_confirmation` instead, so you can ask
the user before anything is re-pulled.
## When the user TELLS you where someone works
"Mauricio works at Autopistas del Café", "Carlo is at MO3 now", "she's moved to
Odinsa" — pass that company as `employer`. Re-pulling LinkedIn cannot help here: the
provider is the thing that was wrong, which is why this path exists.
`employer` is where the person IS. A sentence can name a company for the opposite
reason, and those two readings must never be confused:
- "Venkat LEFT Splashtop", "she's no longer at Acme", "he's leaving Globex" name
where the person is NOT. There is no stated employer here at all. Do NOT pass it
as `employer` — that would file them at the company they just left, which is the
exact corruption this tool has to avoid. Leave `employer` unset; this is an
ordinary refresh, and if the user also says where they went ("left Splashtop for
RudderStack"), the destination is the `employer`, never the origin.
- A company inside a QUESTION — "is Matt still at Quindar?", "did Marco leave
Algolia?" — is something to check, not a fact being supplied. Never pass it.
Nothing is written until a person confirms. The tool walks one question at a time and
each status names exactly what is still missing, so ASK THE USER and call again with
the answer. Never fill these in yourself:
- `needs_contact_choice` several people match. Show `candidates` and pass the
chosen one's `id` as `contact_id`, keeping everything
else the same.
- `needs_business_choice` several companies match, or one partially matches.
Show `choices` and pass the chosen
`employer_business_id`. Do not pick for them. If none
is right, ask for the website and pass it as
`employer_website`.
- `needs_new_company_confirmed` no company on file matches. If `choices` holds a
company the tool found, ask whether it is the right
one; otherwise ask for the website. Call again with
`employer` unchanged (it is the company's name) and
`employer_website` set to the confirmed web address.
- `needs_change_kind` ask whether we simply had it wrong, or they have moved
jobs. Pass `employer_change_kind` as `"correction"` or
`"job_change"`. This decides whether their PAST calls
move too, so it must come from the user.
- `needs_since` a job change needs a start date. Pass `employer_since`
as YYYY-MM-DD. Calls before it stay with the old
company.
- `proposal` ready. Show `message` — it spells out what will change,
including how many calls move — and, only once the user
agrees, call again passing `apply_token`.
- `no_change_needed` we already have them at that company and their calls
are filed there. Say so; do not ask anything further.
- `applied` done.
- `expired` the confirmation lapsed or was already used; start over.
`apply_token` executes the plan the server built and the user saw. It is single-use
and short-lived, so do not store or reuse one, and never invent one.
`user_requested`: set true only when the user asked for this refresh outright
("refresh Matt Wood", "re-pull her details", "update his record from LinkedIn") or
has just confirmed a refresh you offered. Leave it false when you are acting on a
hint that something changed ("Marco is now CEO of Kleecks", "is Matt still at
Quindar?"); the tool then resolves the contact and returns `needs_confirmation` so
you can ask before anything is re-pulled. The tool never infers this from the
wording of `query`.
Only a `started` status enqueues anything. Every other status is a safe no-op:
- `started` refresh was queued; enrichment is NOT complete yet
- `needs_confirmation` one contact resolved from an implicit signal — ask the user
before refreshing, do not call again unconfirmed
- `ambiguous` several candidates matched; present them and ask
- `no_linkedin_url` contact found but has no stored URL to re-enrich from
- `no_match` nothing resolved
`needs_confirmation` is deliberate, not a failure: it keeps a passing mention of a
contact from silently triggering re-enrichment. See `contact_refresh_runner`.
Side effects: on `started`, invokes `trigger_refresh_contact`.
refresh_contact