openagents_sdk::chats::wire
What the chat API sends and takes (/v1/threads, its messages, and its
event stream), with the rules every client applies to it. Nothing here
makes a request, so the desktop and phone apps (through [crate::chats]'s
calls) and the website's GPUI chat (through the browser's fetch and
EventSource) read the same values the same way.
Rows are read leniently: a field the service adds later is ignored, and
one it leaves out, or sends as null, takes its default.
| Item | What it does |
|---|---|
BadEvent struct | An event [`Event::read`] refused. |
Change struct | The body of `PATCH /v1/threads/{id}`: only what changes. |
Content struct | One part of a [`MessageRow`]. |
Event enum | One event of a turn's stream: message text, tool output, cards, the end, or an error. |
FileRef struct | A file sent with a message. |
Filing struct | Whether a chat is pinned and archived, as the service reports it after a change. |
Frames struct | Splits a turn's event stream into the `data` of each event, as the bytes arrive. |
MessageBody struct | The body of `POST /v1/threads` and `POST /v1/threads/{id}/messages`. |
MessageRow struct | One message in `GET /v1/threads/{id}/messages`, which keeps every message and its position (`msg_{index}`). |
Page struct | A page of `{data, next}`. |
Refusal struct | A refused turn: its code, a message to show, and when to try again. |
RefusalCode enum | Why the service refused or ended a turn. |
Started struct | `201 {id, answering}` from `POST /v1/threads`. |
Stopped struct | The service's answer to a stop request. |
Thread struct | One chat in `GET /v1/threads`, and the row of `GET /v1/threads/{id}`. |
ThreadDetail struct | `GET /v1/threads/{id}`: the row and its newest messages, empty ones left out. |
ThreadList struct | `GET /v1/threads`. |
ThreadMessage struct | One message in `GET /v1/threads/{id}`. |
TooLarge struct | A stream that sent more than [`Frames::LIMIT`] without ending an event. |
is_request_id fn | Whether `id` is a request ID the service takes: a lowercase or uppercase hex UUID with its dashes. |
message_ok fn | Whether `text` may be sent: not blank, and at most [`MAX_MESSAGE_CHARS`]. |
title fn | `title` trimmed, when it may name a chat: not blank, at most [`MAX_TITLE_CHARS`], and without control characters. |
MAX_EVENT_INDEX const | The highest message index a turn's events may name. |
MAX_MESSAGE_CHARS const | The longest message, in characters, a turn may send. |
MAX_TITLE_CHARS const | The longest chat title, in characters. |
BadEvent
pub struct BadEvent;
An event [Event::read] refused.
Change
pub struct Change {
pub title: Option<String>,
pub pinned: Option<bool>,
pub archived: Option<bool>,
pub project: Option<Option<String>>,
}
The body of PATCH /v1/threads/{id}: only what changes.
Content
pub struct Content {
pub kind: String,
pub text: String,
}
One part of a [MessageRow].
Event
pub enum Event {
Text {
request_id: String,
index: usize,
role: crate::MessageRole,
text: String,
replace: bool,
},
Tool {
request_id: String,
index: usize,
role: crate::MessageRole,
text: String,
replace: bool,
},
Cards { request_id: String, cards: Value },
Done { request_id: String, outcome: String, revision: u64 },
Error { request_id: String, error: Refusal },
}
One event of a turn's stream: message text, tool output, cards, the end, or an error.
Event::request_id
pub fn request_id(&self) -> &str
The request this event belongs to.
Event::read
pub fn read(data: &str, request_id: &str) -> Result<Self, BadEvent>
Reads one event's data for the turn request_id. Refuses an event
that isn't JSON, belongs to another turn, or names a message past
[MAX_EVENT_INDEX].
Event::ends
pub fn ends(&self) -> bool
Whether the turn's stream ends after this event.
Event::card_list
pub fn card_list(&self) -> Vec<Value>
The cards a [Event::Cards] carries, each one card's object.
FileRef
pub struct FileRef {
pub id: String,
pub name: String,
pub kind: String,
pub size: u64,
}
A file sent with a message.
Filing
pub struct Filing {
pub pinned: bool,
pub archived: bool,
}
Whether a chat is pinned and archived, as the service reports it after a change.
Frames
pub struct Frames {}
Splits a turn's event stream into the data of each event, as the bytes
arrive. The native client reads the response through it; a browser's
EventSource does the same splitting itself.
Frames::push
pub fn push(&mut self, chunk: &[u8]) -> Result<(), TooLarge>
Adds bytes read from the stream. Refuses more than [Frames::LIMIT] unread.
Frames::next
pub fn next(&mut self) -> Result<Option<String>, BadEvent>
The next whole event's data lines, joined, or None until more
bytes arrive. An event with no data (a comment or keepalive) is skipped.
MessageBody
pub struct MessageBody<'a> {
pub request_id: &'a str,
pub text: &'a str,
pub project: Option<&'a str>,
}
The body of POST /v1/threads and POST /v1/threads/{id}/messages.
MessageRow
pub struct MessageRow {
pub id: String,
pub role: String,
pub content: Vec<Content>,
}
One message in GET /v1/threads/{id}/messages, which keeps every
message and its position (msg_{index}).
MessageRow::index
pub fn index(&self) -> Option<usize>
Its position in the chat.
MessageRow::text
pub fn text(&self) -> String
Its text parts, joined by line breaks.
Page
pub struct Page<T> {
pub data: Vec<T>,
pub next: Option<String>,
}
A page of {data, next}.
Refusal
pub struct Refusal {
pub code: RefusalCode,
pub message: String,
pub retry_after_ms: Option<u64>,
}
A refused turn: its code, a message to show, and when to try again.
RefusalCode
pub enum RefusalCode {
QuotaExhausted,
RateLimited,
Busy,
Unavailable,
Timeout,
AccessLost,
StreamTimeout,
Other(String),
}
Why the service refused or ended a turn.
Started
pub struct Started {
pub id: String,
pub answering: bool,
}
201 {id, answering} from POST /v1/threads.
Stopped
pub struct Stopped {
pub request_id: String,
pub stopped: bool,
pub finished: bool,
}
The service's answer to a stop request.
Thread
pub struct Thread {
pub id: String,
pub request_id: Option<String>,
pub outcome: Option<String>,
pub title: String,
pub line: String,
pub surface: String,
pub computer: Option<String>,
pub updated_unix: u64,
pub working: bool,
pub online: bool,
pub can_reply: bool,
pub pinned: bool,
pub project: Option<String>,
pub messages: usize,
}
One chat in GET /v1/threads, and the row of GET /v1/threads/{id}.
Thread::pending
pub fn pending(&self) -> bool
Whether an answer is being written now.
Thread::synced
pub fn synced(&self) -> bool
Whether the chat lives on a computer or phone rather than here.
ThreadDetail
pub struct ThreadDetail {
pub thread: Thread,
pub messages: Vec<ThreadMessage>,
pub earlier: usize,
}
GET /v1/threads/{id}: the row and its newest messages, empty ones left out.
ThreadList
pub struct ThreadList {
pub threads: Vec<Thread>,
pub total: usize,
pub more: bool,
pub next_offset: Option<usize>,
}
GET /v1/threads.
ThreadMessage
pub struct ThreadMessage {
pub role: String,
pub text: String,
pub files: Vec<FileRef>,
}
One message in GET /v1/threads/{id}.
TooLarge
pub struct TooLarge;
A stream that sent more than [Frames::LIMIT] without ending an event.
is_request_id
pub fn is_request_id(id: &str) -> bool
Whether id is a request ID the service takes: a lowercase or uppercase
hex UUID with its dashes.
message_ok
pub fn message_ok(text: &str) -> bool
Whether text may be sent: not blank, and at most [MAX_MESSAGE_CHARS].
title
pub fn title(title: &str) -> Option<&str>
title trimmed, when it may name a chat: not blank, at most
[MAX_TITLE_CHARS], and without control characters.
MAX_EVENT_INDEX
pub const MAX_EVENT_INDEX: usize = 4000;
The highest message index a turn's events may name.
MAX_MESSAGE_CHARS
pub const MAX_MESSAGE_CHARS: usize = 4000;
The longest message, in characters, a turn may send.
MAX_TITLE_CHARS
pub const MAX_TITLE_CHARS: usize = 120;
The longest chat title, in characters.