private Result completeAsync(Query query, Prompt prompt, InferenceParameters options, Result result, Execution execution) {
        final EventStream eventStream = new EventStream();

        if (shouldAddPrompt(query)) {
            eventStream.add(prompt.asString(), "prompt");
        }
        if (shouldAddHits(query) && result != null) {
            eventStream.add(renderHits(result, execution), "hits");
        }

        final TokenStats tokenStats = new TokenStats();
        languageModel.completeAsync(prompt, options, completion -> {
            tokenStats.onToken();
            handleCompletion(eventStream, completion);
        }).exceptionally(exception -> {
            handleException(eventStream, exception);
            eventStream.markComplete();
            return Completion.FinishReason.error;
        }).thenAccept(finishReason -> {
            tokenStats.onCompletion();
            if (shouldAddTokenStats(query)) {
                eventStream.add(tokenStats.report(), "stats");
            }
            eventStream.markComplete();
        });

        HitGroup hitGroup = new HitGroup("token_stream");
        hitGroup.add(eventStream);
        return new Result(query, hitGroup);
    }
Base class for LLM searchers. Provides utilities for calling LLMs and handling properties.

@author lesters
container-search/src/main/java/ai/vespa/search/llm/LLMSearcher.java