Skip to main content

gestalt/
app.rs

1// Code generated by sdkgen. DO NOT EDIT.
2
3//! Generated native types and clients for app.proto.
4
5use 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
17/// Open enum for `gestalt.provider.v1.ConnectionMode`; unknown numeric values are preserved.
18pub type ConnectionMode = i32;
19
20/// ConnectionMode describes which credential sources a provider accepts.
21///
22/// Named values of `ConnectionMode`.
23pub mod connection_mode {
24    /// CONNECTION_MODE_UNSPECIFIED.
25    pub const CONNECTION_MODE_UNSPECIFIED: i32 = 0;
26    /// CONNECTION_MODE_NONE.
27    pub const CONNECTION_MODE_NONE: i32 = 1;
28    /// CONNECTION_MODE_SUBJECT.
29    pub const CONNECTION_MODE_SUBJECT: i32 = 2;
30}
31
32/// AccessContext describes the host-side access decision for an operation.
33///
34/// Native message type for `gestalt.provider.v1.AccessContext`.
35#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct AccessContext {
38    /// The `policy` field.
39    pub policy: String,
40    /// The `role` field.
41    pub role: String,
42}
43
44/// Native message type for `gestalt.provider.v1.AgentInvocationContext`.
45#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub struct AgentInvocationContext {
48    /// The `provider_name` field.
49    pub provider_name: String,
50    /// The `session_id` field.
51    pub session_id: String,
52    /// The `turn_id` field.
53    pub turn_id: String,
54}
55
56/// Native message type for `gestalt.provider.v1.AgentToolRef`.
57#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
58#[serde(rename_all = "camelCase")]
59pub struct AgentToolRef {
60    /// The `app` field.
61    pub app: String,
62    /// The `operation` field.
63    pub operation: String,
64    /// The `connection` field.
65    pub connection: String,
66    /// The `instance` field.
67    pub instance: String,
68    /// The `title` field.
69    pub title: String,
70    /// The `description` field.
71    pub description: String,
72    /// The `credential_mode` field.
73    pub credential_mode: String,
74    /// The `system` field.
75    pub system: String,
76    /// The `run_as` field; None when unset.
77    pub run_as: Option<SubjectContext>,
78}
79
80/// AppInvokeGraphQLRequest invokes the raw GraphQL surface on another plugin
81/// through Gestalt.
82///
83/// Native message type for `gestalt.provider.v1.AppInvokeGraphQLRequest`.
84#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub struct AppInvokeGraphQLRequest {
87    /// The `app` field.
88    pub app: String,
89    /// The `document` field.
90    pub document: String,
91    /// The `variables` field; None when unset.
92    pub variables: Option<serde_json::Map<String, serde_json::Value>>,
93    /// The `connection` field.
94    pub connection: String,
95    /// The `instance` field.
96    pub instance: String,
97    /// The `idempotency_key` field.
98    pub idempotency_key: String,
99    /// The `context` field; None when unset.
100    pub context: Option<RequestContext>,
101    /// headers overrides outbound static headers declared by the target provider.
102    ///
103    /// The `headers` field.
104    pub headers: std::collections::BTreeMap<String, String>,
105}
106
107/// AppInvokeRequest invokes a declared operation on another app through Gestalt.
108///
109/// Native message type for `gestalt.provider.v1.AppInvokeRequest`.
110#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct AppInvokeRequest {
113    /// The `app` field.
114    pub app: String,
115    /// The `operation` field.
116    pub operation: String,
117    /// The `params` field; None when unset.
118    pub params: Option<serde_json::Map<String, serde_json::Value>>,
119    /// The `connection` field.
120    pub connection: String,
121    /// The `instance` field.
122    pub instance: String,
123    /// The `idempotency_key` field.
124    pub idempotency_key: String,
125    /// The `credential_mode` field.
126    pub credential_mode: String,
127    /// The `context` field; None when unset.
128    pub context: Option<RequestContext>,
129    /// The `run_as` field; None when unset.
130    pub run_as: Option<SubjectContext>,
131    /// headers overrides outbound static headers declared by the target provider.
132    ///
133    /// The `headers` field.
134    pub headers: std::collections::BTreeMap<String, String>,
135}
136
137/// Catalog is the static or request-scoped executable surface exposed by a
138/// provider.
139///
140/// Native message type for `gestalt.provider.v1.Catalog`.
141#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
142#[serde(rename_all = "camelCase")]
143pub struct Catalog {
144    /// The `name` field.
145    pub name: String,
146    /// The `display_name` field.
147    pub display_name: String,
148    /// The `description` field.
149    pub description: String,
150    /// The `icon_svg` field.
151    pub icon_svg: String,
152    /// The `operations` field.
153    pub operations: Vec<CatalogOperation>,
154}
155
156/// CatalogOperation is one executable operation exposed by an integration
157/// provider.
158///
159/// Native message type for `gestalt.provider.v1.CatalogOperation`.
160#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
161#[serde(rename_all = "camelCase")]
162pub struct CatalogOperation {
163    /// The `id` field.
164    pub id: String,
165    /// The `method` field.
166    pub method: String,
167    /// The `title` field.
168    pub title: String,
169    /// The `description` field.
170    pub description: String,
171    /// The `input_schema` field.
172    pub input_schema: String,
173    /// The `annotations` field; None when unset.
174    pub annotations: Option<OperationAnnotations>,
175    /// The `parameters` field.
176    pub parameters: Vec<CatalogParameter>,
177    /// The `required_scopes` field.
178    pub required_scopes: Vec<String>,
179    /// The `tags` field.
180    pub tags: Vec<String>,
181    /// The `read_only` field.
182    pub read_only: bool,
183    /// The `visible` field; None when unset.
184    pub visible: Option<bool>,
185    /// The `transport` field.
186    pub transport: String,
187    /// The `allowed_roles` field.
188    pub allowed_roles: Vec<String>,
189    /// Response mode and schema for this operation. Replaces the former
190    /// output_schema string; absent is equivalent to unary with no schema.
191    ///
192    /// The `response` field; None when unset.
193    pub response: Option<OperationResponseSpec>,
194}
195
196/// CatalogParameter describes one input parameter surfaced in the generated
197/// catalog for an operation.
198///
199/// Native message type for `gestalt.provider.v1.CatalogParameter`.
200#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct CatalogParameter {
203    /// The `name` field.
204    pub name: String,
205    /// The `type` field.
206    pub r#type: String,
207    /// The `description` field.
208    pub description: String,
209    /// The `required` field.
210    pub required: bool,
211    /// The `default` field; None when unset.
212    pub default: Option<serde_json::Value>,
213}
214
215/// ConnectionParamDef describes one provider-defined connection parameter.
216///
217/// Native message type for `gestalt.provider.v1.ConnectionParamDef`.
218#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct ConnectionParamDef {
221    /// The `required` field.
222    pub required: bool,
223    /// The `description` field.
224    pub description: String,
225    /// The `default_value` field.
226    pub default_value: String,
227    /// The `from` field.
228    pub from: String,
229    /// The `field` field.
230    pub field: String,
231}
232
233/// CredentialContext describes the resolved credential used for an operation.
234///
235/// Native message type for `gestalt.provider.v1.CredentialContext`.
236#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
237#[serde(rename_all = "camelCase")]
238pub struct CredentialContext {
239    /// The `mode` field.
240    pub mode: String,
241    /// The `subject_id` field.
242    pub subject_id: String,
243    /// The `connection` field.
244    pub connection: String,
245    /// The `instance` field.
246    pub instance: String,
247}
248
249/// ExecuteRequest invokes one executable operation.
250///
251/// Native message type for `gestalt.provider.v1.ExecuteRequest`.
252#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
253#[serde(rename_all = "camelCase")]
254pub struct ExecuteRequest {
255    /// The `operation` field.
256    pub operation: String,
257    /// The `params` field; None when unset.
258    pub params: Option<serde_json::Map<String, serde_json::Value>>,
259    /// The `token` field.
260    pub token: String,
261    /// The `connection_params` field.
262    pub connection_params: std::collections::BTreeMap<String, String>,
263    /// The `invocation_id` field.
264    pub invocation_id: String,
265    /// The `context` field; None when unset.
266    pub context: Option<RequestContext>,
267    /// The `idempotency_key` field.
268    pub idempotency_key: String,
269}
270
271/// GetSessionCatalogRequest asks a provider for request-scoped catalog
272/// extensions.
273///
274/// Native message type for `gestalt.provider.v1.GetSessionCatalogRequest`.
275#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
276#[serde(rename_all = "camelCase")]
277pub struct GetSessionCatalogRequest {
278    /// The `token` field.
279    pub token: String,
280    /// The `connection_params` field.
281    pub connection_params: std::collections::BTreeMap<String, String>,
282    /// The `invocation_id` field.
283    pub invocation_id: String,
284    /// The `context` field; None when unset.
285    pub context: Option<RequestContext>,
286}
287
288/// GetSessionCatalogResponse returns request-scoped catalog extensions.
289///
290/// Native message type for `gestalt.provider.v1.GetSessionCatalogResponse`.
291#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
292#[serde(rename_all = "camelCase")]
293pub struct GetSessionCatalogResponse {
294    /// The `catalog` field; None when unset.
295    pub catalog: Option<Catalog>,
296}
297
298/// HTTPSubjectRequest carries one verified hosted HTTP request into an optional
299/// plugin-local subject resolution hook.
300///
301/// Native message type for `gestalt.provider.v1.HTTPSubjectRequest`.
302#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
303#[serde(rename_all = "camelCase")]
304pub struct HTTPSubjectRequest {
305    /// The `binding` field.
306    pub binding: String,
307    /// The `method` field.
308    pub method: String,
309    /// The `path` field.
310    pub path: String,
311    /// The `content_type` field.
312    pub content_type: String,
313    /// The `headers` field.
314    pub headers: std::collections::BTreeMap<String, StringList>,
315    /// The `query` field.
316    pub query: std::collections::BTreeMap<String, StringList>,
317    /// The `params` field; None when unset.
318    pub params: Option<serde_json::Map<String, serde_json::Value>>,
319    /// The `raw_body` field.
320    pub raw_body: Vec<u8>,
321    /// The `security_scheme` field.
322    pub security_scheme: String,
323    /// The `verified_subject` field.
324    pub verified_subject: String,
325    /// The `verified_claims` field.
326    pub verified_claims: std::collections::BTreeMap<String, String>,
327}
328
329/// HostContext describes stable public host metadata available to provider code.
330///
331/// Native message type for `gestalt.provider.v1.HostContext`.
332#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
333#[serde(rename_all = "camelCase")]
334pub struct HostContext {
335    /// The `public_base_url` field.
336    pub public_base_url: String,
337}
338
339/// Native message type for `gestalt.provider.v1.InvocationContext`.
340#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
341#[serde(rename_all = "camelCase")]
342pub struct InvocationContext {
343    /// The `request_id` field.
344    pub request_id: String,
345    /// The `depth` field.
346    pub depth: i32,
347    /// The `call_chain` field.
348    pub call_chain: Vec<String>,
349    /// The `surface` field.
350    pub surface: String,
351    /// The `internal_connection_access` field.
352    pub internal_connection_access: bool,
353    /// The `connection` field.
354    pub connection: String,
355}
356
357/// Values of the `value` oneof in `InvokeFrame`; the message field is None when unset.
358#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
359#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
360pub enum InvokeFrameValue {
361    /// The `metadata` variant.
362    Metadata(InvokeMetadata),
363    /// The `data` variant.
364    Data(Vec<u8>),
365}
366
367/// InvokeFrame is one frame in a streaming invocation. The first frame is always
368/// metadata; subsequent frames carry data bytes produced by the operation
369/// handler (after encoding, for typed item streams). A mid-stream error (for
370/// example, a validation failure or a recovered panic) may emit a trailing
371/// metadata frame with a non-2xx status followed by a data frame carrying a
372/// JSON error body, after which the stream ends.
373///
374/// Native message type for `gestalt.provider.v1.InvokeFrame`.
375#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
376#[serde(rename_all = "camelCase")]
377pub struct InvokeFrame {
378    /// The `value` oneof; None when unset.
379    pub value: Option<InvokeFrameValue>,
380}
381
382/// InvokeMetadata is the first frame of a streaming invocation. It carries the
383/// HTTP-shaped status, headers, and the response media type (from the
384/// operation's StreamResponseSpec).
385///
386/// Native message type for `gestalt.provider.v1.InvokeMetadata`.
387#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct InvokeMetadata {
390    /// The `status` field.
391    pub status: i32,
392    /// The `headers` field.
393    pub headers: std::collections::BTreeMap<String, StringList>,
394    /// The `media_type` field.
395    pub media_type: String,
396}
397
398/// OperationAnnotations carries optional host hints about how an operation
399/// behaves.
400///
401/// Native message type for `gestalt.provider.v1.OperationAnnotations`.
402#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
403#[serde(rename_all = "camelCase")]
404pub struct OperationAnnotations {
405    /// The `read_only_hint` field; None when unset.
406    pub read_only_hint: Option<bool>,
407    /// The `idempotent_hint` field; None when unset.
408    pub idempotent_hint: Option<bool>,
409    /// The `destructive_hint` field; None when unset.
410    pub destructive_hint: Option<bool>,
411    /// The `open_world_hint` field; None when unset.
412    pub open_world_hint: Option<bool>,
413}
414
415/// Values of the `kind` oneof in `OperationResponseSpec`; the message field is None when unset.
416#[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
417#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
418pub enum OperationResponseSpecKind {
419    /// The `unary` variant.
420    Unary(UnaryResponseSpec),
421    /// The `stream` variant.
422    Stream(StreamResponseSpec),
423}
424
425/// OperationResponseSpec declares how an operation responds. App authoring
426/// defaults to unary; emitted catalogs always declare either unary or stream.
427///
428/// Native message type for `gestalt.provider.v1.OperationResponseSpec`.
429#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
430#[serde(rename_all = "camelCase")]
431pub struct OperationResponseSpec {
432    /// The `kind` oneof; None when unset.
433    pub kind: Option<OperationResponseSpecKind>,
434}
435
436/// OperationResult is the serialized result returned from an Execute call.
437///
438/// Native message type for `gestalt.provider.v1.OperationResult`.
439#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
440#[serde(rename_all = "camelCase")]
441pub struct OperationResult {
442    /// The `status` field.
443    pub status: i32,
444    /// The `body` field.
445    pub body: Vec<u8>,
446    /// The `headers` field.
447    pub headers: std::collections::BTreeMap<String, StringList>,
448}
449
450/// ProviderContext identifies the provider process that received the request
451/// context from the host and is trusted to propagate it back to host services.
452///
453/// Native message type for `gestalt.provider.v1.ProviderContext`.
454#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
455#[serde(rename_all = "camelCase")]
456pub struct ProviderContext {
457    /// The `kind` field.
458    pub kind: String,
459    /// The `name` field.
460    pub name: String,
461}
462
463/// ProviderMetadata describes an integration provider's static capabilities.
464///
465/// Native message type for `gestalt.provider.v1.ProviderMetadata`.
466#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
467#[serde(rename_all = "camelCase")]
468pub struct ProviderMetadata {
469    /// The `name` field.
470    pub name: String,
471    /// The `display_name` field.
472    pub display_name: String,
473    /// The `description` field.
474    pub description: String,
475    /// The `connection_mode` field.
476    pub connection_mode: ConnectionMode,
477    /// The `auth_types` field.
478    pub auth_types: Vec<String>,
479    /// The `connection_params` field.
480    pub connection_params: std::collections::BTreeMap<String, ConnectionParamDef>,
481    /// The `static_catalog` field; None when unset.
482    pub static_catalog: Option<Catalog>,
483    /// The `supports_session_catalog` field.
484    pub supports_session_catalog: bool,
485    /// The `min_protocol_version` field.
486    pub min_protocol_version: i32,
487    /// The `max_protocol_version` field.
488    pub max_protocol_version: i32,
489    /// Workflow definitions this app declares as desired state. Each entry is a
490    /// serialized gestalt.provider.v1.WorkflowDefinitionSpec (workflow.proto).
491    /// Framed as bytes because workflow.proto imports app.proto, so this file
492    /// cannot reference WorkflowDefinitionSpec directly. The spec `id` is the
493    /// app-local id; stored ids look like app_notes_daily-summary (app name + local id)
494    /// and are applied with gestaltd authority on the config-definitions reconcile path.
495    ///
496    /// The `workflow_definition_specs` field.
497    pub workflow_definition_specs: Vec<Vec<u8>>,
498}
499
500/// RequestContext bundles the caller, credential, access, and host metadata for
501/// one operation.
502///
503/// Native message type for `gestalt.provider.v1.RequestContext`.
504#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
505#[serde(rename_all = "camelCase")]
506pub struct RequestContext {
507    /// The `subject` field; None when unset.
508    pub subject: Option<SubjectContext>,
509    /// The `credential` field; None when unset.
510    pub credential: Option<CredentialContext>,
511    /// The `access` field; None when unset.
512    pub access: Option<AccessContext>,
513    /// The `workflow` field; None when unset.
514    pub workflow: Option<serde_json::Map<String, serde_json::Value>>,
515    /// The `host` field; None when unset.
516    pub host: Option<HostContext>,
517    /// Original agent caller when an agent tool executes with delegated run-as identity.
518    ///
519    /// The `agent_subject` field; None when unset.
520    pub agent_subject: Option<SubjectContext>,
521    /// The `caller` field; None when unset.
522    pub caller: Option<ProviderContext>,
523    /// The `invocation` field; None when unset.
524    pub invocation: Option<InvocationContext>,
525    /// Agent tool refs granted to the operation request, when the request is
526    /// executing as an agent tool.
527    ///
528    /// The `tool_refs` field.
529    pub tool_refs: Vec<AgentToolRef>,
530    /// Preserves the distinction between an omitted tool-ref context and an
531    /// explicitly empty inherited tool-ref context.
532    ///
533    /// The `tool_refs_set` field.
534    pub tool_refs_set: bool,
535    /// The `request_meta` field; None when unset.
536    pub request_meta: Option<RequestMetaContext>,
537    /// The `agent` field; None when unset.
538    pub agent: Option<AgentInvocationContext>,
539}
540
541/// Native message type for `gestalt.provider.v1.RequestMetaContext`.
542#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
543#[serde(rename_all = "camelCase")]
544pub struct RequestMetaContext {
545    /// The `client_ip` field.
546    pub client_ip: String,
547    /// The `remote_addr` field.
548    pub remote_addr: String,
549    /// The `user_agent` field.
550    pub user_agent: String,
551}
552
553/// ResolveHTTPSubjectRequest asks a provider to map a verified hosted HTTP
554/// request to a concrete Gestalt subject before normal operation authorization
555/// and dispatch.
556///
557/// Native message type for `gestalt.provider.v1.ResolveHTTPSubjectRequest`.
558#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
559#[serde(rename_all = "camelCase")]
560pub struct ResolveHTTPSubjectRequest {
561    /// The `request` field; None when unset.
562    pub request: Option<HTTPSubjectRequest>,
563    /// The `context` field; None when unset.
564    pub context: Option<RequestContext>,
565}
566
567/// ResolveHTTPSubjectResponse returns the concrete Gestalt subject a hosted HTTP
568/// request should execute as. An unset subject means "fall back to the binding
569/// subject". When reject_status is set, the host should reject the inbound
570/// request with the provided status and message.
571///
572/// Native message type for `gestalt.provider.v1.ResolveHTTPSubjectResponse`.
573#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
574#[serde(rename_all = "camelCase")]
575pub struct ResolveHTTPSubjectResponse {
576    /// The `subject` field; None when unset.
577    pub subject: Option<SubjectContext>,
578    /// The `reject_status` field.
579    pub reject_status: i32,
580    /// The `reject_message` field.
581    pub reject_message: String,
582}
583
584/// StartProviderRequest configures an integration provider for one runtime
585/// session.
586///
587/// Native message type for `gestalt.provider.v1.StartProviderRequest`.
588#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
589#[serde(rename_all = "camelCase")]
590pub struct StartProviderRequest {
591    /// The `name` field.
592    pub name: String,
593    /// The `config` field; None when unset.
594    pub config: Option<serde_json::Map<String, serde_json::Value>>,
595    /// The `protocol_version` field.
596    pub protocol_version: i32,
597}
598
599/// StartProviderResponse confirms the protocol version the provider is serving.
600///
601/// Native message type for `gestalt.provider.v1.StartProviderResponse`.
602#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
603#[serde(rename_all = "camelCase")]
604pub struct StartProviderResponse {
605    /// The `protocol_version` field.
606    pub protocol_version: i32,
607}
608
609/// StreamResponseSpec describes a streaming operation response. The media type
610/// names the representation (for example application/x-ndjson); the item schema
611/// is optional and describes one yielded item when the stream is typed.
612///
613/// Native message type for `gestalt.provider.v1.StreamResponseSpec`.
614#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
615#[serde(rename_all = "camelCase")]
616pub struct StreamResponseSpec {
617    /// The `media_type` field.
618    pub media_type: String,
619    /// The `item_schema` field; None when unset.
620    pub item_schema: Option<serde_json::Map<String, serde_json::Value>>,
621}
622
623/// StringList is a helper map value for repeated HTTP header and query values.
624///
625/// Native message type for `gestalt.provider.v1.StringList`.
626#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
627#[serde(rename_all = "camelCase")]
628pub struct StringList {
629    /// The `values` field.
630    pub values: Vec<String>,
631}
632
633/// SubjectContext identifies the caller that initiated an operation.
634///
635/// Native message type for `gestalt.provider.v1.SubjectContext`.
636#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
637#[serde(rename_all = "camelCase")]
638pub struct SubjectContext {
639    /// The `id` field.
640    pub id: String,
641    /// The `email` field.
642    pub email: String,
643    /// The `display_name` field.
644    pub display_name: String,
645    /// The `scopes` field.
646    pub scopes: Vec<String>,
647    /// The `permissions` field.
648    pub permissions: Vec<SubjectPermissionContext>,
649}
650
651/// Native message type for `gestalt.provider.v1.SubjectPermissionContext`.
652#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
653#[serde(rename_all = "camelCase")]
654pub struct SubjectPermissionContext {
655    /// The `app` field.
656    pub app: String,
657    /// The `operations` field.
658    pub operations: Vec<String>,
659    /// The `all_operations` field.
660    pub all_operations: bool,
661}
662
663/// UnaryResponseSpec describes a unary (fully materialized) operation response.
664///
665/// Native message type for `gestalt.provider.v1.UnaryResponseSpec`.
666#[derive(Clone, Debug, Default, PartialEq, serde::Serialize, serde::Deserialize)]
667#[serde(rename_all = "camelCase")]
668pub struct UnaryResponseSpec {
669    /// The `schema` field; None when unset.
670    pub schema: Option<serde_json::Map<String, serde_json::Value>>,
671}
672
673/// Client for the `gestalt.provider.v1.App` service.
674pub struct App {
675    inner: v1::app_client::AppClient<HostServiceChannel>,
676    timeout: Option<std::time::Duration>,
677    context: Option<RequestContext>,
678}
679
680impl App {
681    /// Creates a client over an established channel.
682    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    /// Sets a deadline applied to every unary call; calls that run past it
691    /// fail with DEADLINE_EXCEEDED. Streaming calls are unaffected.
692    pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
693        self.timeout = Some(timeout);
694        self
695    }
696
697    /// Sets the default request context, injected into outgoing requests
698    /// that do not carry one.
699    pub fn with_context(mut self, context: RequestContext) -> Self {
700        self.context = Some(context);
701        self
702    }
703
704    /// Connects to the `app` host service described by the environment.
705    pub async fn connect() -> Result<Self, GestaltError> {
706        Self::connect_named("").await
707    }
708
709    /// Connects to the named `app` host-service binding.
710    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    /// Calls `gestalt.provider.v1.App.Invoke`.
719    /// The result decodes with the standard JSON operation envelope
720    /// semantics; payload failures surface as [`InvokeError`].
721    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    /// Calls `gestalt.provider.v1.App.Invoke` with the full request and response messages.
762    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    /// InvokeStream is the streaming counterpart of Invoke. It is gRPC-only (no
779    /// REST binding) and shares Invoke's request shape, authorization, and
780    /// signature policy. The first response frame is always InvokeMetadata;
781    /// subsequent frames carry data bytes from the operation's stream response.
782    /// A mid-stream error may emit a trailing metadata frame with an error status
783    /// followed by a JSON error body, after which the stream ends.
784    ///
785    /// Calls `gestalt.provider.v1.App.InvokeStream`, returning a stream of converted frames.
786    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    /// Calls `gestalt.provider.v1.App.InvokeGraphQL`.
804    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    /// Calls `gestalt.provider.v1.App.InvokeGraphQL` with the full request and response messages.
829    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/// Optional parameters of [`App::invoke`]; the default value leaves every
847/// option unset.
848#[derive(Clone, Debug, Default)]
849pub struct AppInvokeOptions {
850    /// The `connection` field.
851    pub connection: String,
852    /// The `instance` field.
853    pub instance: String,
854    /// The `idempotency_key` field.
855    pub idempotency_key: String,
856    /// The `credential_mode` field.
857    pub credential_mode: String,
858    /// The `run_as` field; None when unset.
859    pub run_as: Option<SubjectContext>,
860    /// headers overrides outbound static headers declared by the target provider.
861    ///
862    /// The `headers` field.
863    pub headers: std::collections::BTreeMap<String, String>,
864}
865
866/// Optional parameters of [`App::invoke_stream`]; the default value leaves every
867/// option unset.
868#[derive(Clone, Debug, Default)]
869pub struct AppInvokeStreamOptions {
870    /// The `connection` field.
871    pub connection: String,
872    /// The `instance` field.
873    pub instance: String,
874    /// The `idempotency_key` field.
875    pub idempotency_key: String,
876    /// The `credential_mode` field.
877    pub credential_mode: String,
878    /// The `run_as` field; None when unset.
879    pub run_as: Option<SubjectContext>,
880    /// headers overrides outbound static headers declared by the target provider.
881    ///
882    /// The `headers` field.
883    pub headers: std::collections::BTreeMap<String, String>,
884}
885
886/// Optional parameters of [`App::invoke_graphql`]; the default value leaves every
887/// option unset.
888#[derive(Clone, Debug, Default)]
889pub struct AppInvokeGraphQLOptions {
890    /// The `connection` field.
891    pub connection: String,
892    /// The `instance` field.
893    pub instance: String,
894    /// The `idempotency_key` field.
895    pub idempotency_key: String,
896    /// The `variables` field; None when unset.
897    pub variables: Option<serde_json::Map<String, serde_json::Value>>,
898    /// headers overrides outbound static headers declared by the target provider.
899    ///
900    /// The `headers` field.
901    pub headers: std::collections::BTreeMap<String, String>,
902}
903
904/// InvokeStream is the streaming counterpart of Invoke. It is gRPC-only (no
905/// REST binding) and shares Invoke's request shape, authorization, and
906/// signature policy. The first response frame is always InvokeMetadata;
907/// subsequent frames carry data bytes from the operation's stream response.
908/// A mid-stream error may emit a trailing metadata frame with an error status
909/// followed by a JSON error body, after which the stream ends.
910///
911/// Stream of converted `InvokeFrame` frames; transport errors convert to GestaltError.
912pub struct AppInvokeStreamStream {
913    inner: tonic::Streaming<v1::InvokeFrame>,
914}
915
916impl AppInvokeStreamStream {
917    /// Receives the next frame, or None when the stream ends.
918    pub async fn recv(&mut self) -> Result<Option<InvokeFrame>, GestaltError> {
919        Ok(self.inner.message().await?.map(from_wire_invoke_frame))
920    }
921}
922
923/// AppProvider models the shared Gestalt integration-provider protocol.
924///
925/// Client for the `gestalt.provider.v1.AppProvider` service.
926pub 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    /// Creates a client over an established channel.
934    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    /// Sets a deadline applied to every unary call; calls that run past it
943    /// fail with DEADLINE_EXCEEDED. Streaming calls are unaffected.
944    pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
945        self.timeout = Some(timeout);
946        self
947    }
948
949    /// Sets the default request context, injected into outgoing requests
950    /// that do not carry one.
951    pub fn with_context(mut self, context: RequestContext) -> Self {
952        self.context = Some(context);
953        self
954    }
955
956    /// Calls `gestalt.provider.v1.AppProvider.GetMetadata`.
957    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    /// Calls `gestalt.provider.v1.AppProvider.StartProvider`.
967    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    /// Calls `gestalt.provider.v1.AppProvider.StartProvider` with the full request and response messages.
987    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    /// Calls `gestalt.provider.v1.AppProvider.Execute`.
1000    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    /// Calls `gestalt.provider.v1.AppProvider.Execute` with the full request and response messages.
1026    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    /// ExecuteStream is the streaming counterpart of Execute. The first response
1043    /// frame is always InvokeMetadata; subsequent frames carry encoded data bytes.
1044    /// A mid-stream error may emit a trailing metadata frame with an error status
1045    /// followed by a JSON error body, after which the stream ends.
1046    ///
1047    /// Calls `gestalt.provider.v1.AppProvider.ExecuteStream`, returning a stream of converted frames.
1048    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    /// Calls `gestalt.provider.v1.AppProvider.ResolveHTTPSubject`.
1066    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    /// Calls `gestalt.provider.v1.AppProvider.GetSessionCatalog`.
1085    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    /// Calls `gestalt.provider.v1.AppProvider.GetSessionCatalog` with the full request and response messages.
1107    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
1126/// ExecuteStream is the streaming counterpart of Execute. The first response
1127/// frame is always InvokeMetadata; subsequent frames carry encoded data bytes.
1128/// A mid-stream error may emit a trailing metadata frame with an error status
1129/// followed by a JSON error body, after which the stream ends.
1130///
1131/// Stream of converted `InvokeFrame` frames; transport errors convert to GestaltError.
1132pub struct AppProviderExecuteStreamStream {
1133    inner: tonic::Streaming<v1::InvokeFrame>,
1134}
1135
1136impl AppProviderExecuteStreamStream {
1137    /// Receives the next frame, or None when the stream ends.
1138    pub async fn recv(&mut self) -> Result<Option<InvokeFrame>, GestaltError> {
1139        Ok(self.inner.message().await?.map(from_wire_invoke_frame))
1140    }
1141}