use std::time::Duration;
use schemars::{JsonSchema, Schema};
use serde::{Deserialize, Serialize};
use crate::error::SchemaCheckError;
use crate::ids::{ReadRequestId, ReadToolKey};
use crate::schema::validate_against;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum DataSensitivity {
Public,
Internal,
Confidential,
Restricted,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum TrustLevel {
Untrusted,
Retrieved,
Authoritative,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ReadToolDefinition {
pub key: ReadToolKey,
pub description: String,
pub input_schema: Schema,
pub output_schema: Schema,
pub sensitivity: DataSensitivity,
pub timeout: Duration,
pub max_result_bytes: usize,
}
impl ReadToolDefinition {
pub fn validate_input(&self, arguments: &serde_json::Value) -> Result<(), SchemaCheckError> {
validate_against(&self.input_schema, arguments)
}
pub fn validate_output(&self, output: &serde_json::Value) -> Result<(), SchemaCheckError> {
validate_against(&self.output_schema, output)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct ReadRequest {
pub request_id: ReadRequestId,
pub tool: ReadToolKey,
pub arguments: serde_json::Value,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ReadResult {
pub request_id: ReadRequestId,
pub tool: ReadToolKey,
pub output: serde_json::Value,
pub truncated: bool,
pub source_label: String,
pub trust: TrustLevel,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_request_denies_unknown_fields() {
let ok = serde_json::json!({
"request_id": "r1",
"tool": "case.get",
"arguments": {"case_id": "inv-1"}
});
let parsed = serde_json::from_value::<ReadRequest>(ok).expect("a well-formed request");
assert_eq!(parsed.arguments["case_id"], "inv-1");
let bad = serde_json::json!({
"request_id": "r1",
"tool": "case.get",
"arguments": {},
"write": true
});
assert!(serde_json::from_value::<ReadRequest>(bad).is_err());
}
#[test]
fn trust_ordering() {
assert!(TrustLevel::Untrusted < TrustLevel::Authoritative);
assert!(DataSensitivity::Public < DataSensitivity::Restricted);
}
}