Kitto.Chat.Runner
In-memory conversation store and asynchronous runner for the help chat. TKXChatStore keeps one conversation per user (v1: single thread, no DB persistence — the history lives for the session). Sending a message appends the user message plus a Pending assistant message and submits a request to TKXChatRunner, a small worker pool separate from the Indy request threads (so a slow provider call — e.g. an LLM HTTP round-trip — never blocks the web server) and separate from the notification job queue (so chat replies do not surface in the bell). The worker calls the configured provider and writes the reply back into the store; the client retrieves it by polling the chat poll endpoint.
TKXChatStore class
Per-user, in-memory conversation store. Thread-safe: the web (request) threads append messages and read history, while runner (worker) threads complete the pending assistant messages. Process-global singleton.
function AddUserMessage(const AUser, AContent: string): TKXChatMessage;Appends a user message to the user's conversation and returns it.
function AddPendingAssistant(const AUser: string): string;Appends a placeholder assistant message (Pending) and returns its id; the runner later completes it in place.
procedure AppendAssistantToken(const AUser, AId, AToken: string);Appends AToken to the (still pending) assistant message AId, leaving it pending. A streaming provider calls this for each token, so the poll endpoint returns the growing partial reply and the drawer fills in incrementally without any server-push machinery.
procedure CompleteAssistant(const AUser, AId, AContent: string);Marks the pending assistant message AId as completed with AContent.
procedure FailAssistant(const AUser, AId, AError: string);Marks the pending assistant message AId as failed with an error text.
function TryGetMessage(const AUser, AId: string;Returns a copy of the assistant message AId, if present.
function GetMessages(const AUser: string): TArray<TKXChatMessage>;Returns the full conversation of the user, in order.
function GetHistory(const AUser: string;Returns the completed (non-pending, non-error) messages to feed the provider as context, most recent AMaxMessages kept (0 = all).
procedure Clear(const AUser: string);Clears the user's conversation.
class function Instance: TKXChatStore;The process-global conversation store.
TKXChatRunner class
Worker-pool runner that produces assistant replies off the request thread. Submitted requests run the configured provider and write the reply into the TKXChatStore. Pool size from HelpChat/PoolSize (default 2). Process-global singleton.
Routines
procedure Submit(const AUser, AAssistantId, AProviderName: string;Submits a request: the worker will run AProviderName against the user's current history and complete the assistant message AAssistantId.
class function Instance: TKXChatRunner;The process-global chat runner, created on first use.
function NewChatId: string;Formats a fresh URL-safe message id (hyphenated hex, no braces).
