1use crate::codec::app::{
6 from_wire_get_session_catalog_response, from_wire_invoke_frame, from_wire_operation_result,
7 from_wire_provider_metadata, from_wire_resolve_http_subject_response,
8 from_wire_start_provider_response, to_wire_app_invoke_graphql_request,
9 to_wire_app_invoke_request, to_wire_execute_request, to_wire_get_session_catalog_request,
10 to_wire_resolve_http_subject_request, to_wire_start_provider_request,
11};
12use crate::codec::host_service::{HostServiceChannel, connect_host_service, plain_channel};
13use crate::generated::v1;
14use crate::invoke_support::{InvokeError, decode_app_result};
15use crate::rpc_support::GestaltError;
16
17pub type ConnectionMode = i32;
19
20pub mod connection_mode {
24 pub const CONNECTION_MODE_UNSPECIFIED: i32 = 0;
26 pub const CONNECTION_MODE_NONE: i32 = 1;
28 pub const CONNECTION_MODE_SUBJECT: i32 = 2;
30}
31
32#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct AccessContext {
38 pub policy: String,
40 pub role: String,
42}
43
44#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct AgentInvocationContext {
48 pub provider_name: String,
50 pub session_id: String,
52 pub turn_id: String,
54}
55
56#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct AgentToolRef {
60 pub app: String,
62 pub operation: String,
64 pub connection: String,
66 pub instance: String,
68 pub title: String,
70 pub description: String,
72 pub credential_mode: String,
74 pub system: String,
76 pub run_as: Option<SubjectContext>,
78}
79
80#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub struct AppInvokeGraphQLRequest {
87 pub app: String,
89 pub document: String,
91 pub variables: Option<serde_json::Map<String, serde_json::Value>>,
93 pub connection: String,
95 pub instance: String,
97 pub idempotency_key: String,
99 pub context: Option<RequestContext>,
101 pub headers: std::collections::BTreeMap<String, String>,
105}
106
107#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct AppInvokeRequest {
113 pub app: String,
115 pub operation: String,
117 pub params: Option<serde_json::Map<String, serde_json::Value>>,
119 pub connection: String,
121 pub instance: String,
123 pub idempotency_key: String,
125 pub credential_mode: String,
127 pub context: Option<RequestContext>,
129 pub run_as: Option<SubjectContext>,
131 pub headers: std::collections::BTreeMap<String, String>,
135}
136
137#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct Catalog {
144 pub name: String,
146 pub display_name: String,
148 pub description: String,
150 pub icon_svg: String,
152 pub operations: Vec<CatalogOperation>,
154}
155
156#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
161#[serde(rename_all = "camelCase")]
162pub struct CatalogOperation {
163 pub id: String,
165 pub method: String,
167 pub title: String,
169 pub description: String,
171 pub input_schema: String,
173 pub annotations: Option<OperationAnnotations>,
175 pub parameters: Vec<CatalogParameter>,
177 pub required_scopes: Vec<String>,
179 pub tags: Vec<String>,
181 pub read_only: bool,
183 pub visible: Option<bool>,
185 pub transport: String,
187 pub allowed_roles: Vec<String>,
189 pub response: Option<OperationResponseSpec>,
194}
195
196#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct CatalogParameter {
203 pub name: String,
205 pub r#type: String,
207 pub description: String,
209 pub required: bool,
211 pub default: Option<serde_json::Value>,
213}
214
215#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct ConnectionParamDef {
221 pub required: bool,
223 pub description: String,
225 pub default_value: String,
227 pub from: String,
229 pub field: String,
231}
232
233#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
237#[serde(rename_all = "camelCase")]
238pub struct CredentialContext {
239 pub mode: String,
241 pub subject_id: String,
243 pub connection: String,
245 pub instance: String,
247}
248
249#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
253#[serde(rename_all = "camelCase")]
254pub struct ExecuteRequest {
255 pub operation: String,
257 pub params: Option<serde_json::Map<String, serde_json::Value>>,
259 pub token: String,
261 pub connection_params: std::collections::BTreeMap<String, String>,
263 pub invocation_id: String,
265 pub context: Option<RequestContext>,
267 pub idempotency_key: String,
269}
270
271#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
276#[serde(rename_all = "camelCase")]
277pub struct GetSessionCatalogRequest {
278 pub token: String,
280 pub connection_params: std::collections::BTreeMap<String, String>,
282 pub invocation_id: String,
284 pub context: Option<RequestContext>,
286}
287
288#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
292#[serde(rename_all = "camelCase")]
293pub struct GetSessionCatalogResponse {
294 pub catalog: Option<Catalog>,
296}
297
298#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
303#[serde(rename_all = "camelCase")]
304pub struct HTTPSubjectRequest {
305 pub binding: String,
307 pub method: String,
309 pub path: String,
311 pub content_type: String,
313 pub headers: std::collections::BTreeMap<String, StringList>,
315 pub query: std::collections::BTreeMap<String, StringList>,
317 pub params: Option<serde_json::Map<String, serde_json::Value>>,
319 pub raw_body: Vec<u8>,
321 pub security_scheme: String,
323 pub verified_subject: String,
325 pub verified_claims: std::collections::BTreeMap<String, String>,
327}
328
329#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
333#[serde(rename_all = "camelCase")]
334pub struct HostContext {
335 pub public_base_url: String,
337}
338
339#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
341#[serde(rename_all = "camelCase")]
342pub struct InvocationContext {
343 pub request_id: String,
345 pub depth: i32,
347 pub call_chain: Vec<String>,
349 pub surface: String,
351 pub internal_connection_access: bool,
353 pub connection: String,
355}
356
357#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
359#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
360pub enum InvokeFrameValue {
361 Metadata(InvokeMetadata),
363 Data(Vec<u8>),
365}
366
367#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
376#[serde(rename_all = "camelCase")]
377pub struct InvokeFrame {
378 pub value: Option<InvokeFrameValue>,
380}
381
382#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct InvokeMetadata {
390 pub status: i32,
392 pub headers: std::collections::BTreeMap<String, StringList>,
394 pub media_type: String,
396}
397
398#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
403#[serde(rename_all = "camelCase")]
404pub struct OperationAnnotations {
405 pub read_only_hint: Option<bool>,
407 pub idempotent_hint: Option<bool>,
409 pub destructive_hint: Option<bool>,
411 pub open_world_hint: Option<bool>,
413}
414
415#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
417#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
418pub enum OperationResponseSpecKind {
419 Unary(UnaryResponseSpec),
421 Stream(StreamResponseSpec),
423}
424
425#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
430#[serde(rename_all = "camelCase")]
431pub struct OperationResponseSpec {
432 pub kind: Option<OperationResponseSpecKind>,
434}
435
436#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
440#[serde(rename_all = "camelCase")]
441pub struct OperationResult {
442 pub status: i32,
444 pub body: Vec<u8>,
446 pub headers: std::collections::BTreeMap<String, StringList>,
448}
449
450#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
455#[serde(rename_all = "camelCase")]
456pub struct ProviderContext {
457 pub kind: String,
459 pub name: String,
461}
462
463#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
467#[serde(rename_all = "camelCase")]
468pub struct ProviderMetadata {
469 pub name: String,
471 pub display_name: String,
473 pub description: String,
475 pub connection_mode: ConnectionMode,
477 pub auth_types: Vec<String>,
479 pub connection_params: std::collections::BTreeMap<String, ConnectionParamDef>,
481 pub static_catalog: Option<Catalog>,
483 pub supports_session_catalog: bool,
485 pub min_protocol_version: i32,
487 pub max_protocol_version: i32,
489 pub workflow_definition_specs: Vec<Vec<u8>>,
498}
499
500#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
505#[serde(rename_all = "camelCase")]
506pub struct RequestContext {
507 pub subject: Option<SubjectContext>,
509 pub credential: Option<CredentialContext>,
511 pub access: Option<AccessContext>,
513 pub workflow: Option<serde_json::Map<String, serde_json::Value>>,
515 pub host: Option<HostContext>,
517 pub agent_subject: Option<SubjectContext>,
521 pub caller: Option<ProviderContext>,
523 pub invocation: Option<InvocationContext>,
525 pub tool_refs: Vec<AgentToolRef>,
530 pub tool_refs_set: bool,
535 pub request_meta: Option<RequestMetaContext>,
537 pub agent: Option<AgentInvocationContext>,
539}
540
541#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
543#[serde(rename_all = "camelCase")]
544pub struct RequestMetaContext {
545 pub client_ip: String,
547 pub remote_addr: String,
549 pub user_agent: String,
551}
552
553#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
559#[serde(rename_all = "camelCase")]
560pub struct ResolveHTTPSubjectRequest {
561 pub request: Option<HTTPSubjectRequest>,
563 pub context: Option<RequestContext>,
565}
566
567#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
574#[serde(rename_all = "camelCase")]
575pub struct ResolveHTTPSubjectResponse {
576 pub subject: Option<SubjectContext>,
578 pub reject_status: i32,
580 pub reject_message: String,
582}
583
584#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
589#[serde(rename_all = "camelCase")]
590pub struct StartProviderRequest {
591 pub name: String,
593 pub config: Option<serde_json::Map<String, serde_json::Value>>,
595 pub protocol_version: i32,
597}
598
599#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
603#[serde(rename_all = "camelCase")]
604pub struct StartProviderResponse {
605 pub protocol_version: i32,
607}
608
609#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
615#[serde(rename_all = "camelCase")]
616pub struct StreamResponseSpec {
617 pub media_type: String,
619 pub item_schema: Option<serde_json::Map<String, serde_json::Value>>,
621}
622
623#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
627#[serde(rename_all = "camelCase")]
628pub struct StringList {
629 pub values: Vec<String>,
631}
632
633#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
637#[serde(rename_all = "camelCase")]
638pub struct SubjectContext {
639 pub id: String,
641 pub email: String,
643 pub display_name: String,
645 pub scopes: Vec<String>,
647 pub permissions: Vec<SubjectPermissionContext>,
649}
650
651#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
653#[serde(rename_all = "camelCase")]
654pub struct SubjectPermissionContext {
655 pub app: String,
657 pub operations: Vec<String>,
659 pub all_operations: bool,
661}
662
663#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
667#[serde(rename_all = "camelCase")]
668pub struct UnaryResponseSpec {
669 pub schema: Option<serde_json::Map<String, serde_json::Value>>,
671}
672
673pub struct App {
675 inner: v1::app_client::AppClient<HostServiceChannel>,
676 timeout: Option<std::time::Duration>,
677 context: Option<RequestContext>,
678}
679
680impl App {
681 pub fn new(channel: tonic::transport::Channel) -> Self {
683 Self {
684 inner: v1::app_client::AppClient::new(plain_channel(channel)),
685 timeout: None,
686 context: None,
687 }
688 }
689
690 pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
693 self.timeout = Some(timeout);
694 self
695 }
696
697 pub fn with_context(mut self, context: RequestContext) -> Self {
700 self.context = Some(context);
701 self
702 }
703
704 pub async fn connect() -> Result<Self, GestaltError> {
706 Self::connect_named("").await
707 }
708
709 pub async fn connect_named(name: &str) -> Result<Self, GestaltError> {
711 Ok(Self {
712 inner: v1::app_client::AppClient::new(connect_host_service("app", name).await?),
713 timeout: None,
714 context: None,
715 })
716 }
717
718 pub async fn invoke(
722 &mut self,
723 app: String,
724 operation: String,
725 params: Option<serde_json::Map<String, serde_json::Value>>,
726 options: AppInvokeOptions,
727 ) -> Result<serde_json::Value, InvokeError> {
728 let request = AppInvokeRequest {
729 app,
730 operation,
731 params,
732 connection: options.connection,
733 instance: options.instance,
734 idempotency_key: options.idempotency_key,
735 credential_mode: options.credential_mode,
736 run_as: options.run_as,
737 headers: options.headers,
738 context: self.context.clone(),
739 };
740 let invoke_context_app = request.app.clone();
741 let invoke_context_operation = request.operation.clone();
742 let mut tonic_request = tonic::Request::new(to_wire_app_invoke_request(request));
743 if let Some(timeout) = self.timeout {
744 tonic_request.set_timeout(timeout);
745 }
746 let response = from_wire_operation_result(
747 self.inner
748 .invoke(tonic_request)
749 .await
750 .map_err(GestaltError::from)?
751 .into_inner(),
752 );
753 Ok(decode_app_result(
754 &invoke_context_app,
755 &invoke_context_operation,
756 response.status,
757 &response.body,
758 )?)
759 }
760
761 pub async fn invoke_raw(
763 &mut self,
764 request: AppInvokeRequest,
765 ) -> Result<OperationResult, GestaltError> {
766 let mut request = request;
767 if request.context.is_none() {
768 request.context = self.context.clone();
769 }
770 let mut tonic_request = tonic::Request::new(to_wire_app_invoke_request(request));
771 if let Some(timeout) = self.timeout {
772 tonic_request.set_timeout(timeout);
773 }
774 let response = self.inner.invoke(tonic_request).await?;
775 Ok(from_wire_operation_result(response.into_inner()))
776 }
777
778 pub async fn invoke_stream(
787 &mut self,
788 request: AppInvokeRequest,
789 ) -> Result<AppInvokeStreamStream, GestaltError> {
790 let mut request = request;
791 if request.context.is_none() {
792 request.context = self.context.clone();
793 }
794 let response = self
795 .inner
796 .invoke_stream(to_wire_app_invoke_request(request))
797 .await?;
798 Ok(AppInvokeStreamStream {
799 inner: response.into_inner(),
800 })
801 }
802
803 pub async fn invoke_graphql(
805 &mut self,
806 app: String,
807 document: String,
808 options: AppInvokeGraphQLOptions,
809 ) -> Result<OperationResult, GestaltError> {
810 let request = AppInvokeGraphQLRequest {
811 app,
812 document,
813 connection: options.connection,
814 instance: options.instance,
815 idempotency_key: options.idempotency_key,
816 variables: options.variables,
817 headers: options.headers,
818 context: self.context.clone(),
819 };
820 let mut tonic_request = tonic::Request::new(to_wire_app_invoke_graphql_request(request));
821 if let Some(timeout) = self.timeout {
822 tonic_request.set_timeout(timeout);
823 }
824 let response = self.inner.invoke_graph_ql(tonic_request).await?;
825 Ok(from_wire_operation_result(response.into_inner()))
826 }
827
828 pub async fn invoke_graphql_raw(
830 &mut self,
831 request: AppInvokeGraphQLRequest,
832 ) -> Result<OperationResult, GestaltError> {
833 let mut request = request;
834 if request.context.is_none() {
835 request.context = self.context.clone();
836 }
837 let mut tonic_request = tonic::Request::new(to_wire_app_invoke_graphql_request(request));
838 if let Some(timeout) = self.timeout {
839 tonic_request.set_timeout(timeout);
840 }
841 let response = self.inner.invoke_graph_ql(tonic_request).await?;
842 Ok(from_wire_operation_result(response.into_inner()))
843 }
844}
845
846#[derive(Clone, Debug, Default)]
849pub struct AppInvokeOptions {
850 pub connection: String,
852 pub instance: String,
854 pub idempotency_key: String,
856 pub credential_mode: String,
858 pub run_as: Option<SubjectContext>,
860 pub headers: std::collections::BTreeMap<String, String>,
864}
865
866#[derive(Clone, Debug, Default)]
869pub struct AppInvokeStreamOptions {
870 pub connection: String,
872 pub instance: String,
874 pub idempotency_key: String,
876 pub credential_mode: String,
878 pub run_as: Option<SubjectContext>,
880 pub headers: std::collections::BTreeMap<String, String>,
884}
885
886#[derive(Clone, Debug, Default)]
889pub struct AppInvokeGraphQLOptions {
890 pub connection: String,
892 pub instance: String,
894 pub idempotency_key: String,
896 pub variables: Option<serde_json::Map<String, serde_json::Value>>,
898 pub headers: std::collections::BTreeMap<String, String>,
902}
903
904pub struct AppInvokeStreamStream {
913 inner: tonic::Streaming<v1::InvokeFrame>,
914}
915
916impl AppInvokeStreamStream {
917 pub async fn recv(&mut self) -> Result<Option<InvokeFrame>, GestaltError> {
919 Ok(self.inner.message().await?.map(from_wire_invoke_frame))
920 }
921}
922
923pub struct AppProvider {
927 inner: v1::app_provider_client::AppProviderClient<tonic::transport::Channel>,
928 timeout: Option<std::time::Duration>,
929 context: Option<RequestContext>,
930}
931
932impl AppProvider {
933 pub fn new(channel: tonic::transport::Channel) -> Self {
935 Self {
936 inner: v1::app_provider_client::AppProviderClient::new(channel),
937 timeout: None,
938 context: None,
939 }
940 }
941
942 pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
945 self.timeout = Some(timeout);
946 self
947 }
948
949 pub fn with_context(mut self, context: RequestContext) -> Self {
952 self.context = Some(context);
953 self
954 }
955
956 pub async fn get_metadata(&mut self) -> Result<ProviderMetadata, GestaltError> {
958 let mut tonic_request = tonic::Request::new(());
959 if let Some(timeout) = self.timeout {
960 tonic_request.set_timeout(timeout);
961 }
962 let response = self.inner.get_metadata(tonic_request).await?;
963 Ok(from_wire_provider_metadata(response.into_inner()))
964 }
965
966 pub async fn start_provider(
968 &mut self,
969 name: String,
970 protocol_version: i32,
971 config: Option<serde_json::Map<String, serde_json::Value>>,
972 ) -> Result<StartProviderResponse, GestaltError> {
973 let request = StartProviderRequest {
974 name,
975 protocol_version,
976 config,
977 };
978 let mut tonic_request = tonic::Request::new(to_wire_start_provider_request(request));
979 if let Some(timeout) = self.timeout {
980 tonic_request.set_timeout(timeout);
981 }
982 let response = self.inner.start_provider(tonic_request).await?;
983 Ok(from_wire_start_provider_response(response.into_inner()))
984 }
985
986 pub async fn start_provider_raw(
988 &mut self,
989 request: StartProviderRequest,
990 ) -> Result<StartProviderResponse, GestaltError> {
991 let mut tonic_request = tonic::Request::new(to_wire_start_provider_request(request));
992 if let Some(timeout) = self.timeout {
993 tonic_request.set_timeout(timeout);
994 }
995 let response = self.inner.start_provider(tonic_request).await?;
996 Ok(from_wire_start_provider_response(response.into_inner()))
997 }
998
999 pub async fn execute(
1001 &mut self,
1002 operation: String,
1003 token: String,
1004 invocation_id: String,
1005 idempotency_key: String,
1006 params: Option<serde_json::Map<String, serde_json::Value>>,
1007 ) -> Result<OperationResult, GestaltError> {
1008 let request = ExecuteRequest {
1009 operation,
1010 token,
1011 invocation_id,
1012 idempotency_key,
1013 params,
1014 context: self.context.clone(),
1015 ..Default::default()
1016 };
1017 let mut tonic_request = tonic::Request::new(to_wire_execute_request(request));
1018 if let Some(timeout) = self.timeout {
1019 tonic_request.set_timeout(timeout);
1020 }
1021 let response = self.inner.execute(tonic_request).await?;
1022 Ok(from_wire_operation_result(response.into_inner()))
1023 }
1024
1025 pub async fn execute_raw(
1027 &mut self,
1028 request: ExecuteRequest,
1029 ) -> Result<OperationResult, GestaltError> {
1030 let mut request = request;
1031 if request.context.is_none() {
1032 request.context = self.context.clone();
1033 }
1034 let mut tonic_request = tonic::Request::new(to_wire_execute_request(request));
1035 if let Some(timeout) = self.timeout {
1036 tonic_request.set_timeout(timeout);
1037 }
1038 let response = self.inner.execute(tonic_request).await?;
1039 Ok(from_wire_operation_result(response.into_inner()))
1040 }
1041
1042 pub async fn execute_stream(
1049 &mut self,
1050 request: ExecuteRequest,
1051 ) -> Result<AppProviderExecuteStreamStream, GestaltError> {
1052 let mut request = request;
1053 if request.context.is_none() {
1054 request.context = self.context.clone();
1055 }
1056 let response = self
1057 .inner
1058 .execute_stream(to_wire_execute_request(request))
1059 .await?;
1060 Ok(AppProviderExecuteStreamStream {
1061 inner: response.into_inner(),
1062 })
1063 }
1064
1065 pub async fn resolve_http_subject(
1067 &mut self,
1068 request: ResolveHTTPSubjectRequest,
1069 ) -> Result<ResolveHTTPSubjectResponse, GestaltError> {
1070 let mut request = request;
1071 if request.context.is_none() {
1072 request.context = self.context.clone();
1073 }
1074 let mut tonic_request = tonic::Request::new(to_wire_resolve_http_subject_request(request));
1075 if let Some(timeout) = self.timeout {
1076 tonic_request.set_timeout(timeout);
1077 }
1078 let response = self.inner.resolve_http_subject(tonic_request).await?;
1079 Ok(from_wire_resolve_http_subject_response(
1080 response.into_inner(),
1081 ))
1082 }
1083
1084 pub async fn get_session_catalog(
1086 &mut self,
1087 token: String,
1088 invocation_id: String,
1089 ) -> Result<GetSessionCatalogResponse, GestaltError> {
1090 let request = GetSessionCatalogRequest {
1091 token,
1092 invocation_id,
1093 context: self.context.clone(),
1094 ..Default::default()
1095 };
1096 let mut tonic_request = tonic::Request::new(to_wire_get_session_catalog_request(request));
1097 if let Some(timeout) = self.timeout {
1098 tonic_request.set_timeout(timeout);
1099 }
1100 let response = self.inner.get_session_catalog(tonic_request).await?;
1101 Ok(from_wire_get_session_catalog_response(
1102 response.into_inner(),
1103 ))
1104 }
1105
1106 pub async fn get_session_catalog_raw(
1108 &mut self,
1109 request: GetSessionCatalogRequest,
1110 ) -> Result<GetSessionCatalogResponse, GestaltError> {
1111 let mut request = request;
1112 if request.context.is_none() {
1113 request.context = self.context.clone();
1114 }
1115 let mut tonic_request = tonic::Request::new(to_wire_get_session_catalog_request(request));
1116 if let Some(timeout) = self.timeout {
1117 tonic_request.set_timeout(timeout);
1118 }
1119 let response = self.inner.get_session_catalog(tonic_request).await?;
1120 Ok(from_wire_get_session_catalog_response(
1121 response.into_inner(),
1122 ))
1123 }
1124}
1125
1126pub struct AppProviderExecuteStreamStream {
1133 inner: tonic::Streaming<v1::InvokeFrame>,
1134}
1135
1136impl AppProviderExecuteStreamStream {
1137 pub async fn recv(&mut self) -> Result<Option<InvokeFrame>, GestaltError> {
1139 Ok(self.inner.message().await?.map(from_wire_invoke_frame))
1140 }
1141}