Graine AI

Several agents in one app

Run more than one agent — a support agent in Help, a sales agent on Plans — each with its own key, design, chat and actions, while who the user is, the install and the screen stay shared; and place calls with a named agent.

Each agent is configured once under a name of your choosing, with its own publishable key. A screen talks to one of them. The user signs in once for all of them.

Per agentShared by every agent
Its settings and design, its chat and its kept conversation, its bar, its components, its registered actions, its scheduling rules and bookings, its memory scopeThe install, who the user is (identify once reaches all; identify(null) signs out of all), the memory choice, the current screen, the phone's one call engine

One conversation runs at a time across all agents: starting one ends another.

What it needs in the dashboard

WhereSettingValue
Each agent → Embed & WidgetsSet up embeddingEach agent its own publishable key
Each agent → Embed & Widgets → InstallAllowed domainsapp:// on every agent your app uses
Each agent → Memory → SettingsWho is the user?The same field on every agent, so one sign-in is one person for all
Each agent → Calls & schedulingName on the incoming callA different name per agent, so the user can tell who rings

What to do, in order

  1. Configure each agent at launch: the default one without a name, the others with theirs.
  2. Identify the user once — on any agent. → Every agent knows them.
  3. Show each agent where it belongs: the views take the agent.
  4. Place calls with a named agent, and book calls with the agent the user is talking to. → A ring Graine sends answers as the agent that booked it, with its call name and design.
  5. Sign out once: identify(null) on any agent signs out of all.

The code, platform by platform

1. Configure each agent:

GraineInApp.configure(GraineConfig(baseUrl: "https://www.graine.ai", publishableKey: "pk_live_support…"))            // the default agent
GraineInApp.configure(GraineConfig(baseUrl: "https://www.graine.ai", publishableKey: "pk_live_sales…"), name: "sales")

→ GraineInApp.shared is the default agent; GraineInApp.named("sales") the other (nil if never configured); GraineInApp.all every agent by name.

2. Identify once: GraineInApp.shared.identify(["user_id": user.id]).

3. The views take the agent:

struct PlansScreen: View {
    var body: some View {
        Text("Plans")
            .overlay(GraineAgentBar(graine: GraineInApp.named("sales")))
    }
}

GraineChatView(graine:), GraineWidgetView(graine:) and .graineBookingSheet(isPresented:graine:) take it too.

4. Calls with a named agent:

GraineInApp.shared.calls.startCall(reason: "upgrade", agent: "sales")
let call = await GraineInApp.named("sales")?.presentBooking(reason: "Talk about plans")

5. Sign out: GraineInApp.shared.identify(nil).

Troubleshooting

What you seeWhyFix
The second agent does not know the userA different Who is the user? fieldThe same field on every agent
A ring shows the wrong nameBoth agents share one call nameName on the incoming call per agent
Starting a chat with one agent ends a call with anotherOne conversation at a time, on purpose—

In depth: Use more than one agent in your app.

On this page