Skip to content

Auto-launch the Server

Let your client application start the Tryll server automatically instead of requiring a separately-launched process.

flowchart LR
    ManagedServer -->|"--port N"| ServerProcess["tryll_server"]
    ServerProcess -->|"TCP ready"| Client
    Client -->|"Connect(host, port)"| Session

The client spawns the server with --port <N> on the command line so the port both sides use is always in sync — no editing of server-config.json needed.


C++

RunAndConnect is the one-call factory for the common case. It starts the server, waits for the TCP port to open, and returns a ConnectedSession that owns both the process and the socket — destructor shuts them down in the right order automatically.

#include <tryll/TryllClient.h>   // pulls in ManagedServer.h transitively

namespace TC = Tryll::Client;

TC::ManagedServerOptions opts;
opts.exe  = "C:/tryll/tryll_server.exe";  // required — no auto-discovery
opts.port = 9100;

// Spawn server → wait for TCP → connect → return session.  Throws on failure.
auto session = Tryll::TryllClient::RunAndConnect(opts);

session.GetClient().ConfigureSession(TC::InferenceEngine::LlamaCpp);
auto agent = session.GetClient().CreateAgent(graph);
// …
// session destructor: graceful TCP close, then server process termination

For async startup (e.g. editor plugin startup, game initialization):

auto future = Tryll::TryllClient::RunAndConnectAsync(std::move(opts));
// do other work …
auto session = future.get();   // blocks until ready; propagates any TryllError

Lower-level: ManagedServer + Connect

When you need finer control over the server lifetime (e.g. a long-lived server shared across multiple client sessions), use ManagedServer and Connect separately:

#include <tryll/ManagedServer.h>
#include <tryll/TryllClient.h>

TC::ManagedServerOptions opts;
opts.exe  = "C:/tryll/tryll_server.exe";
opts.port = 9100;

auto server = TC::ManagedServer::Start(opts);
// Start() blocks until the TCP port accepts connections (up to opts.startTimeout).

// First session
auto clientA = Tryll::TryllClient::Connect(server.Host(), server.Port());
clientA.ConfigureSession(TC::InferenceEngine::LlamaCpp);
// … use clientA …
clientA.Shutdown();

// Second session — server still running
auto clientB = Tryll::TryllClient::Connect(server.Host(), server.Port());
// …
clientB.Shutdown();

server.Stop();   // or let server go out of scope — destructor calls Stop()

Key ManagedServerOptions fields

Option Default Description
exe (required) Path to tryll_server.exe. No automatic discovery.
port 9100 Passed as --port to the server.
host "127.0.0.1" Used only for the TCP ready-probe.
workingDirectory exe.parent_path() Where the server looks for data/.
stdoutLog / stderrLog (discard) Redirect server output to files.
startTimeout 30 s How long to wait for the port to open.
stopTimeout 8 s How long to wait for graceful exit before force-kill.

test-chat

The bundled tryll_test_chat demo uses RunAndConnect automatically and discovers the server exe from the build directory. Use --no-managed-server to disable this and connect to a server you started yourself:

build\test-chat\Debug\tryll_test_chat.exe --no-managed-server

Other useful flags:

# Use a server exe from a different location
tryll_test_chat.exe --server-exe C:\tryll\tryll_server.exe

# Run on a non-default port
tryll_test_chat.exe --server-port 9200

Python

run_and_connect is the one-call factory for the common case. It starts the server and returns a ConnectedSession context manager that tears everything down automatically:

from pathlib import Path
from tryll_client import TryllClient, InferenceEngine

with TryllClient.run_and_connect(
    exe=Path("C:/tryll/tryll_server.exe"),  # required — no auto-discovery
    port=9100,
) as session:
    session.client.configure_session(InferenceEngine.LlamaCpp)
    agent = session.client.create_agent(graph)
    reply = agent.send_message("Hello!")
    print(reply)
# __exit__: client.shutdown() then server.stop()

Without a context manager:

session = TryllClient.run_and_connect(exe=Path("C:/tryll/tryll_server.exe"), port=9100)
try:
    session.client.configure_session(InferenceEngine.LlamaCpp)
    # …
finally:
    session.shutdown()

Lower-level: ManagedServer + connect

When you need a long-lived server shared across multiple client sessions, use ManagedServer and connect separately:

from pathlib import Path
from tryll_client import TryllClient, ManagedServer, InferenceEngine

with ManagedServer.start(
    exe=Path("C:/tryll/tryll_server.exe"),  # required — no auto-discovery
    port=9100,
) as srv:
    # First session
    client_a = TryllClient.connect(srv.host, srv.port)
    client_a.configure_session(InferenceEngine.LlamaCpp)
    # … use client_a …
    client_a.shutdown()

    # Second session — server still running
    client_b = TryllClient.connect(srv.host, srv.port)
    # …
    client_b.shutdown()
# ManagedServer.__exit__ calls stop() automatically

Key parameters

Parameter Default Description
exe (required) Path to tryll_server[.exe].
port 9100 Passed as --port to the server.
host "127.0.0.1" Used only for the TCP ready-probe.
cwd exe.parent Working directory for the child process.
stdout / stderr (discard) Redirect server output to files.
start_timeout 30.0 Seconds to wait for the port to open.
stop_timeout 8.0 Seconds to wait for graceful exit before force-kill.
connect_timeout 30.0 (run_and_connect only) Seconds to wait for SessionReady.

Unreal

The Unreal plugin auto-launches the server through project settings.

  1. Open Edit → Project Settings → Plugins → Tryll Client.
  2. Set Editor Server Exe Path to the path of tryll_server.exe (absolute, or relative to the project directory). Leave it empty to disable auto-launch in the editor and start the server manually.
  3. For packaged builds, set Build Server Exe Path to the path relative to the game executable directory (default: tryll_server.exe, meaning the server exe sits next to the game exe).
  4. Auto Launch Server is true by default. Uncheck it to disable auto-launch entirely.

The subsystem spawns the server on Initialize and terminates it on Deinitialize (when the game instance ends). The ServerPort property on UTryllSubsystem must match whatever port the server uses (server-config.json's port field).

Editor vs packaged

EditorServerExePath defaults to empty, which disables auto-launch in the editor on purpose — most developers prefer to run the server manually while iterating. Set it to opt in.