Neocortex
IntegrationsUnity SDKAPI Reference

Neocortex Group Director

Several characters sharing one conversation in Unity

Experimental

Group chat is currently an experimental feature. Its API and behavior may change in future SDK updates.

NeocortexGroupDirector runs a conversation across several characters. Each character keeps its own NeocortexSmartAgent on its own GameObject, with its own voice, animation and events. The director assembles them into a cast, sends one group turn, and routes every reply back to the character that said it.

Neocortex Group Director

Setting up

  1. Put a NeocortexGroupDirector on an empty GameObject
  2. Drag your characters into its Agents list
  3. Add a NeocortexGroupChatUI on the same GameObject for the chat panel, input, thinking indicator and microphone

One UI for the whole cast

Use a single NeocortexGroupChatUI on the director. Do not also put a NeocortexChatUI on each character: every one of them would print the same replies again.

Adding an agent to the cast switches its Auto Voice Input off, because the director owns the microphone for the whole scene. Without that, every character in the cast would answer the player separately.

A cast of two or more characters needs a Pro or Team plan. A cast of one behaves like normal single character chat and works on any plan.

Methods

Send

The player speaks to the group. An AI director decides who answers and in what order, up to Max Turns speakers.

  • Parameters:
    • message: What the player said.
    Send Example
    director.Send("Hi everyone, introduce yourselves");

SendTo

Addresses one character, skipping the director entirely when you already know who should answer. There is an overload taking a character id instead of an agent.

  • Parameters:
    • agent: The character that should answer, or characterId as a string.
    • message: What the player said.
    SendTo Example
    director.SendTo(alice, "Alice, what do you think?");
    director.SendTo("cmrkiw4f100017k7sfnicq08e", "And you?");

Continue

Runs an ambient turn with no player input, so the cast talks among themselves. Also the natural thing to call right after the roster changes, so the others react to the arrival or departure immediately.

Continue Example
director.AddAgent(maya);
director.Continue();

SendAudio

Transcribes the player's recording, raises it on OnPlayerSpeech, then runs the turn with it. Ignored while a turn is already in flight.

  • Parameters:
    SendAudio Example
    mic.OnAudioRecorded.AddListener((clip) => director.SendAudio(clip));
    director.OnPlayerSpeech.AddListener((text) => chatPanel.AddMessage("You", text, true));

AddAgent

Adds a character to the cast while the scene runs. The others are told: they greet the newcomer and start addressing them.

  • Parameters:
    • agent: The NeocortexSmartAgent joining the scene.

A late joiner is new to the conversation

A character that joins partway through only sees the transcript from the moment it joined. Anything said before it arrived is invisible to it, so a secret shared earlier stays secret.


RemoveAgent

Removes a character from the cast. The others stop addressing them and still know later that the character left, rather than assuming they are still there.

  • Parameters:
    • agent: The NeocortexSmartAgent leaving the scene.
    AddAgent and RemoveAgent Example
    director.AddAgent(maya);     // Maya joins
    director.RemoveAgent(bram);  // Bram leaves
    director.Continue();         // let the cast react right away

ClearSession

Forgets the shared session id, so the next turn starts a fresh conversation.

ClearSession Example
director.ClearSession();

GetHistory

The shared transcript, oldest first and name labelled per speaker. Also raised on OnHistoryReceived.

  • Parameters:
    • limit (optional): Messages per page. Defaults to 20.
    • before (optional): A nextCursor from a previous page.
  • Returns: Task<ApiChatHistory>
    GetHistory Example
    ApiChatHistory history = await director.GetHistory(20);
    foreach (ChatHistoryEntry entry in history.messages)
    {
        Debug.Log($"{entry.name ?? "Player"}: {entry.content}");
    }

Events

OnSpeaker

Raised before each character speaks its turn. Use it for the shared transcript and name label.

  • Arguments:
    • message: The GroupMessage for this speaker, { characterId, name, lines[], actions[], flowState }.
    OnSpeaker Example
    director.OnSpeaker.AddListener((msg) =>
    {
        string text = string.Join(" ", msg.lines.Select(l => l.text));
        chatPanel.AddMessage(msg.name, text, false);
    });

OnPlayerSpeech

Raised with the transcript of the player's spoken input, so the UI can show what they said.

  • Arguments:
    • message: The transcribed text.
    OnPlayerSpeech Example
    director.OnPlayerSpeech.AddListener((text) => chatPanel.AddMessage("You", text, true));

OnTurnStarted

Raised when a turn begins. Lock your input field here while the cast talks.

OnTurnStarted Example
director.OnTurnStarted.AddListener(() => textInput.interactable = false);

OnTurnFinished

Raised when every speaker in the turn has finished. Release input here.

OnTurnFinished Example
director.OnTurnFinished.AddListener(() => textInput.interactable = true);

OnGroupResponseReceived

Raised once with the whole group turn, before the speakers are played out.

  • Arguments:
    • response: The GroupChatResponse, carrying sessionId and every GroupMessage in speaking order.
    OnGroupResponseReceived Example
    director.OnGroupResponseReceived.AddListener((response) =>
    {
        Debug.Log($"{response.messages.Length} characters answered");
    });

OnHistoryReceived

Raised when GetHistory() returns, each entry name labelled.

  • Arguments:
    • messages: A ChatHistoryEntry[] of past messages.
    OnHistoryReceived Example
    director.OnHistoryReceived.AddListener((messages) =>
    {
        foreach (var m in messages) chatPanel.AddMessage(m.name, m.content, m.sender == "USER");
    });

OnRequestFailed

Raised when the turn fails.

  • Arguments:
    • error: The error message.
    OnRequestFailed Example
    director.OnRequestFailed.AddListener((error) => Debug.LogError(error));

IsBusy is true while a turn is being fetched or played out, and sends are ignored during that window, so turns can never overlap. SessionId holds the shared scene session, empty until the server mints one on the first turn, and Agents is the current cast.

How replies are played

The director plays speakers strictly in order: it routes each message to its agent, waits for that character to finish, then starts the next. Every character therefore speaks with its own ChatLinesMode, AudioSource and animation events, exactly as it would in a single character scene.

Keeping turns tight

Max Turns caps how many characters speak per director turn, and SendTo skips the director entirely when you already know who should answer.

On this page