Skip to main content

vv_agent/app_server/protocol/
schema.rs

1use std::collections::BTreeMap;
2use std::fmt;
3
4use schemars::{schema_for, JsonSchema};
5use serde::{Deserialize, Serialize};
6use ts_rs::TS;
7
8use super::{
9    AppItem, AppThread, AppTurn, ApprovalRequestParams, ApprovalResolveParams, ClientRequest,
10    InitializeParams, InitializeResponse, JsonRpcMessage, ServerNotification, ServerRequest,
11    ThreadReadResponse, ThreadResumeResponse, ThreadStartResponse, TurnStartResponse,
12};
13
14pub type SchemaBundle = BTreeMap<String, String>;
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
17#[serde(rename_all = "camelCase")]
18pub struct SchemaExportResponse {
19    pub json_schema: SchemaBundle,
20    pub typescript: SchemaBundle,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct AppServerSchemaError {
25    message: String,
26}
27
28impl AppServerSchemaError {
29    fn json(error: serde_json::Error) -> Self {
30        Self {
31            message: error.to_string(),
32        }
33    }
34}
35
36impl fmt::Display for AppServerSchemaError {
37    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
38        formatter.write_str(&self.message)
39    }
40}
41
42impl std::error::Error for AppServerSchemaError {}
43
44pub fn generate_app_server_json_schema_bundle() -> Result<SchemaBundle, AppServerSchemaError> {
45    let mut bundle = SchemaBundle::new();
46    insert_json_schema::<ClientRequest>(&mut bundle, "ClientRequest")?;
47    insert_json_schema::<ServerNotification>(&mut bundle, "ServerNotification")?;
48    insert_json_schema::<ServerRequest>(&mut bundle, "ServerRequest")?;
49    insert_json_schema::<SchemaExportResponse>(&mut bundle, "SchemaExportResponse")?;
50    insert_json_schema::<JsonRpcMessage>(&mut bundle, "JsonRpcMessage")?;
51    insert_json_schema::<InitializeParams>(&mut bundle, "InitializeParams")?;
52    insert_json_schema::<InitializeResponse>(&mut bundle, "InitializeResponse")?;
53    insert_json_schema::<ThreadStartResponse>(&mut bundle, "ThreadStartResponse")?;
54    insert_json_schema::<ThreadReadResponse>(&mut bundle, "ThreadReadResponse")?;
55    insert_json_schema::<ThreadResumeResponse>(&mut bundle, "ThreadResumeResponse")?;
56    insert_json_schema::<TurnStartResponse>(&mut bundle, "TurnStartResponse")?;
57    insert_json_schema::<AppThread>(&mut bundle, "AppThread")?;
58    insert_json_schema::<AppTurn>(&mut bundle, "AppTurn")?;
59    insert_json_schema::<AppItem>(&mut bundle, "AppItem")?;
60    insert_json_schema::<ApprovalRequestParams>(&mut bundle, "ApprovalRequestParams")?;
61    insert_json_schema::<ApprovalResolveParams>(&mut bundle, "ApprovalResolveParams")?;
62    Ok(bundle)
63}
64
65pub fn generate_app_server_typescript_bundle() -> Result<SchemaBundle, AppServerSchemaError> {
66    let mut bundle = SchemaBundle::new();
67    insert_typescript::<ClientRequest>(&mut bundle, "ClientRequest.ts");
68    insert_typescript::<ServerNotification>(&mut bundle, "ServerNotification.ts");
69    insert_typescript::<ServerRequest>(&mut bundle, "ServerRequest.ts");
70    insert_typescript::<SchemaExportResponse>(&mut bundle, "SchemaExportResponse.ts");
71    insert_typescript::<InitializeParams>(&mut bundle, "InitializeParams.ts");
72    insert_typescript::<InitializeResponse>(&mut bundle, "InitializeResponse.ts");
73    insert_typescript::<ThreadStartResponse>(&mut bundle, "ThreadStartResponse.ts");
74    insert_typescript::<ThreadReadResponse>(&mut bundle, "ThreadReadResponse.ts");
75    insert_typescript::<ThreadResumeResponse>(&mut bundle, "ThreadResumeResponse.ts");
76    insert_typescript::<TurnStartResponse>(&mut bundle, "TurnStartResponse.ts");
77    insert_typescript::<AppThread>(&mut bundle, "AppThread.ts");
78    insert_typescript::<AppTurn>(&mut bundle, "AppTurn.ts");
79    insert_typescript::<AppItem>(&mut bundle, "AppItem.ts");
80    insert_typescript::<ApprovalRequestParams>(&mut bundle, "ApprovalRequestParams.ts");
81    insert_typescript::<ApprovalResolveParams>(&mut bundle, "ApprovalResolveParams.ts");
82    Ok(bundle)
83}
84
85fn insert_json_schema<T: JsonSchema>(
86    bundle: &mut SchemaBundle,
87    name: &'static str,
88) -> Result<(), AppServerSchemaError> {
89    let schema = schema_for!(T);
90    let value = serde_json::to_string_pretty(&schema).map_err(AppServerSchemaError::json)?;
91    bundle.insert(name.to_string(), value);
92    Ok(())
93}
94
95fn insert_typescript<T: TS>(bundle: &mut SchemaBundle, file_name: &'static str) {
96    bundle.insert(file_name.to_string(), format!("export {};\n", T::decl()));
97}