llm-ui-kit / llm-ui

The React library for LLMs
https://llm-ui.com
MIT License
370 stars 14 forks source link

Block match output being truncated prematurely #239

Closed craigmassie closed 4 months ago

craigmassie commented 4 months ago

Hey, love the project! Just testing it out for the first time and running into some issues with the output being truncated (outputRaw/llmOutput contains the correct string, output/visibleText doesn't).

As an example: outputRaw: [...]hey\n\nIf you need further details or assistance, please let me know!" output: [...]hey\n\nIf you need further details or assistance, pleas\n"

I can repro this with different outputs, so I don't think the issue is specific to this exact response.

The code to reproduce is almost identical to the example in the docs which leads me to believe it's being removed on conversion to the internal AST:

    const startChat = useCallback(() => {
        setIsStarted(true);
        setOutput("");
        const webSocket = new WebSocket(`url`, accessToken);

        webSocket.onopen = () => {
            console.log("WebSocket connection opened");
            webSocket.send(MARKDOWN_PROMPT);
        };

        webSocket.onmessage = (e) => {
            const token = e.data;
            setOutput((prevResponse) => `${prevResponse}${token}`);
        };

        webSocket.onerror = (error) => {
            console.log("WebSocket error: ", error);
        };

        webSocket.onclose = (e) => {
            console.log("WebSocket connection closed", e);
            setIsStreamFinished(true);
        };

        return () => {
            webSocket.close();
        };
    }, []);

    const { blockMatches } = useLLMOutput({
        llmOutput: output,
        blocks: [],
        fallbackBlock: {
            component: MarkdownComponent,
            lookBack: markdownLookBack(),
        },
        isStreamFinished,
    });

    return (
        <div className="prose">
            <p>Prompt: {MARKDOWN_PROMPT}</p>
            {!isStarted && <button onClick={startChat}>Start</button>}
            {blockMatches.map((blockMatch, index) => {
                const Component = blockMatch.block.component;
                return <Component key={index} blockMatch={blockMatch} />;
            })}
        </div>
    );

Any help here would be super appreciated!

richardgill commented 4 months ago

Hey, glad you like it!

It looks like you're missing 15 chars which is the number of 'read ahead' characters in the throttle function. It only prints these out once isStreamFinished is true.

Is your isStreamFinished being correctly set to true at the end. Looks like maybe it's only set when the connection is closed.

craigmassie commented 4 months ago

That was it! Thanks Richard :)