#![forbid(unsafe_code)]
#![warn(missing_docs)]
use serde::{Deserialize, Serialize};
pub type Handle = u32;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum MediaKind {
Text,
Image {
format: String,
},
Document {
pages: u32,
has_text_layer: bool,
},
Binary,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "cmd", rename_all = "snake_case")]
pub enum Command {
Infer {
prompt: String,
max_tokens: u32,
#[serde(default)]
images: Vec<Handle>,
},
Open {
path: String,
},
Slice {
handle: Handle,
offset: u64,
len: u64,
},
SliceBytes {
handle: Handle,
offset: u64,
len: u64,
},
PageText {
handle: Handle,
page: u32,
},
PageImage {
handle: Handle,
page: u32,
},
Emit {
progress: serde_json::Value,
},
Done {
result: serde_json::Value,
},
Fail {
code: String,
message: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum Event {
InferDone {
text: String,
tokens_out: u32,
},
Opened {
handle: Handle,
len: u64,
#[serde(default)]
kind: MediaKind,
},
Sliced {
text: String,
next_offset: u64,
},
SlicedBytes {
bytes_base64: String,
next_offset: u64,
},
PageTexted {
text: String,
},
PageImaged {
handle: Handle,
len: u64,
},
Emitted,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenAction {
Continue,
Stop,
}
impl TokenAction {
pub fn from_i32(v: i32) -> Self {
if v == 0 {
Self::Continue
} else {
Self::Stop
}
}
pub fn as_i32(self) -> i32 {
match self {
Self::Continue => 0,
Self::Stop => 1,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum JobStatus {
Queued,
Running,
Completed,
Failed,
Cancelled,
}
impl JobStatus {
pub fn is_terminal(self) -> bool {
matches!(self, Self::Completed | Self::Failed | Self::Cancelled)
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct Usage {
pub tokens_in: u32,
pub tokens_out: u32,
pub duration_ms: u64,
pub model: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Envelope {
pub status: JobStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JobError>,
pub usage: Usage,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct JobError {
pub code: String,
pub message: String,
}
pub mod error_codes {
pub const MODEL_LOAD_FAILED: &str = "model_load_failed";
pub const CAPABILITY_DENIED: &str = "capability_denied";
pub const SCHEMA_VALIDATION_FAILED: &str = "schema_validation_failed";
pub const WASM_TRAP: &str = "wasm_trap";
pub const TIMEOUT: &str = "timeout";
pub const CANCELLED: &str = "cancelled";
pub const UNSUPPORTED: &str = "unsupported";
}
impl Default for MediaKind {
fn default() -> Self {
Self::Text
}
}