Back to Onyx

README

backend/onyx/db/README.md

3.3.62.4 KB
Original Source

An explanation of how the history of messages, tool calls, and docs are stored in the database:

Messages are grouped by a chat session, a tree structured is used to allow edits and for the user to switch between branches. Each ChatMessage is either a user message or an assistant message. It should always alternate between the two, System messages, custom agent prompt injections, and reminder messages are injected dynamically after the chat session is loaded into memory. The user and assistant messages are stored in pairs, though it is ok if the user message is stored and the assistant message fails.

The user chat message is relatively simple and includes the user prompt and any attached documents. The assistant message includes the response, tool calls, feedback, citations, etc. Things provided as input are part of the user message, things that happen during the inference and LLM loop are part of the assistant message.

Reasoning is part of the message or tool call that occured after the reasoning. Really the reasoning should be part of the previous message / tool call because if it branches afterwards as a result of the reasoning, this is somewhat unintuitive. But to not include reasoning as part of the user message, it is instead included with the following message or tool call. With parallel tool calls, the reasoning will be included with each of the tool calls.

Tool calls are stored in the ToolCall table and can represent all of the following:

  • Parallel tool calls, these will have the same turn number and parent tool call id
  • Sequential tool calls, these will have a different turn number and parent tool call id
  • Tool calls attached to the ChatMessage are top level tool calls directly triggered by the LLM
  • Tool calls that are instead attached to other ToolCalls are tool calls that happen as part of an agent that has been called. The top level tool call is the agent call and the tool calls that have the agent call as a parent are the tool calls that happen as part of the agent.

The different branches are generated by sending a new search query to an existing parent.

                 [Empty Root Message]  (This allows the first message to be branched/edited as well)
              /           |           \
[First Message] [First Message Edit 1] [First Message Edit 2]
       |                  |
[Second Message]  [Second Message of Edit 1 Branch]