// What the agent streams back while a prompt runs. One union, fourteen shapes, tagged by
// `sessionUpdate` on the wire.
///|
/// One streamed item of content.
#derive(Eq)
pub(all) struct ContentChunk {
content : ContentBlock
message_id : String?
meta : Json?
}
///|
pub extend ContentChunk with Eq::{equal, not_equal}
///|
pub extend ContentChunk with @json.ToJson::{to_json}
///|
pub impl ToJson for ContentChunk with fn to_json(self) {
json_of([
("content", Some(write(self.content))),
("messageId", json_string(self.message_id)),
("_meta", self.meta),
])
}
///|
pub extend ContentChunk with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for ContentChunk with fn from_json(json, path) {
let fields = expect_object(json, path)
{
content: required_object(fields, "content", path),
message_id: string_member(fields, "messageId", path),
meta: meta_of(fields, path),
}
}
///|
/// How urgent a plan entry is.
#derive(Eq)
pub(all) enum PlanEntryPriority {
High
Medium
Low
}
///|
pub extend PlanEntryPriority with Eq::{equal, not_equal}
///|
/// The name the priority travels as.
pub fn PlanEntryPriority::to_string(self : PlanEntryPriority) -> String {
match self {
High => "high"
Medium => "medium"
Low => "low"
}
}
///|
/// The priority with that name, or `None`.
pub fn PlanEntryPriority::of(name : String) -> PlanEntryPriority? {
match name {
"high" => Some(High)
"medium" => Some(Medium)
"low" => Some(Low)
_ => None
}
}
///|
pub extend PlanEntryPriority with @json.ToJson::{to_json}
///|
pub impl ToJson for PlanEntryPriority with fn to_json(self) {
Json::string(self.to_string())
}
///|
pub extend PlanEntryPriority with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for PlanEntryPriority with fn from_json(json, path) {
match PlanEntryPriority::of(text_of(json, path)) {
Some(priority) => priority
None => raise want(path, "a plan entry priority", json)
}
}
///|
/// How far a plan entry got.
#derive(Eq)
pub(all) enum PlanEntryStatus {
Pending
InProgress
Completed
}
///|
pub extend PlanEntryStatus with Eq::{equal, not_equal}
///|
/// The name the status travels as.
pub fn PlanEntryStatus::to_string(self : PlanEntryStatus) -> String {
match self {
Pending => "pending"
InProgress => "in_progress"
Completed => "completed"
}
}
///|
/// The status with that name, or `None`.
pub fn PlanEntryStatus::of(name : String) -> PlanEntryStatus? {
match name {
"pending" => Some(Pending)
"in_progress" => Some(InProgress)
"completed" => Some(Completed)
_ => None
}
}
///|
pub extend PlanEntryStatus with @json.ToJson::{to_json}
///|
pub impl ToJson for PlanEntryStatus with fn to_json(self) {
Json::string(self.to_string())
}
///|
pub extend PlanEntryStatus with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for PlanEntryStatus with fn from_json(json, path) {
match PlanEntryStatus::of(text_of(json, path)) {
Some(status) => status
None => raise want(path, "a plan entry status", json)
}
}
///|
/// One step of the agent's plan.
#derive(Eq)
pub(all) struct PlanEntry {
content : String
priority : PlanEntryPriority
status : PlanEntryStatus
meta : Json?
}
///|
pub extend PlanEntry with Eq::{equal, not_equal}
///|
pub extend PlanEntry with @json.ToJson::{to_json}
///|
pub impl ToJson for PlanEntry with fn to_json(self) {
json_of([
("content", Some(Json::string(self.content))),
("priority", Some(write(self.priority))),
("status", Some(write(self.status))),
("_meta", self.meta),
])
}
///|
pub extend PlanEntry with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for PlanEntry with fn from_json(json, path) {
let fields = expect_object(json, path)
{
content: required_string(fields, "content", path),
priority: required_enum(fields, "priority", path, PlanEntryPriority::of),
status: required_enum(fields, "status", path, PlanEntryStatus::of),
meta: meta_of(fields, path),
}
}
///|
/// The whole plan, replacing whatever came before.
#derive(Eq)
pub(all) struct Plan {
entries : Array[PlanEntry]
meta : Json?
}
///|
pub extend Plan with Eq::{equal, not_equal}
///|
pub extend Plan with @json.ToJson::{to_json}
///|
pub impl ToJson for Plan with fn to_json(self) {
json_of([
("entries", Some(Json::array(self.entries.map(write)))),
("_meta", self.meta),
])
}
///|
pub extend Plan with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Plan with fn from_json(json, path) {
let fields = expect_object(json, path)
{
entries: required_objects(fields, "entries", path),
meta: meta_of(fields, path),
}
}
///|
/// The text typed after a command's name, offered to the user as a hint.
#derive(Eq)
pub(all) struct CommandInput {
hint : String
meta : Json?
}
///|
pub extend CommandInput with Eq::{equal, not_equal}
///|
pub extend CommandInput with @json.ToJson::{to_json}
///|
pub impl ToJson for CommandInput with fn to_json(self) {
json_of([("hint", Some(Json::string(self.hint))), ("_meta", self.meta)])
}
///|
pub extend CommandInput with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for CommandInput with fn from_json(json, path) {
let fields = expect_object(json, path)
{ hint: required_string(fields, "hint", path), meta: meta_of(fields, path), }
}
///|
/// A slash command the user may type.
#derive(Eq)
pub(all) struct AvailableCommand {
name : String
description : String
input : CommandInput?
meta : Json?
}
///|
pub extend AvailableCommand with Eq::{equal, not_equal}
///|
pub extend AvailableCommand with @json.ToJson::{to_json}
///|
pub impl ToJson for AvailableCommand with fn to_json(self) {
json_of([
("name", Some(Json::string(self.name))),
("description", Some(Json::string(self.description))),
("input", self.input.map(write)),
("_meta", self.meta),
])
}
///|
pub extend AvailableCommand with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for AvailableCommand with fn from_json(json, path) {
let fields = expect_object(json, path)
{
name: required_string(fields, "name", path),
description: required_string(fields, "description", path),
input: object_member(fields, "input", path),
meta: meta_of(fields, path),
}
}
///|
/// The command list, replacing whatever came before.
#derive(Eq)
pub(all) struct AvailableCommands {
available_commands : Array[AvailableCommand]
meta : Json?
}
///|
pub extend AvailableCommands with Eq::{equal, not_equal}
///|
pub extend AvailableCommands with @json.ToJson::{to_json}
///|
pub impl ToJson for AvailableCommands with fn to_json(self) {
json_of([
("availableCommands", Some(Json::array(self.available_commands.map(write)))),
("_meta", self.meta),
])
}
///|
pub extend AvailableCommands with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for AvailableCommands with fn from_json(json, path) {
let fields = expect_object(json, path)
{
available_commands: required_objects(fields, "availableCommands", path),
meta: meta_of(fields, path),
}
}
///|
/// The session's mode changed.
#derive(Eq)
pub(all) struct ModeChanged {
current_mode_id : String
meta : Json?
}
///|
pub extend ModeChanged with Eq::{equal, not_equal}
///|
pub extend ModeChanged with @json.ToJson::{to_json}
///|
pub impl ToJson for ModeChanged with fn to_json(self) {
json_of([
("currentModeId", Some(Json::string(self.current_mode_id))),
("_meta", self.meta),
])
}
///|
pub extend ModeChanged with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for ModeChanged with fn from_json(json, path) {
let fields = expect_object(json, path)
{
current_mode_id: required_string(fields, "currentModeId", path),
meta: meta_of(fields, path),
}
}
///|
/// The session's metadata changed; only the fields that changed are present.
#derive(Eq)
pub(all) struct SessionInfoChanged {
title : String?
updated_at : String?
meta : Json?
}
///|
pub extend SessionInfoChanged with Eq::{equal, not_equal}
///|
pub extend SessionInfoChanged with @json.ToJson::{to_json}
///|
pub impl ToJson for SessionInfoChanged with fn to_json(self) {
json_of([
("title", json_string(self.title)),
("updatedAt", json_string(self.updated_at)),
("_meta", self.meta),
])
}
///|
pub extend SessionInfoChanged with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for SessionInfoChanged with fn from_json(json, path) {
let fields = expect_object(json, path)
{
title: string_member(fields, "title", path),
updated_at: string_member(fields, "updatedAt", path),
meta: meta_of(fields, path),
}
}
///|
/// What the turn cost, in whatever currency the agent bills in.
#derive(Eq)
pub(all) struct Cost {
amount : Double
currency : String
meta : Json?
}
///|
pub extend Cost with Eq::{equal, not_equal}
///|
pub extend Cost with @json.ToJson::{to_json}
///|
pub impl ToJson for Cost with fn to_json(self) {
json_of([
("amount", Some(Json::number(self.amount))),
("currency", Some(Json::string(self.currency))),
("_meta", self.meta),
])
}
///|
pub extend Cost with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Cost with fn from_json(json, path) {
let fields = expect_object(json, path)
{
amount: float_of(required(fields, "amount", path), path.add_key("amount")),
currency: required_string(fields, "currency", path),
meta: meta_of(fields, path),
}
}
///|
/// How much of the context window the conversation fills.
#derive(Eq)
pub(all) struct Usage {
used : Int64
size : Int64
cost : Cost?
meta : Json?
}
///|
pub extend Usage with Eq::{equal, not_equal}
///|
pub extend Usage with @json.ToJson::{to_json}
///|
pub impl ToJson for Usage with fn to_json(self) {
json_of([
("used", json_int(Some(self.used))),
("size", json_int(Some(self.size))),
("cost", self.cost.map(write)),
("_meta", self.meta),
])
}
///|
pub extend Usage with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Usage with fn from_json(json, path) {
let fields = expect_object(json, path)
{
used: int_of(required(fields, "used", path), path.add_key("used")),
size: int_of(required(fields, "size", path), path.add_key("size")),
cost: object_member(fields, "cost", path),
meta: meta_of(fields, path),
}
}
///|
/// How loud a notice is. Unknown severities are kept as they came.
#derive(Eq)
pub(all) enum Severity {
Info
Warning
Error
Other(String)
}
///|
pub extend Severity with Eq::{equal, not_equal}
///|
/// The name the severity travels as.
pub fn Severity::to_string(self : Severity) -> String {
match self {
Info => "info"
Warning => "warning"
Error => "error"
Other(name) => name
}
}
///|
/// The severity with that name; unknown names are kept as they came.
pub fn Severity::of(name : String) -> Severity {
match name {
"info" => Info
"warning" => Warning
"error" => Error
other => Other(other)
}
}
///|
pub extend Severity with @json.ToJson::{to_json}
///|
pub impl ToJson for Severity with fn to_json(self) {
Json::string(self.to_string())
}
///|
pub extend Severity with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Severity with fn from_json(json, path) {
Severity::of(text_of(json, path))
}
///|
/// Something to tell the user that is not part of the conversation.
#derive(Eq)
pub(all) struct Notice {
severity : Severity
title : String
description : String?
meta : Json?
}
///|
pub extend Notice with Eq::{equal, not_equal}
///|
pub extend Notice with @json.ToJson::{to_json}
///|
pub impl ToJson for Notice with fn to_json(self) {
json_of([
("severity", Some(write(self.severity))),
("title", Some(Json::string(self.title))),
("description", json_string(self.description)),
("_meta", self.meta),
])
}
///|
pub extend Notice with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Notice with fn from_json(json, path) {
let fields = expect_object(json, path)
{
severity: required_enum(fields, "severity", path, name => {
Some(Severity::of(name))
}),
title: required_string(fields, "title", path),
description: string_member(fields, "description", path),
meta: meta_of(fields, path),
}
}
///|
/// Where a context compaction got to. Unknown states are kept as they came.
#derive(Eq)
pub(all) enum CompactionStatus {
InProgress
Completed
Failed
Cancelled
Other(String)
}
///|
pub extend CompactionStatus with Eq::{equal, not_equal}
///|
/// The name the state travels as.
pub fn CompactionStatus::to_string(self : CompactionStatus) -> String {
match self {
InProgress => "in_progress"
Completed => "completed"
Failed => "failed"
Cancelled => "cancelled"
Other(name) => name
}
}
///|
/// The state with that name; unknown names are kept as they came.
pub fn CompactionStatus::of(name : String) -> CompactionStatus {
match name {
"in_progress" => InProgress
"completed" => Completed
"failed" => Failed
"cancelled" => Cancelled
other => Other(other)
}
}
///|
pub extend CompactionStatus with @json.ToJson::{to_json}
///|
pub impl ToJson for CompactionStatus with fn to_json(self) {
Json::string(self.to_string())
}
///|
pub extend CompactionStatus with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for CompactionStatus with fn from_json(json, path) {
CompactionStatus::of(text_of(json, path))
}
///|
/// A compaction, created the first time its identifier is seen and updated after that.
#derive(Eq)
pub(all) struct Compaction {
compaction_id : String
status : CompactionStatus
summary : Array[ContentBlock]?
error : String?
meta : Json?
}
///|
pub extend Compaction with Eq::{equal, not_equal}
///|
pub extend Compaction with @json.ToJson::{to_json}
///|
pub impl ToJson for Compaction with fn to_json(self) {
json_of([
("compactionId", Some(Json::string(self.compaction_id))),
("status", Some(write(self.status))),
("summary", json_list_of(self.summary)),
("error", json_string(self.error)),
("_meta", self.meta),
])
}
///|
pub extend Compaction with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for Compaction with fn from_json(json, path) {
let fields = expect_object(json, path)
{
compaction_id: required_string(fields, "compactionId", path),
status: required_enum(fields, "status", path, name => {
Some(CompactionStatus::of(name))
}),
summary: list_member(fields, "summary", path, (value, at) => read(value, at)),
error: string_member(fields, "error", path),
meta: meta_of(fields, path),
}
}
///|
/// One more block of a compaction's retained summary.
#derive(Eq)
pub(all) struct CompactionSummary {
compaction_id : String
content : ContentBlock
meta : Json?
}
///|
pub extend CompactionSummary with Eq::{equal, not_equal}
///|
pub extend CompactionSummary with @json.ToJson::{to_json}
///|
pub impl ToJson for CompactionSummary with fn to_json(self) {
json_of([
("compactionId", Some(Json::string(self.compaction_id))),
("content", Some(write(self.content))),
("_meta", self.meta),
])
}
///|
pub extend CompactionSummary with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for CompactionSummary with fn from_json(json, path) {
let fields = expect_object(json, path)
{
compaction_id: required_string(fields, "compactionId", path),
content: required_object(fields, "content", path),
meta: meta_of(fields, path),
}
}
///|
/// Everything the agent may tell the client mid-turn, tagged by `sessionUpdate` on the wire.
#derive(Eq)
pub(all) enum SessionUpdate {
UserMessageChunk(ContentChunk)
AgentMessageChunk(ContentChunk)
AgentThoughtChunk(ContentChunk)
ToolCall(ToolCall)
ToolCallUpdate(ToolCallUpdate)
Plan(Plan)
AvailableCommands(AvailableCommands)
ModeChanged(ModeChanged)
ConfigOptionChanged(Array[ConfigOption])
SessionInfoChanged(SessionInfoChanged)
Usage(Usage)
Notice(Notice)
Compaction(Compaction)
CompactionSummary(CompactionSummary)
}
///|
pub extend SessionUpdate with Eq::{equal, not_equal}
///|
pub extend SessionUpdate with @json.ToJson::{to_json}
///|
pub impl ToJson for SessionUpdate with fn to_json(self) {
match self {
UserMessageChunk(chunk) =>
json_tagged(write(chunk), "sessionUpdate", "user_message_chunk")
AgentMessageChunk(chunk) =>
json_tagged(write(chunk), "sessionUpdate", "agent_message_chunk")
AgentThoughtChunk(chunk) =>
json_tagged(write(chunk), "sessionUpdate", "agent_thought_chunk")
ToolCall(call) => json_tagged(write(call), "sessionUpdate", "tool_call")
ToolCallUpdate(update) =>
json_tagged(write(update), "sessionUpdate", "tool_call_update")
Plan(plan) => json_tagged(write(plan), "sessionUpdate", "plan")
AvailableCommands(commands) =>
json_tagged(write(commands), "sessionUpdate", "available_commands_update")
ModeChanged(change) =>
json_tagged(write(change), "sessionUpdate", "current_mode_update")
ConfigOptionChanged(options) =>
json_tagged(
json_of([("configOptions", Some(Json::array(options.map(write))))]),
"sessionUpdate",
"config_option_update",
)
SessionInfoChanged(change) =>
json_tagged(write(change), "sessionUpdate", "session_info_update")
Usage(usage) => json_tagged(write(usage), "sessionUpdate", "usage_update")
Notice(notice) => json_tagged(write(notice), "sessionUpdate", "notice")
Compaction(compaction) =>
json_tagged(write(compaction), "sessionUpdate", "compaction_update")
CompactionSummary(chunk) =>
json_tagged(write(chunk), "sessionUpdate", "compaction_summary_chunk")
}
}
///|
pub extend SessionUpdate with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for SessionUpdate with fn from_json(json, path) {
let fields = expect_object(json, path)
match required_string(fields, "sessionUpdate", path) {
"user_message_chunk" => UserMessageChunk(read(json, path))
"agent_message_chunk" => AgentMessageChunk(read(json, path))
"agent_thought_chunk" => AgentThoughtChunk(read(json, path))
"tool_call" => ToolCall(read(json, path))
"tool_call_update" => ToolCallUpdate(read(json, path))
"plan" => Plan(read(json, path))
"available_commands_update" => AvailableCommands(read(json, path))
"current_mode_update" => ModeChanged(read(json, path))
"config_option_update" =>
ConfigOptionChanged(required_objects(fields, "configOptions", path))
"session_info_update" => SessionInfoChanged(read(json, path))
"usage_update" => Usage(read(json, path))
"notice" => Notice(read(json, path))
"compaction_update" => Compaction(read(json, path))
"compaction_summary_chunk" => CompactionSummary(read(json, path))
other =>
raise @json.JsonDecodeError(
(path.add_key("sessionUpdate"), "unknown update \{other}"),
)
}
}
///|
/// One update as it travels: the session it belongs to and the update itself.
#derive(Eq)
pub(all) struct SessionNotification {
session_id : String
update : SessionUpdate
meta : Json?
}
///|
pub extend SessionNotification with Eq::{equal, not_equal}
///|
pub extend SessionNotification with @json.ToJson::{to_json}
///|
pub impl ToJson for SessionNotification with fn to_json(self) {
json_of([
("sessionId", Some(Json::string(self.session_id))),
("update", Some(write(self.update))),
("_meta", self.meta),
])
}
///|
pub extend SessionNotification with @json.FromJson::{from_json}
///|
pub impl @json.FromJson for SessionNotification with fn from_json(json, path) {
let fields = expect_object(json, path)
{
session_id: required_string(fields, "sessionId", path),
update: required_object(fields, "update", path),
meta: meta_of(fields, path),
}
}