💭Concepts

A high-level view of a stage project and how they fit in the context of a chat.

Project Structure

A stage is, at its core, a React website, just a very small one.

public/
    chub_meta.yaml  # Information like the stage's name.
src/
    Stage.tsx  # The core stage implementation.
                       # This is the main file to edit.
    TestRunner.tsx     # A runner for testing.
    assets/
        test-init.json    # Testing data for the Test Runner.
    index.scss         # CSS styling
    main.tsx           # The app's entry point.
    App.tsx
package.json        # Dependency management
.github/            # A utility file that creates the stage
    workflows/      # project in Chub, and builds and deploys it
        deploy.yml  # on push.
.eslintrc.cjs       # Linter configuration file
index.html          # The root HTML
tsconfig.json       # TypeScript configuration file
tsconfig.node.json  # TypeScript configuration file
vite.config.ts      # Vite configuration file
yarn.lock           # Freezes dependencies

Communication between the chat UI itself and the stage site is handled by the stages library -- to develop you only need to be concerned with implementing the StageBase interface.

Where a Stage Exists in a Chat

If a stage is given a position of 'NONE' in the chub-meta.yaml, it doesn't display at all, instead running in the background. Otherwise, on a desktop or wide screen, it displays to the right of a chat, with the majority of the height of the window minus some padding.

On mobile devices or narrow windows, the stage is given a smaller space between the chat header and messages, with the messages fading out in the background.

If there are multiple visible stages, they will share the space, with equal-height rows on wide screens and equal-width columns on narrow screens.

If your stage outputs system messages, they will display at the end of whatever message they were given in response to. System messages are visible to the human only, and not sent to the LLM.

Stage Lifecycle and Communication

Top-Down Communication Points

There are four places where a stage is called: initialization, before a message is sent to an LLM, after a response is received from an LLM, and when the user swipes or jumps from one place in the chat tree to another. The interface template file is heavily commented with explanations of each case.

Initialization

This corresponds to the 'constructor' and 'load' functions in the stage interface. When a chat is started, an initialization function is called in your stage with information about the chat and its participants. The stage has the opportunity to return some initialization-specific state information -- for a more detailed explanation of state types, see State.

Before a Prompt

This corresponds to the 'beforePrompt' function in the stage interface. When a user initiates a call to an LLM, the stage is first sent information on the prompt being sent, and has the chance to modify the user's message, save the stage's updated internal state, append something to the prompt, and attach a system message to the user's message.

After a Response

This corresponds to the 'afterResponse' function in the stage interface. When a response is fully received from the LLM, the stage has an opportunity to modify the response message, save the stage's updated internal state, and attach a system message to the bot's message.

On a Swipe or Jump

This corresponds to the 'setState' function in the stage interface. On a swipe or jump to a message that has already been seen previously, the stage is sent what its message-level state for that message was. For example, in a stage that shows a character's expression pack, the message-level state has each character's current emotion. Note how this is only one of the three types of state -- see State for more information.

Rendering

The 'render' function may be called at any time, and returns a ReactElement component. It's what your stage will look like. Try to avoid doing significant work inside this function.

Bottom-Up Communication Points (Experimental/Unstable)

Additionally, there are functions a stage may call at any time. They are contained in the 'generator' member of your stage class, i.e. it can be called with this.generator.someFunction(). Its interface is here: https://github.com/CharHubAI/chub-extensions-ts/blob/main/src/types/generation/service.ts. Note: of these, only {'makeImage', 'imageToImage', 'removeBackground', 'inpaintImage'} are implemented, and none of them are stable. For this reason, awaiting on any of them within any of the top-down communication points is not wise at this time. Best results are always with the 1:1 aspect ratio. Since these are ad-hoc generations meant to come back in a few seconds, there is a quality tradeoff. A proper imagegen and *gen UI with tradeoffs balanced towards higher quality is under development.

Last updated