vv_agent/app_server/protocol/
schema.rs1use 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}