Skip to main content

greentic_interfaces_host/
lib.rs

1#![deny(unsafe_code)]
2#![warn(missing_docs, clippy::unwrap_used, clippy::expect_used)]
3//! Host-facing bindings and mappers re-exported from `greentic-interfaces`.
4
5#[cfg(target_arch = "wasm32")]
6compile_error!("greentic-interfaces-host is intended for native host targets.");
7
8pub use greentic_interfaces::{bindings, mappers, validate};
9
10/// Component control and exports.
11pub mod component {
12    /// Component ABI with config surface `greentic:component/component@0.5.0`.
13    pub mod v0_5 {
14        pub use greentic_interfaces::component_v0_5::*;
15    }
16    /// Component ABI with optional config schema export `greentic:component/component-configurable@0.5.0`.
17    pub mod v0_5_configurable {
18        pub use greentic_interfaces::component_configurable_v0_5::*;
19    }
20    /// Compatibility exports for `greentic:component/component@0.4.0`.
21    pub mod v0_4 {
22        pub use greentic_interfaces::component_v0_4::*;
23    }
24    /// Generic component invocation world `greentic:component-v1/component-host@0.1.0`.
25    pub mod v1 {
26        pub use greentic_interfaces::component_v1::*;
27        pub use greentic_interfaces::mappers::ComponentOutcome;
28        pub use greentic_interfaces::mappers::ComponentOutcomeStatus;
29    }
30    /// Describe-only schema export world `greentic:component/component@1.0.0`.
31    pub mod describe_v1 {
32        pub use greentic_interfaces::component_describe_v1::*;
33    }
34    /// Lifecycle hooks world `greentic:lifecycle/component-lifecycle@1.0.0`.
35    pub mod lifecycle_v1 {
36        pub use greentic_interfaces::component_lifecycle_v1::*;
37    }
38}
39
40/// Runner host bundle `greentic:host@1.0.0`.
41pub mod runner_host_v1 {
42    pub use greentic_interfaces::runner_host_v1::*;
43}
44
45/// Pack exporters.
46pub mod pack_exports {
47    /// Pack exports `0.2.0` world.
48    pub mod v0_2 {
49        pub use greentic_interfaces::pack_export_v0_2::*;
50    }
51    /// Pack exports `0.4.0` world.
52    pub mod v0_4 {
53        pub use greentic_interfaces::pack_export_v0_4::*;
54    }
55    /// Pack metadata/flow discovery world `greentic:pack-export-v1/pack-host@0.1.0`.
56    pub mod v1 {
57        pub use greentic_interfaces::mappers::{
58            FlowDescriptor as HostFlowDescriptor, PackDescriptor as HostPackDescriptor,
59        };
60        pub use greentic_interfaces::pack_export_v1::*;
61    }
62}
63
64/// Core types.
65pub mod types {
66    /// Shared flow/component fundamentals `greentic:common-types/common@0.1.0`.
67    pub mod common_v0_1 {
68        pub use greentic_interfaces::common_types_v0_1::*;
69    }
70    /// Core type defs for the 0.2 line.
71    pub mod types_core_v0_2 {
72        pub use greentic_interfaces::types_core_v0_2::*;
73    }
74    /// Core type defs for the 0.4 line.
75    pub mod types_core_v0_4 {
76        pub use greentic_interfaces::types_core_v0_4::*;
77    }
78}
79
80/// v1 host capability contracts.
81pub mod secrets {
82    /// `greentic:secrets-store/store@1.0.0` host imports.
83    pub mod store_v1 {
84        pub use greentic_interfaces::secrets_store_v1::*;
85    }
86}
87
88/// Provider core schema world `greentic:provider-schema-core@1.0.0`.
89#[cfg(feature = "provider-core-v1")]
90pub mod provider_core_v1 {
91    pub use greentic_interfaces::provider_schema_core_v1::*;
92}
93
94/// Shared messaging provider metadata/render helpers.
95pub mod provider_common {
96    pub use greentic_interfaces::bindings::provider_common_0_0_2_common::exports::provider::common::capabilities::*;
97    pub use greentic_interfaces::bindings::provider_common_0_0_2_common::exports::provider::common::render::*;
98}
99
100/// v1 host capability contracts.
101pub mod state {
102    pub use greentic_interfaces::state_store_v1::*;
103}
104
105/// v1 host capability contracts.
106pub mod http_client {
107    /// `greentic:http/client@1.0.0` bindings.
108    pub use greentic_interfaces::http_client_v1::*;
109
110    /// `greentic:http/client@1.1.0` bindings with request options + tenant context.
111    pub mod v1_1 {
112        pub use greentic_interfaces::http_client_v1_1::*;
113    }
114}
115
116/// v1 host capability contracts.
117pub mod telemetry {
118    pub use greentic_interfaces::telemetry_logger_v1::*;
119}
120
121/// v1 host capability contracts.
122#[cfg(feature = "oauth-broker-v1")]
123pub mod oauth_broker {
124    pub use greentic_interfaces::oauth_broker_v1::*;
125}
126
127/// v1 OAuth broker client imports.
128#[cfg(feature = "oauth-broker-v1")]
129pub mod oauth_broker_client {
130    pub use greentic_interfaces::oauth_broker_client_v1::*;
131}
132
133/// Generic worker ABI world.
134#[cfg(feature = "worker-v1")]
135pub mod worker {
136    use greentic_interfaces::bindings::greentic::interfaces_types::types as interfaces_types;
137    use greentic_interfaces::worker_v1::exports::greentic::worker::worker_api::{
138        TenantCtx as WitWorkerTenantCtx, WorkerMessage as WitWorkerMessage,
139        WorkerRequest as WitWorkerRequest, WorkerResponse as WitWorkerResponse,
140    };
141    use greentic_interfaces::worker_v1::greentic::types_core::types::{
142        Cloud, DeploymentCtx, Platform,
143    };
144    use greentic_types::{ErrorCode, GreenticError, TenantCtx};
145    use serde::{Deserialize, Serialize};
146    use serde_json::Value;
147
148    pub use greentic_interfaces::worker_v1::*;
149
150    type MapperResult<T> = Result<T, GreenticError>;
151
152    fn to_worker_tenant(ctx: TenantCtx) -> MapperResult<WitWorkerTenantCtx> {
153        let base = crate::mappers::tenant_ctx_to_wit(ctx)?;
154        Ok(WitWorkerTenantCtx {
155            tenant: base.tenant,
156            team: base.team,
157            user: base.user,
158            deployment: DeploymentCtx {
159                cloud: Cloud::Other,
160                region: None,
161                platform: Platform::Other,
162                runtime: None,
163            },
164            trace_id: base.trace_id,
165            session_id: base.session_id,
166            flow_id: base.flow_id,
167            node_id: base.node_id,
168            provider_id: base.provider_id,
169        })
170    }
171
172    fn from_worker_tenant(ctx: WitWorkerTenantCtx) -> MapperResult<TenantCtx> {
173        let base = interfaces_types::TenantCtx {
174            env: "unknown".to_string(),
175            tenant: ctx.tenant.clone(),
176            tenant_id: ctx.tenant,
177            team: ctx.team.clone(),
178            team_id: ctx.team,
179            user: ctx.user.clone(),
180            user_id: ctx.user,
181            trace_id: ctx.trace_id,
182            i18n_id: None,
183            correlation_id: None,
184            session_id: ctx.session_id,
185            flow_id: ctx.flow_id,
186            node_id: ctx.node_id,
187            provider_id: ctx.provider_id,
188            deadline_ms: None,
189            attempt: 0,
190            idempotency_key: None,
191            impersonation: None,
192            attributes: Vec::new(),
193        };
194        crate::mappers::tenant_ctx_from_wit(base)
195    }
196
197    /// Host-friendly request wrapper for worker invocations (uses `greentic-types` and `serde_json` payloads).
198    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
199    pub struct HostWorkerRequest {
200        /// ABI version identifier (e.g. "1.0").
201        pub version: String,
202        /// Shared tenant context from `greentic-types`.
203        pub tenant: TenantCtx,
204        /// Target worker identifier.
205        pub worker_id: String,
206        /// JSON payload for the worker.
207        pub payload: Value,
208        /// ISO8601 UTC timestamp of the request.
209        pub timestamp_utc: String,
210        /// Optional correlation identifier.
211        pub correlation_id: Option<String>,
212        /// Optional session identifier.
213        pub session_id: Option<String>,
214        /// Optional thread identifier.
215        pub thread_id: Option<String>,
216    }
217
218    /// Host-friendly worker message envelope.
219    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
220    pub struct HostWorkerMessage {
221        /// Message kind (e.g. "text", "card").
222        pub kind: String,
223        /// JSON payload content.
224        pub payload: Value,
225    }
226
227    /// Host-friendly worker response wrapper with typed tenant context.
228    #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
229    pub struct HostWorkerResponse {
230        /// Mirrors the request version.
231        pub version: String,
232        /// Shared tenant context from `greentic-types`.
233        pub tenant: TenantCtx,
234        /// Worker identifier that produced the response.
235        pub worker_id: String,
236        /// ISO8601 UTC timestamp.
237        pub timestamp_utc: String,
238        /// Accumulated worker messages.
239        pub messages: Vec<HostWorkerMessage>,
240        /// Optional correlation identifier.
241        pub correlation_id: Option<String>,
242        /// Optional session identifier.
243        pub session_id: Option<String>,
244        /// Optional thread identifier.
245        pub thread_id: Option<String>,
246    }
247
248    impl TryFrom<HostWorkerMessage> for WitWorkerMessage {
249        type Error = GreenticError;
250
251        fn try_from(value: HostWorkerMessage) -> MapperResult<Self> {
252            let payload_json = serde_json::to_string(&value.payload)
253                .map_err(|err| GreenticError::new(ErrorCode::InvalidInput, err.to_string()))?;
254            Ok(Self {
255                kind: value.kind,
256                payload_json,
257            })
258        }
259    }
260
261    impl TryFrom<WitWorkerMessage> for HostWorkerMessage {
262        type Error = GreenticError;
263
264        fn try_from(value: WitWorkerMessage) -> MapperResult<Self> {
265            let payload = serde_json::from_str(&value.payload_json).map_err(|err| {
266                GreenticError::new(
267                    ErrorCode::InvalidInput,
268                    format!("invalid worker payload: {err}"),
269                )
270            })?;
271            Ok(Self {
272                kind: value.kind,
273                payload,
274            })
275        }
276    }
277
278    impl TryFrom<HostWorkerRequest> for WitWorkerRequest {
279        type Error = GreenticError;
280
281        fn try_from(value: HostWorkerRequest) -> MapperResult<Self> {
282            let payload_json = serde_json::to_string(&value.payload)
283                .map_err(|err| GreenticError::new(ErrorCode::InvalidInput, err.to_string()))?;
284            Ok(Self {
285                version: value.version,
286                tenant: to_worker_tenant(value.tenant)?,
287                worker_id: value.worker_id,
288                correlation_id: value.correlation_id,
289                session_id: value.session_id,
290                thread_id: value.thread_id,
291                payload_json,
292                timestamp_utc: value.timestamp_utc,
293            })
294        }
295    }
296
297    impl TryFrom<WitWorkerRequest> for HostWorkerRequest {
298        type Error = GreenticError;
299
300        fn try_from(value: WitWorkerRequest) -> MapperResult<Self> {
301            let payload: Value = serde_json::from_str(&value.payload_json).map_err(|err| {
302                GreenticError::new(
303                    ErrorCode::InvalidInput,
304                    format!("invalid worker payload: {err}"),
305                )
306            })?;
307            Ok(Self {
308                version: value.version,
309                tenant: from_worker_tenant(value.tenant)?,
310                worker_id: value.worker_id,
311                correlation_id: value.correlation_id,
312                session_id: value.session_id,
313                thread_id: value.thread_id,
314                payload,
315                timestamp_utc: value.timestamp_utc,
316            })
317        }
318    }
319
320    impl TryFrom<HostWorkerResponse> for WitWorkerResponse {
321        type Error = GreenticError;
322
323        fn try_from(value: HostWorkerResponse) -> MapperResult<Self> {
324            let messages = value
325                .messages
326                .into_iter()
327                .map(WitWorkerMessage::try_from)
328                .collect::<MapperResult<Vec<_>>>()?;
329            Ok(Self {
330                version: value.version,
331                tenant: to_worker_tenant(value.tenant)?,
332                worker_id: value.worker_id,
333                correlation_id: value.correlation_id,
334                session_id: value.session_id,
335                thread_id: value.thread_id,
336                messages,
337                timestamp_utc: value.timestamp_utc,
338            })
339        }
340    }
341
342    impl TryFrom<WitWorkerResponse> for HostWorkerResponse {
343        type Error = GreenticError;
344
345        fn try_from(value: WitWorkerResponse) -> MapperResult<Self> {
346            let messages = value
347                .messages
348                .into_iter()
349                .map(HostWorkerMessage::try_from)
350                .collect::<MapperResult<Vec<_>>>()?;
351            Ok(Self {
352                version: value.version,
353                tenant: from_worker_tenant(value.tenant)?,
354                worker_id: value.worker_id,
355                correlation_id: value.correlation_id,
356                session_id: value.session_id,
357                thread_id: value.thread_id,
358                messages,
359                timestamp_utc: value.timestamp_utc,
360            })
361        }
362    }
363}
364
365/// GUI fragment renderers implemented by components.
366#[cfg(feature = "gui-fragment")]
367pub mod gui_fragment {
368    pub use greentic_interfaces::bindings::greentic_gui_1_0_0_gui_fragment::exports::greentic::gui::fragment_api as bindings;
369    pub use bindings::FragmentContext;
370    pub use bindings::Guest as GuiFragment;
371}
372
373/// Supply-chain provider contracts.
374pub mod supply_chain {
375    /// Source provider world `greentic:source/source-sync@1.0.0`.
376    pub mod source {
377        pub use greentic_interfaces::bindings::greentic_source_1_0_0_source_sync::exports::greentic::source::source_api::*;
378    }
379    /// Build provider world `greentic:build/builder@1.0.0`.
380    pub mod build {
381        pub use greentic_interfaces::bindings::greentic_build_1_0_0_builder::exports::greentic::build::builder_api::*;
382    }
383    /// Scanner world `greentic:scan/scanner@1.0.0`.
384    pub mod scan {
385        pub use greentic_interfaces::bindings::greentic_scan_1_0_0_scanner::exports::greentic::scan::scanner_api::*;
386    }
387    /// Signing world `greentic:signing/signer@1.0.0`.
388    pub mod signing {
389        pub use greentic_interfaces::bindings::greentic_signing_1_0_0_signer::exports::greentic::signing::signer_api::*;
390    }
391    /// Attestation world `greentic:attestation/attester@1.0.0`.
392    pub mod attestation {
393        pub use greentic_interfaces::bindings::greentic_attestation_1_0_0_attester::exports::greentic::attestation::attester_api::*;
394    }
395    /// Policy evaluation world `greentic:policy/policy-evaluator@1.0.0`.
396    pub mod policy {
397        pub use greentic_interfaces::bindings::greentic_policy_1_0_0_policy_evaluator::exports::greentic::policy::policy_api::*;
398    }
399    /// Metadata store world `greentic:metadata/metadata-store@1.0.0`.
400    pub mod metadata {
401        pub use greentic_interfaces::bindings::greentic_metadata_1_0_0_metadata_store::exports::greentic::metadata::metadata_api::*;
402    }
403    /// OCI distribution world `greentic:oci/oci-distribution@1.0.0`.
404    pub mod oci {
405        pub use greentic_interfaces::bindings::greentic_oci_1_0_0_oci_distribution::exports::greentic::oci::oci_api::*;
406    }
407}
408
409/// Desired state distribution contracts.
410pub mod distribution {
411    /// `greentic:distribution/distribution@1.0.0`.
412    pub mod v1 {
413        pub use greentic_interfaces::bindings::greentic_distribution_1_0_0_distribution::exports::greentic::distribution::distribution_api::*;
414    }
415}
416
417/// Distributor API contracts.
418pub mod distributor_api {
419    /// `greentic:distributor-api/distributor-api@1.0.0`.
420    pub mod v1 {
421        pub use greentic_interfaces::bindings::greentic_distributor_api_1_0_0_distributor_api::exports::greentic::distributor_api::distributor::*;
422    }
423    /// `greentic:distributor-api/distributor-api@1.1.0`.
424    pub mod v1_1 {
425        pub use greentic_interfaces::bindings::greentic_distributor_api_1_1_0_distributor_api::exports::greentic::distributor_api::distributor::*;
426    }
427
428    /// Resolved component metadata returned by a ref-based lookup.
429    #[derive(Debug, Clone)]
430    pub struct ResolvedComponent {
431        /// Digest returned by the distributor (opaque string).
432        pub digest: String,
433        /// Metadata returned by `resolve-ref`.
434        pub metadata: v1_1::ResolveRefMetadata,
435    }
436
437    /// Resolved component artifact content.
438    #[derive(Debug, Clone, PartialEq)]
439    pub enum ResolvedArtifact {
440        /// Raw component bytes.
441        Bytes(Vec<u8>),
442        /// Filesystem path to the component.
443        Path(String),
444    }
445
446    /// Host-side resolver for ref-based component lookup.
447    pub trait ComponentResolver {
448        /// Resolve a component reference string to a digest plus metadata.
449        fn resolve_ref(&self, component_ref: &str) -> ResolvedComponent;
450
451        /// Fetch a resolved component artifact by digest.
452        fn fetch_digest(&self, digest: &str) -> ResolvedArtifact;
453    }
454}
455
456/// Stable alias for HTTP client imports.
457pub mod http {
458    pub use super::http_client::*;
459}
460
461/// Stable alias for OAuth broker imports.
462#[cfg(feature = "oauth-broker-v1")]
463pub mod oauth {
464    pub use super::oauth_broker::*;
465}
466
467/// MCP router surfaces (multiple protocol snapshots).
468pub mod mcp {
469    /// `wasix:mcp@24.11.5` snapshot (2024-11-05 spec).
470    #[cfg(feature = "wasix-mcp-24-11-05-host")]
471    pub mod v24_11_05 {
472        pub use greentic_interfaces::wasix_mcp_24_11_05::*;
473    }
474
475    /// `wasix:mcp@25.3.26` snapshot with annotations/audio/completions/progress.
476    #[cfg(feature = "wasix-mcp-25-03-26-host")]
477    pub mod v25_03_26 {
478        pub use greentic_interfaces::wasix_mcp_25_03_26::*;
479    }
480
481    /// `wasix:mcp@25.6.18` snapshot with structured output/resources/elicitation.
482    #[cfg(feature = "wasix-mcp-25-06-18-host")]
483    pub mod v25_06_18 {
484        pub use greentic_interfaces::wasix_mcp_25_06_18::*;
485    }
486}
487
488/// UI action handler contracts.
489pub mod ui_actions {
490    /// UI action handler world `greentic:repo-ui-actions/repo-ui-worker@1.0.0`.
491    pub mod repo_ui_worker {
492        pub use greentic_interfaces::bindings::greentic_repo_ui_actions_1_0_0_repo_ui_worker::exports::greentic::repo_ui_actions::ui_action_api::*;
493    }
494}