1use std::time::Duration;
8
9use schemars::{JsonSchema, Schema};
10use serde::{Deserialize, Serialize};
11
12use crate::error::SchemaCheckError;
13use crate::ids::{ReadRequestId, ReadToolKey};
14use crate::schema::validate_against;
15
16#[derive(
18 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
19)]
20#[serde(rename_all = "snake_case")]
21pub enum DataSensitivity {
22 Public,
24 Internal,
26 Confidential,
28 Restricted,
30}
31
32#[derive(
34 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
35)]
36#[serde(rename_all = "snake_case")]
37pub enum TrustLevel {
38 Untrusted,
40 Retrieved,
42 Authoritative,
44}
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub struct ReadToolDefinition {
49 pub key: ReadToolKey,
51 pub description: String,
53 pub input_schema: Schema,
55 pub output_schema: Schema,
57 pub sensitivity: DataSensitivity,
59 pub timeout: Duration,
61 pub max_result_bytes: usize,
63}
64
65impl ReadToolDefinition {
66 pub fn validate_input(&self, arguments: &serde_json::Value) -> Result<(), SchemaCheckError> {
68 validate_against(&self.input_schema, arguments)
69 }
70
71 pub fn validate_output(&self, output: &serde_json::Value) -> Result<(), SchemaCheckError> {
73 validate_against(&self.output_schema, output)
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
80#[serde(deny_unknown_fields)]
81pub struct ReadRequest {
82 pub request_id: ReadRequestId,
84 pub tool: ReadToolKey,
86 pub arguments: serde_json::Value,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
92pub struct ReadResult {
93 pub request_id: ReadRequestId,
95 pub tool: ReadToolKey,
97 pub output: serde_json::Value,
99 pub truncated: bool,
101 pub source_label: String,
103 pub trust: TrustLevel,
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn read_request_denies_unknown_fields() {
113 let ok = serde_json::json!({
114 "request_id": "r1",
115 "tool": "case.get",
116 "arguments": {"case_id": "inv-1"}
117 });
118 let parsed = serde_json::from_value::<ReadRequest>(ok).expect("a well-formed request");
119 assert_eq!(parsed.arguments["case_id"], "inv-1");
120 let bad = serde_json::json!({
121 "request_id": "r1",
122 "tool": "case.get",
123 "arguments": {},
124 "write": true
125 });
126 assert!(serde_json::from_value::<ReadRequest>(bad).is_err());
127 }
128
129 #[test]
130 fn trust_ordering() {
131 assert!(TrustLevel::Untrusted < TrustLevel::Authoritative);
132 assert!(DataSensitivity::Public < DataSensitivity::Restricted);
133 }
134}