#![forbid(unsafe_code)]
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::{Value, json};
use std::collections::HashSet;
use std::fmt;
use thiserror::Error;
mod catalog_proof;
mod route_identity;
pub use catalog_proof::*;
pub use route_identity::*;
pub const M1_WIRE_VERSION: &str = "2026-07-24.m1";
pub const MAX_SPEND_AUTHORIZATION_MICRO_USD: u64 = 10_000_000;
macro_rules! identifier {
($name:ident) => {
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
#[serde(transparent)]
pub struct $name(String);
impl $name {
pub fn parse(value: impl Into<String>) -> Result<Self, ValidationError> {
let value = value.into();
if value.is_empty()
|| value.len() > 128
|| !value.bytes().all(|byte| {
byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_' | b'.' | b':')
})
{
return Err(ValidationError::InvalidIdentifier(stringify!($name)));
}
Ok(Self(value))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for $name {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(&self.0)
}
}
impl<'de> Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
Self::parse(value).map_err(serde::de::Error::custom)
}
}
};
}
identifier!(HarnessInstanceId);
identifier!(SessionId);
identifier!(TurnId);
identifier!(RequestId);
identifier!(AttemptId);
identifier!(ResponseId);
identifier!(ItemId);
identifier!(CallId);
#[derive(Debug, Error, PartialEq, Eq)]
pub enum ValidationError {
#[error("an identifier is invalid")]
InvalidIdentifier(&'static str),
#[error("the wire version is unsupported")]
UnsupportedWireVersion,
#[error("streaming is required")]
StreamingRequired,
#[error("the request contains a non-translatable capability")]
NonTranslatableCapability,
#[error("the tool definition is invalid or collides with another tool")]
InvalidToolDefinition,
#[error("the request declares an invalid spend authorization")]
InvalidSpendAuthorization,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CanonicalRequest {
pub wire_version: String,
pub model: String,
pub stream: bool,
pub harness_instance: HarnessInstanceId,
pub session_id: SessionId,
pub turn_id: TurnId,
pub input: Vec<InputItem>,
#[serde(default)]
pub tools: Vec<FunctionTool>,
#[serde(default)]
pub tool_choice: ToolChoice,
#[serde(default)]
pub structured_output: Option<StructuredOutputIntent>,
#[serde(default)]
pub reasoning: ReasoningIntent,
#[serde(default)]
pub max_output_tokens: Option<u32>,
#[serde(default)]
pub max_spend_micro_usd: Option<u64>,
#[serde(default)]
pub capabilities: CapabilityRequirements,
}
impl CanonicalRequest {
pub fn validate(&self) -> Result<(), ValidationError> {
if self.wire_version != M1_WIRE_VERSION {
return Err(ValidationError::UnsupportedWireVersion);
}
if !self.stream {
return Err(ValidationError::StreamingRequired);
}
if let Some(max_spend) = self.max_spend_micro_usd
&& max_spend > MAX_SPEND_AUTHORIZATION_MICRO_USD
{
return Err(ValidationError::InvalidSpendAuthorization);
}
validate_tools(&self.tools)?;
if let ToolChoice::Named(name) = &self.tool_choice {
validate_tool_name(name)?;
if self.tools.iter().filter(|tool| tool.name == *name).count() != 1 {
return Err(ValidationError::InvalidToolDefinition);
}
}
for item in &self.input {
if let InputItem::FunctionCall {
namespace, name, ..
} = item
{
validate_tool_name(name)?;
if let Some(namespace) = namespace {
validate_tool_namespace(namespace)?;
}
}
}
Ok(())
}
pub fn function_output(&self) -> Option<(&CallId, &Value)> {
self.input.iter().find_map(|item| match item {
InputItem::FunctionCallOutput { call_id, output } => Some((call_id, output)),
InputItem::Message { .. } | InputItem::FunctionCall { .. } => None,
})
}
pub fn function_call(&self, expected_call_id: &CallId) -> Option<(Option<&str>, &str)> {
self.input.iter().find_map(|item| match item {
InputItem::FunctionCall {
call_id,
namespace,
name,
..
} if call_id == expected_call_id => Some((namespace.as_deref(), name.as_str())),
InputItem::Message { .. }
| InputItem::FunctionCall { .. }
| InputItem::FunctionCallOutput { .. } => None,
})
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case", deny_unknown_fields)]
pub enum InputItem {
Message {
role: MessageRole,
content: Vec<ContentBlock>,
},
FunctionCall {
call_id: CallId,
#[serde(default, skip_serializing_if = "Option::is_none")]
namespace: Option<String>,
name: String,
arguments: Value,
},
FunctionCallOutput {
call_id: CallId,
output: Value,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MessageRole {
Developer,
System,
User,
Assistant,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case", deny_unknown_fields)]
pub enum ContentBlock {
Text { text: String },
ImageReference { url: String },
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FunctionTool {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
pub name: String,
pub description: String,
pub parameters: Value,
pub strict: bool,
}
pub const MAX_TOOL_COMPONENT_BYTES: usize = 64;
pub fn validate_tool_name(value: &str) -> Result<(), ValidationError> {
validate_tool_component(value)
}
pub fn validate_tool_namespace(value: &str) -> Result<(), ValidationError> {
validate_tool_component(value)?;
if matches!(
value,
"function" | "custom" | "namespace" | "tool_search" | "web_search"
) {
return Err(ValidationError::InvalidToolDefinition);
}
Ok(())
}
fn validate_tool_component(value: &str) -> Result<(), ValidationError> {
if value.is_empty()
|| value.len() > MAX_TOOL_COMPONENT_BYTES
|| !value
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-'))
{
return Err(ValidationError::InvalidToolDefinition);
}
Ok(())
}
fn validate_tools(tools: &[FunctionTool]) -> Result<(), ValidationError> {
let mut identities = HashSet::new();
let mut namespaces = HashSet::new();
let mut direct_names = HashSet::new();
for tool in tools {
validate_tool_name(&tool.name)?;
if let Some(namespace) = &tool.namespace {
validate_tool_namespace(namespace)?;
namespaces.insert(namespace.as_str());
} else {
direct_names.insert(tool.name.as_str());
}
if !identities.insert((tool.namespace.as_deref(), tool.name.as_str())) {
return Err(ValidationError::InvalidToolDefinition);
}
}
if namespaces
.iter()
.any(|namespace| direct_names.contains(namespace))
{
return Err(ValidationError::InvalidToolDefinition);
}
Ok(())
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolChoice {
#[default]
Auto,
None,
Required,
Named(String),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct StructuredOutputIntent {
pub name: String,
pub schema: Value,
pub strict: bool,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningIntent {
#[default]
None,
PublicSummary,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CapabilityRequirements {
#[serde(default)]
pub images: bool,
#[serde(default)]
pub structured_output: bool,
#[serde(default)]
pub public_reasoning: bool,
#[serde(default)]
pub audio: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ProviderCapabilities {
pub images: bool,
pub structured_output: bool,
pub public_reasoning: bool,
pub audio: bool,
}
impl CapabilityRequirements {
pub fn preflight(&self, supported: ProviderCapabilities) -> Result<(), PublicErrorCode> {
if (self.images && !supported.images)
|| (self.structured_output && !supported.structured_output)
|| (self.public_reasoning && !supported.public_reasoning)
|| (self.audio && !supported.audio)
{
return Err(PublicErrorCode::UnsupportedCapability);
}
Ok(())
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PublicErrorCode {
InvalidRequest,
AuthenticationRequired,
ModelNotFound,
UnsupportedCapability,
UnsupportedWireCombination,
RouterUnavailable,
CorrelationMismatch,
ProviderFailure,
}
impl PublicErrorCode {
pub fn as_str(&self) -> &'static str {
match self {
Self::InvalidRequest => "invalid_request",
Self::AuthenticationRequired => "authentication_required",
Self::ModelNotFound => "model_not_found",
Self::UnsupportedCapability => "unsupported_capability",
Self::UnsupportedWireCombination => "unsupported_wire_combination",
Self::RouterUnavailable => "router_unavailable",
Self::CorrelationMismatch => "correlation_mismatch",
Self::ProviderFailure => "provider_failure",
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PublicError {
pub code: PublicErrorCode,
pub message: String,
pub request_id: RequestId,
pub retryable: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option<Value>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum InterruptionCause {
ProviderFailure,
MalformedStream,
Timeout,
Cancelled,
}
impl InterruptionCause {
const fn as_str(self) -> &'static str {
match self {
Self::ProviderFailure => "provider_failure",
Self::MalformedStream => "malformed_stream",
Self::Timeout => "timeout",
Self::Cancelled => "cancelled",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SafeResumeBoundary {
PublicOutput,
ToolCall,
ForwardedToolResult,
}
impl SafeResumeBoundary {
const fn as_str(self) -> &'static str {
match self {
Self::PublicOutput => "public_output",
Self::ToolCall => "tool_call",
Self::ForwardedToolResult => "forwarded_tool_result",
}
}
}
impl PublicError {
pub fn redacted(code: PublicErrorCode, request_id: RequestId, retryable: bool) -> Self {
let message = match code {
PublicErrorCode::InvalidRequest => "The request is invalid.",
PublicErrorCode::AuthenticationRequired => "Local authentication is required.",
PublicErrorCode::ModelNotFound => "The requested model alias is unavailable.",
PublicErrorCode::UnsupportedCapability => {
"The route does not support a required capability."
}
PublicErrorCode::UnsupportedWireCombination => {
"The requested wire combination is unsupported."
}
PublicErrorCode::RouterUnavailable => "The local router is unavailable.",
PublicErrorCode::CorrelationMismatch => "The tool result correlation is invalid.",
PublicErrorCode::ProviderFailure => "The transformed provider failed.",
};
Self {
code,
message: message.to_owned(),
request_id,
retryable,
details: None,
}
}
pub fn interrupted(
request_id: RequestId,
cause: InterruptionCause,
boundary: SafeResumeBoundary,
) -> Self {
let mut error = Self::redacted(PublicErrorCode::ProviderFailure, request_id, false);
error.message = "The provider stream stopped after a non-replayable boundary.".to_owned();
error.details = Some(json!({
"interruption": {
"cause": cause.as_str(),
"boundary": boundary.as_str(),
"automatic_replay": false,
"safe_resume": {
"action": "start_new_turn",
"preserve_visible_output": true,
"repeat_completed_tool_calls": false
}
}
}));
error
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SubagentDisposition {
Native,
Emulated,
Refused { reason: String },
}
impl SubagentDisposition {
pub fn derive(native_selected: bool, emulation_enabled: bool) -> Self {
if native_selected {
Self::Native
} else if emulation_enabled {
Self::Emulated
} else {
Self::Refused {
reason: "no_phase_serves_subagents_natively_and_emulation_is_disabled".to_owned(),
}
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum CanonicalEvent {
#[serde(rename = "response.created")]
ResponseCreated {
response_id: ResponseId,
request_id: RequestId,
sequence: u64,
},
#[serde(rename = "response.in_progress")]
ResponseInProgress {
response_id: ResponseId,
sequence: u64,
},
#[serde(rename = "response.output_item.added")]
OutputItemAdded {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
item_kind: OutputItemKind,
#[serde(skip_serializing_if = "Option::is_none")]
call_id: Option<CallId>,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
namespace: Option<String>,
},
#[serde(rename = "response.output_item.done")]
OutputItemDone {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
#[serde(skip_serializing_if = "Option::is_none")]
call_id: Option<CallId>,
},
#[serde(rename = "response.content_part.added")]
ContentPartAdded {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
},
#[serde(rename = "response.content_part.done")]
ContentPartDone {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
},
#[serde(rename = "response.output_text.delta")]
OutputTextDelta {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
delta: String,
},
#[serde(rename = "response.output_text.done")]
OutputTextDone {
response_id: ResponseId,
item_id: ItemId,
sequence: u64,
text: String,
},
#[serde(rename = "response.function_call_arguments.delta")]
FunctionCallArgumentsDelta {
response_id: ResponseId,
item_id: ItemId,
call_id: CallId,
sequence: u64,
delta: String,
},
#[serde(rename = "response.function_call_arguments.done")]
FunctionCallArgumentsDone {
response_id: ResponseId,
item_id: ItemId,
call_id: CallId,
sequence: u64,
arguments: Value,
},
#[serde(rename = "response.completed")]
ResponseCompleted {
response_id: ResponseId,
sequence: u64,
usage: Usage,
},
#[serde(rename = "response.failed")]
ResponseFailed {
response_id: ResponseId,
sequence: u64,
error: PublicError,
},
#[serde(rename = "error")]
Error { sequence: u64, error: PublicError },
}
impl CanonicalEvent {
pub fn event_name(&self) -> &'static str {
match self {
Self::ResponseCreated { .. } => "response.created",
Self::ResponseInProgress { .. } => "response.in_progress",
Self::OutputItemAdded { .. } => "response.output_item.added",
Self::OutputItemDone { .. } => "response.output_item.done",
Self::ContentPartAdded { .. } => "response.content_part.added",
Self::ContentPartDone { .. } => "response.content_part.done",
Self::OutputTextDelta { .. } => "response.output_text.delta",
Self::OutputTextDone { .. } => "response.output_text.done",
Self::FunctionCallArgumentsDelta { .. } => "response.function_call_arguments.delta",
Self::FunctionCallArgumentsDone { .. } => "response.function_call_arguments.done",
Self::ResponseCompleted { .. } => "response.completed",
Self::ResponseFailed { .. } => "response.failed",
Self::Error { .. } => "error",
}
}
pub fn visibility(&self) -> EventVisibility {
match self {
Self::OutputTextDelta { .. }
| Self::OutputTextDone { .. }
| Self::ContentPartAdded { .. }
| Self::ContentPartDone { .. } => EventVisibility::PublicOutput,
Self::OutputItemAdded {
item_kind: OutputItemKind::FunctionCall,
..
}
| Self::FunctionCallArgumentsDelta { .. }
| Self::FunctionCallArgumentsDone { .. } => EventVisibility::ToolCall,
_ => EventVisibility::None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OutputItemKind {
Message,
FunctionCall,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Usage {
pub input_tokens: u64,
pub output_tokens: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EventVisibility {
None,
PublicOutput,
ToolCall,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum VisibilityState {
PreVisible,
VisibleOutput,
ToolVisible,
VisibleOutputAndTool,
TransportAmbiguous,
}
#[derive(Debug)]
pub struct ReplayGuard {
state: VisibilityState,
}
#[derive(Debug)]
pub struct ReplayAuthorization(());
impl Default for ReplayGuard {
fn default() -> Self {
Self {
state: VisibilityState::PreVisible,
}
}
}
impl ReplayGuard {
pub fn observe(&mut self, visibility: EventVisibility) {
self.state = match (self.state, visibility) {
(state, EventVisibility::None) => state,
(VisibilityState::PreVisible, EventVisibility::PublicOutput) => {
VisibilityState::VisibleOutput
}
(VisibilityState::PreVisible, EventVisibility::ToolCall) => {
VisibilityState::ToolVisible
}
(VisibilityState::VisibleOutput, EventVisibility::ToolCall)
| (VisibilityState::ToolVisible, EventVisibility::PublicOutput) => {
VisibilityState::VisibleOutputAndTool
}
(state, EventVisibility::PublicOutput | EventVisibility::ToolCall) => state,
};
}
pub fn mark_transport_ambiguous(&mut self) {
self.state = VisibilityState::TransportAmbiguous;
}
pub fn mark_tool_result_forwarded(&mut self) {
self.state = VisibilityState::ToolVisible;
}
pub fn authorize_transient_retry(&self) -> Option<ReplayAuthorization> {
(self.state == VisibilityState::PreVisible).then_some(ReplayAuthorization(()))
}
pub fn state(&self) -> VisibilityState {
self.state
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn strict_request_rejects_hidden_reasoning_and_unknown_fields() {
let request = json!({
"wire_version": M1_WIRE_VERSION,
"model": "router-auto",
"stream": true,
"harness_instance": "cli",
"session_id": "session-1",
"turn_id": "turn-1",
"input": [],
"encrypted_reasoning": "must-not-cross"
});
assert!(serde_json::from_value::<CanonicalRequest>(request).is_err());
}
#[test]
fn identifier_deserialization_enforces_constructor_invariants() {
for invalid in [json!(""), json!("line\nbreak"), json!("x".repeat(129))] {
assert!(serde_json::from_value::<SessionId>(invalid).is_err());
}
assert_eq!(
serde_json::from_value::<SessionId>(json!("session-safe_1"))
.expect("valid identifier")
.as_str(),
"session-safe_1"
);
}
#[test]
fn replay_truth_table_is_fail_closed() {
let mut pre = ReplayGuard::default();
assert!(pre.authorize_transient_retry().is_some());
pre.observe(EventVisibility::PublicOutput);
assert!(pre.authorize_transient_retry().is_none());
let mut tool = ReplayGuard::default();
tool.observe(EventVisibility::ToolCall);
assert!(tool.authorize_transient_retry().is_none());
let mut both = ReplayGuard::default();
both.observe(EventVisibility::PublicOutput);
both.observe(EventVisibility::ToolCall);
assert!(both.authorize_transient_retry().is_none());
let mut ambiguous = ReplayGuard::default();
ambiguous.mark_transport_ambiguous();
assert!(ambiguous.authorize_transient_retry().is_none());
let mut forwarded_result = ReplayGuard::default();
forwarded_result.mark_tool_result_forwarded();
assert!(forwarded_result.authorize_transient_retry().is_none());
}
#[test]
fn structured_interruption_has_one_safe_non_replay_resume_action() {
let error = PublicError::interrupted(
RequestId::parse("request-interrupted").expect("fixture ID"),
InterruptionCause::ProviderFailure,
SafeResumeBoundary::ForwardedToolResult,
);
assert_eq!(error.code, PublicErrorCode::ProviderFailure);
assert!(!error.retryable);
assert_eq!(
error.details,
Some(json!({
"interruption": {
"cause": "provider_failure",
"boundary": "forwarded_tool_result",
"automatic_replay": false,
"safe_resume": {
"action": "start_new_turn",
"preserve_visible_output": true,
"repeat_completed_tool_calls": false
}
}
}))
);
}
#[test]
fn named_tool_choice_requires_one_unambiguous_declared_tool() {
let function = |namespace: Option<&str>| FunctionTool {
namespace: namespace.map(str::to_owned),
name: "lookup".to_owned(),
description: "fixture".to_owned(),
parameters: json!({}),
strict: true,
};
let mut request = CanonicalRequest {
wire_version: M1_WIRE_VERSION.to_owned(),
model: "fixture-transformed".to_owned(),
stream: true,
harness_instance: HarnessInstanceId::parse("cli").expect("fixture ID"),
session_id: SessionId::parse("session").expect("fixture ID"),
turn_id: TurnId::parse("turn").expect("fixture ID"),
input: Vec::new(),
tools: vec![function(None)],
tool_choice: ToolChoice::Named("lookup".to_owned()),
structured_output: None,
reasoning: ReasoningIntent::None,
max_output_tokens: None,
max_spend_micro_usd: None,
capabilities: CapabilityRequirements::default(),
};
assert_eq!(request.validate(), Ok(()));
request.tools = vec![function(Some("one")), function(Some("two"))];
assert_eq!(
request.validate(),
Err(ValidationError::InvalidToolDefinition)
);
request.tools = vec![function(None)];
request.tool_choice = ToolChoice::Named("other".to_owned());
assert_eq!(
request.validate(),
Err(ValidationError::InvalidToolDefinition)
);
}
#[test]
fn spend_authorization_is_bounded_and_zero_means_metered_spend_forbidden() {
let base = CanonicalRequest {
wire_version: M1_WIRE_VERSION.to_owned(),
model: "router-auto".to_owned(),
stream: true,
harness_instance: HarnessInstanceId::parse("desktop").expect("fixture ID"),
session_id: SessionId::parse("session-spend").expect("fixture ID"),
turn_id: TurnId::parse("turn-spend").expect("fixture ID"),
input: Vec::new(),
tools: Vec::new(),
tool_choice: ToolChoice::None,
structured_output: None,
reasoning: ReasoningIntent::None,
max_output_tokens: None,
max_spend_micro_usd: None,
capabilities: CapabilityRequirements::default(),
};
assert_eq!(base.validate(), Ok(()));
let mut zero = base.clone();
zero.max_spend_micro_usd = Some(0);
assert_eq!(zero.validate(), Ok(()));
let mut at_bound = base.clone();
at_bound.max_spend_micro_usd = Some(MAX_SPEND_AUTHORIZATION_MICRO_USD);
assert_eq!(at_bound.validate(), Ok(()));
let mut absurd = base.clone();
absurd.max_spend_micro_usd = Some(MAX_SPEND_AUTHORIZATION_MICRO_USD + 1);
assert_eq!(
absurd.validate(),
Err(ValidationError::InvalidSpendAuthorization)
);
}
#[test]
fn required_capability_is_never_silently_removed() {
let required = CapabilityRequirements {
images: true,
structured_output: true,
public_reasoning: true,
audio: false,
};
let supported = ProviderCapabilities {
images: true,
structured_output: false,
public_reasoning: true,
audio: false,
};
assert_eq!(
required.preflight(supported),
Err(PublicErrorCode::UnsupportedCapability)
);
}
#[test]
fn canonical_fixture_round_trip_preserves_supported_semantics() {
let request = CanonicalRequest {
wire_version: M1_WIRE_VERSION.to_owned(),
model: "fixture-transformed".to_owned(),
stream: true,
harness_instance: HarnessInstanceId::parse("desktop").expect("fixture ID"),
session_id: SessionId::parse("session-semantic").expect("fixture ID"),
turn_id: TurnId::parse("turn-semantic").expect("fixture ID"),
input: vec![
InputItem::Message {
role: MessageRole::Developer,
content: vec![
ContentBlock::Text {
text: "public fixture".to_owned(),
},
ContentBlock::ImageReference {
url: "fixture://image-1".to_owned(),
},
],
},
InputItem::FunctionCall {
call_id: CallId::parse("call-semantic").expect("fixture ID"),
namespace: Some("catalog".to_owned()),
name: "lookup".to_owned(),
arguments: json!({"key": "value"}),
},
InputItem::FunctionCallOutput {
call_id: CallId::parse("call-semantic").expect("fixture ID"),
output: json!({"result": 42}),
},
],
tools: vec![FunctionTool {
namespace: Some("catalog".to_owned()),
name: "lookup".to_owned(),
description: "Synthetic lookup".to_owned(),
parameters: json!({"type": "object", "properties": {"key": {"type": "string"}}}),
strict: true,
}],
tool_choice: ToolChoice::Named("lookup".to_owned()),
structured_output: Some(StructuredOutputIntent {
name: "fixture_result".to_owned(),
schema: json!({"type": "object", "properties": {"result": {"type": "integer"}}}),
strict: true,
}),
reasoning: ReasoningIntent::PublicSummary,
max_output_tokens: Some(128),
max_spend_micro_usd: None,
capabilities: CapabilityRequirements {
images: true,
structured_output: true,
public_reasoning: true,
audio: false,
},
};
let encoded = serde_json::to_vec(&request).expect("serialize canonical fixture");
let decoded: CanonicalRequest =
serde_json::from_slice(&encoded).expect("deserialize canonical fixture");
assert_eq!(decoded, request);
assert_eq!(decoded.tools[0].namespace.as_deref(), Some("catalog"));
let failed = CanonicalEvent::ResponseFailed {
response_id: ResponseId::parse("response-semantic").expect("fixture ID"),
sequence: 17,
error: PublicError::redacted(
PublicErrorCode::ProviderFailure,
RequestId::parse("request-semantic").expect("fixture ID"),
false,
),
};
let failed_round_trip: CanonicalEvent = serde_json::from_value(
serde_json::to_value(&failed).expect("serialize terminal failure"),
)
.expect("deserialize terminal failure");
assert_eq!(failed_round_trip, failed);
}
#[test]
fn canonical_tool_namespaces_reject_duplicates_reserved_names_and_collisions() {
let function = |namespace: Option<&str>, name: &str| FunctionTool {
namespace: namespace.map(str::to_owned),
name: name.to_owned(),
description: "fixture".to_owned(),
parameters: json!({}),
strict: true,
};
assert_eq!(
validate_tools(&[
function(Some("collaboration"), "spawn_agent"),
function(Some("collaboration"), "spawn_agent"),
]),
Err(ValidationError::InvalidToolDefinition)
);
assert_eq!(
validate_tools(&[
function(None, "collaboration"),
function(Some("collaboration"), "spawn_agent"),
]),
Err(ValidationError::InvalidToolDefinition)
);
assert_eq!(
validate_tool_namespace("namespace"),
Err(ValidationError::InvalidToolDefinition)
);
assert_eq!(
validate_tool_name(&"x".repeat(MAX_TOOL_COMPONENT_BYTES + 1)),
Err(ValidationError::InvalidToolDefinition)
);
}
#[test]
fn subagent_disposition_is_deterministic_and_never_silent() {
assert_eq!(
SubagentDisposition::derive(true, false),
SubagentDisposition::Native
);
assert_eq!(
SubagentDisposition::derive(true, true),
SubagentDisposition::Native
);
assert_eq!(
SubagentDisposition::derive(false, true),
SubagentDisposition::Emulated
);
assert_eq!(
SubagentDisposition::derive(false, false),
SubagentDisposition::Refused {
reason: "no_phase_serves_subagents_natively_and_emulation_is_disabled".to_owned()
}
);
}
}