Connect and Manage a Session¶
Open a connection to a running Tryll server, handle reconnection, and shut down cleanly.
Prerequisites
- The Tryll server is running and reachable — see Run the Tryll Server.
- You know the host and port. A server you start by hand binds the
server-config.jsonport (9100by default), which the C++ and Python samples below assume. Auto-launched player servers, and aManagedServerleft at its default port, use an OS-assigned free port instead: connect through the client that launched them, not to 9100. In the editor, 9100 is the configured port and the fallback the plugin tries first.
Steps¶
// 1. Subscribe to connection events before connecting.
TryllClient.Instance.ConnectionChanged += connected => {
if (!connected) return;
// 2. Create the session. The engine hint comes from the Model
// Manager manifest; each model's catalog entry names its engine.
TryllClient.Instance.CreateSession(
TryllClient.Instance.Settings.BuildEngineDeclarations());
};
TryllClient.Instance.CreateSessionComplete += err => {
if (!err.IsOk)
Debug.LogError($"configure failed: {err.Message}");
// 3. Proceed to create storages and agents.
};
// Auto Launch Server (Project Settings) only starts the server process.
// Auto Start Session on a scene TryllClient (off by default) connects and
// creates the session from Awake; StartSession() does the same on demand.
// Otherwise connect manually:
TryllClient.Instance.Connect();
In Blueprint: on Event BeginPlay, get the
UTryllSubsystem and call Connect. Bind
On Connection Changed — when bConnected = true, call
Create Session and wait for On Create Session Complete.
(With Auto Create Session on, the default, the plugin does this
for you.)
In C++, the same subsystem API is available:
#include <tryll/TryllClient.h>
namespace TC = Tryll::Client;
try
{
auto client = Tryll::Client::TryllClient::Connect("127.0.0.1", 9100);
client.CreateSession({});
// ... create agents, send messages ...
client.Shutdown();
}
catch (const Tryll::Client::TryllError& ex)
{
// ex.GetCode() is an ErrorCode; see reference/error-codes.md
std::cerr << "session error " << ex.GetCode()
<< ": " << ex.what() << "\n";
}
from tryll_client import TryllClient, TryllError
# 1. Open the socket. Blocks briefly until ConnectionReady arrives.
client = TryllClient.connect("127.0.0.1", 9100)
# 2. Create the session (mandatory, one-shot). It does not pick an
# engine: each model's catalog entry names its engine. The optional
# `engines` hint only warms engines early.
try:
client.create_session()
except TryllError as e:
print(f"configure failed: {e}")
raise
# 3. Do your work — create storages, agents, send messages.
# See build-chat-agent-with-graph.md for the next step.
# 4. Clean shutdown.
client.shutdown()
Handle reconnection¶
If the socket drops (server restart, network blip, etc.), the server destroys every agent and storage the session owned. The client libraries surface this as a connection-changed event or an async error:
- Unity / Unreal: bind
ConnectionChanged/OnConnectionChanged(false)to a handler that re-callsConnect/CreateSessionand re-creates storages and agents. - Python / C++: catch the
TryllErrorfrom the next request and callTryllClient.connect(...)/Tryll::Client::TryllClient::Connect(...)again to make a fresh client. The old client's storages and agents are gone; re-create them.
There is no server-side session persistence. Everything is rebuilt from scratch on reconnect.
// ConnectionChanged fires false on drop, true when re-established.
TryllClient.Instance.ConnectionChanged += connected => {
if (!connected) return;
TryllClient.Instance.CreateSession(
TryllClient.Instance.Settings.BuildEngineDeclarations());
// Re-create any per-session storages and agents you need.
};
A dropped connection ends the session. Call Connect again, then make
a new session. With Auto Create Session (bAutoCreateSession, on by
default) the subsystem creates it when the connection comes back, and
every UTryllAgentComponent with Auto Create On Connect re-creates
its agent once the session is ready. Storages and agents you created
from code must be re-created in OnCreateSessionComplete.
// Bound with: Subsystem->OnConnectionChanged.AddDynamic(this, &ThisClass::HandleConnection);
// Subsystem->OnCreateSessionComplete.AddDynamic(this, &ThisClass::HandleSession);
void AMyActor::HandleConnection(bool bConnected)
{
UTryllSubsystem* Subsystem = GetGameInstance()->GetSubsystem<UTryllSubsystem>();
if (!bConnected)
{
// Try again after a short delay.
GetWorldTimerManager().SetTimer(ReconnectTimer,
FTimerDelegate::CreateWeakLambda(this, [Subsystem] { Subsystem->Connect(); }),
2.0f, false);
return;
}
if (!GetDefault<UTryllRuntimeSettings>()->bAutoCreateSession)
{
Subsystem->CreateSessionFromSettings();
}
}
void AMyActor::HandleSession(bool bSuccess)
{
if (bSuccess)
{
// Re-create string storages, embedded storages, and code-created agents here.
}
}
Session lifetime rules to remember¶
CreateSessionis mandatory and one-shot (protocol v4): call it exactly once after connecting, before any agent/model/storage/voice request. A request beforeCreateSessionfails withSessionNotReady; a secondCreateSessionfails withSessionAlreadyExists. There is no engine to change: each model's catalog entry names its engine, so a model you download mid-session loads without a new session.- String storages and embedded string storages die with the session.
- Model downloads and loads are global, not per-session. Pinning a model in one session keeps it warm for all sessions.
- Agent ids are session-scoped. A stored
agent_idis meaningless after reconnect.
See Lifetime and Ownership for the full picture of what survives session close and what does not.
Suppress telemetry for a process run¶
To keep a Tryll Dev server from sending telemetry for one run — a QA or CI
pipeline, for example — pass --telemetry-level off:
This overrides "enabled": true in server-config.json for that process.
An editor server raises off to basic. To send turn timings or conversation
text from the editor while debugging, set Telemetry Level in Project
Settings. See Telemetry.
Verify it worked¶
Connecting and creating the session produces these server-side log
lines (at info level):
[info] [Connection 3] accepted
[info] [Session 1] Created uuid=<session-uuid> engine hint: (none) game_name: MyGame storage_root: C:\MyGame\TryllStorage locale: (unset)
The engine hint field lists role=engine pairs (for example
language=llama-cpp, tts=sherpa-onnx) when the client sent a warm-up
hint, and (none) when it did not. storage_root is the process
storage root.
If you do not see a Created line, CreateSession did not complete.
Check the error the client received (CreateSessionComplete in Unity,
On Create Session Complete in Unreal, the raised TryllError in
C++ and Python) — see error codes 2xxx.