Bring a conversation to Z

How AddConvAG turns an off-platform thread into a unique z-link deal room without minting an offer

Ticket: ZLY-1866. Parent: ZLY-1858.

The talent already has a thread outside Z — email, DM, a half-written deal. They should not have to ask the brand to start over. Bring a conversation to Z opens a deal room on the current agent, seeds what we learned, and gives the brand a unique link. The brand (often not logged in, maybe with no account) first sees a welcome, then signs up, then lands in that same room as regular z-link chat.

This is not Test agent (a demo rehearsal) and not a bare /z/:slug visit (a new inbound from a stranger).

What the talent sees

Entry: Conversations + (desktop, mobile, empty inbox). Agency-wide roster inbox has no + — there is no single “this agent”. When the agency is acting as a talent, the + belongs to that talent.

Breadcrumb: Conversations → New. Page title: Bring a conversation to Z. One box: paste the thread, drop offer / contract / screenshots, or type where things stand.

StageWhat happens
AskAddConvAG reads the paste. If the brand is already named, it does not ask again. If the other side is vague (“they”, “a guy at the event”), it asks once for the brand or company name.
WorkingProgress is creating the conversation room, never “and offer”.
DoneUnique link, Copy, optional mailto. Open the conversation (talent thread), Add another, Close. The row is on this agent, outbound, counterpart = brand, no offer badge.

Send by text and vanity URLs (mcdonalds-4kt9) are out of scope.

What the brand sees

The unique URL is /z/{talentSlug}/{roomId} — the same shape as a normal z-link deep link. It is a capability URL: whoever claims first owns the visitor seat.

Welcome copy:

  • You're invited
  • {Talent} invited you ({Brand}) to make them an offer.
  • Short landing line: this is a private room with the talent's agent; notes from the thread they already had are on the card — no need to start over.
  • Card with the AI summary of the brief (and highlights when we have them).
  • Sign up (anonymous) or Continue (already logged in as a brand).
  • After that, they land in this same conversation.

Special cases on that URL:

Who opens the linkWhat they get
Anonymous brandWelcome + Sign up, then claim, then chat
Logged-in brand, seat still freeWelcome + Continue, then claim
Talent (the host)“This is your conversation link” — they do not become the brand
Someone else after claim“This invite was already claimed” — not a new guest room

Once they are in chat, the page should look like a normal z-link (hero + chat), not a conversation picker with a plus. The host-facing agent already has the seeded brief, so the brand should not have to type “hey” for the agent to know this is the McDonald’s thread.

Why a separate agent

The z-link host is the negotiator. If it also ran this intake, it would be tempted to treat the pasted thread as a settled offer. AddConvAG’s only job is: brief + brand name, then stop. Code creates the room.

The same split exists elsewhere: Test agent invents an inbound without becoming the host persona. AddConvAG is the outbound twin — a real thread coming in from the talent, not a rehearsal.

Ops lists it with the others so the prompt is visible and downloadable. It still does not sit in the deal-room cast in The Agents. Those eleven roles mediate a live conversation. AddConvAG never enters that room.

The room that gets created

Kind: deal, on the current talent (or the acted-as talent). Title {Brand} × {Talent}.

  • Host seat: the talent’s account. Durable host memory seeds as usual.
  • Visitor seat: brand display name only. No account, no guest cookie. Do not attach the talent’s zly_z_agent_guest cookie — that would lock the brand out.
  • First host session is agent-opened, so the inbox row is outbound (the talent went to them).
  • Memory carries invite (source add-conv), the summary, the brief as visitor.externalThread, and visitor guidance: prior context, not a settled offer. Do not mint from the seed alone.
  • Negotiation goal gets a suffix with the same rule: wait until the brand confirms they want to make an offer in this chat.
  • Zero offer rows at create.

A bare /z/:slug (no roomId) must not resume this invite room. Hitting the unique /z/:slug/:roomId must not call ensureDealRoomForGuest and mint a second empty room.

Claim is first-writer-wins (claimedByAccountId). After claim, existing VisitorRoomChat continues on that roomId. Visitor account memory is still not seeded — see Identity and Representation.

Hard rules

  • Not Test agent / demo / simulate.
  • Not offer-gen. The brand completes the offer later in z-link chat.
  • Not SMS. Not vanity URLs in v1.
  • Not an agency-wide + without a selected talent.
  • Signup returnTo is the invite URL, not /dashboard.
  • Same person signing up as the talent account is treated as host, never as the brand.

Compared with other surfaces

SurfaceWho starts itRoomOffer
Bring a conversation to ZTalent, from an off-platform threadOutbound deal, unique /z/:slug/:roomIdNone until the brand makes one in chat
Public z-link /z/:slugBrand / strangerInbound deal, guest cookieNormal z-link path
Sibling new offerBooked change, or new campaign after 7 days of silenceAlways-insert deal for the same pairNone copied; fresh negotiation. See Sibling rooms
Test agentTalent rehearsalFresh demo per runMust not mint a live offer

Source

PieceWhere
Talent pagepackages/offers/client/src/app/components/agent/conversations/AddConvAGPage.tsx
+ buttonAddConversationButton.tsx on talent (and act-as) conversation views
Welcome / brief cardpackages/offers/client/src/app/components/zlink/
AddConvAG prompt + turnpackages/z-agent/srv/src/add-conversation.ts, DEFAULT_ADD_CONV_PROMPT in agents/default-prompts.ts
Catalog / ops rowadd-conversation in packages/z-agent/srv/src/agents/catalog.ts
Invite memory + claimpackages/z-agent/srv/src/add-conversation-invite.ts
Outbound roomcreateOutboundInviteDealRoom in packages/z-agent/srv/src/rooms.ts
HTTPPOST /api/z-agent/my/add-conversation/chat, GET / POST …/visitor/invite/:slug/:roomId

Durable memory is in Memory. Host vs visitor seeding is in Identity and Representation. How a public /z/:slug normally opens is in Rooms in the Product.