DataMind Oda keeps each chat's lasting record as a session log file on your computer. This page covers the format of that log: its header, the events inside it, and the rules Oda follows when reading and writing it. It is written for people who inspect, support or process chat logs. Where the files live and how Oda keeps them is covered in Chat logs on disk.
A log holds everything the model saw in the chat, in the order it happened:
The first line is the header. It names the chat and how it started, and Oda can read it on its own to decide how to treat the file before reading anything else. The header carries:
The number of inherited events is kept with the log, not among the records a reader replays.
Before trusting a header, Oda checks its fields:
id must be a string;session metadata createdAt must be a non-negative safe integer;cwd must be absolute.A log written by a different version of Oda is converted or refused when it opens; see Opening older chats.
Every message carries a role:
| Role | What it carries |
|---|---|
user | messages from you and other human input |
model | Oda's answers, including the reasoning that came with them |
tool | a tool result, as a message of its own |
developer | notes about which tools the model had |
Message content comes in a few kinds: text, reasoning, image, file, tool-call and tool-result. Images are held as attachments in PNG, JPEG, WebP or GIF; each image record carries its media type, its size and its dimensions.
Two details matter when you process a log:
Oda stores each value in a log exactly as it was, and refuses a value it cannot store that way instead of storing an approximation. This covers:
undefined members, and arrays with empty slots;The same test runs on the chat's metadata, refused with session metadata must be losslessly JSON-serializable. When a value is refused, nothing from that batch is stored. For the messages a failed check can show, see Chat log problems.
A log is read in pieces, not all at once. Saved events keep their order and their sequence numbers, and reading a log never changes it. A read asks for two things:
Both are whole numbers of zero or more; anything else is refused with read offset must be a non-negative safe integer, got <v> or read length must be a non-negative safe integer, got <v>, depending on which value is wrong. By default a read starts at the beginning and returns the rest of the log. A read that starts at or past the end returns nothing; it is not an error.
A later read never shows an older state than an earlier one.
Oda also keeps small current values built from a chat's log, so it can present the chat's state without replaying every event. These values are called read models.
-1.Everything the model saw in the chat: the messages, the tool calls and their results, the files and images, and the settings each request ran with, all in order. The header at the top names the chat and how it started.
Each message carries one of four roles: user, model, tool or developer. They say where the message came from; the table above lists what each role carries.
PNG, JPEG, WebP and GIF. An image is stored with its media type, its size and its dimensions, and a reference to the attachment that holds it.
So a reader sees every result exactly where it belongs in the conversation. The result message keeps the id of the call it answers and is marked when the call failed. Logs from older formats are converted as they open, and their results also become messages of their own.
Values that JSON cannot keep exactly: negative zero, infinity and NaN, undefined members, empty array slots, hidden or symbol-named members, cycles, and instances of custom classes. Oda refuses them rather than storing a changed value.
Ask for a starting position and a length. The position is the sequence number of the first event to return, and the length is how many events to return. By default a read returns the log from its start, and a position at or past the end returns nothing.
It is the sequence number of the last event that the snapshot's values account for, so you can tell how current they are. A chat with no events yet reports the position -1.
They can lag behind the chat, but they are never wrong: when a saved checkpoint no longer fits the log, Oda rebuilds the state from the log instead of serving it.