1#![allow(clippy::all)]
3#![allow(missing_docs)]
4
5macro_rules! declare_world {
6 (
7 mod $mod_name:ident,
8 path = $path_literal:literal,
9 world = $world_literal:literal
10 $(, legacy = { $($legacy:item)* } )?
11 ) => {
12 pub mod $mod_name {
13 mod bindings {
14 wasmtime::component::bindgen!({
15 path: $path_literal,
16 world: $world_literal,
17 });
18 }
19
20 #[allow(unused_imports)]
21 pub use bindings::*;
22
23 $(
24 $($legacy)*
25 )?
26 }
27 };
28}
29
30#[cfg(feature = "describe-v1")]
31declare_world!(
32 mod component_describe_v1,
33 path = "wit/greentic/component@1.0.0",
34 world = "greentic:component/component@1.0.0",
35 legacy = {
36 pub const PACKAGE_ID: &str = "greentic:component@1.0.0";
38 }
39);
40
41#[cfg(feature = "component-v0-4")]
42declare_world!(
43 mod component_v0_4,
44 path = "wit/greentic/component@0.4.0",
45 world = "greentic:component/component@0.4.0",
46 legacy = {
47 use anyhow::Result as AnyResult;
48 use wasmtime::component::{Component as WasmtimeComponent, Linker};
49 use wasmtime::StoreContextMut;
50
51 pub use bindings::greentic::component::control::Host as ControlHost;
52
53 pub fn add_control_to_linker<T>(
55 linker: &mut Linker<T>,
56 get_host: impl Fn(&mut T) -> &mut (dyn ControlHost + Send + Sync + 'static)
57 + Send
58 + Sync
59 + Copy
60 + 'static,
61 ) -> wasmtime::Result<()>
62 where
63 T: Send + 'static,
64 {
65 let mut inst = linker.instance("greentic:component/control@0.4.0")?;
66
67 inst.func_wrap(
68 "should-cancel",
69 move |mut caller: StoreContextMut<'_, T>, (): ()| {
70 let host = get_host(caller.data_mut());
71 let result = host.should_cancel();
72 Ok((result,))
73 },
74 )?;
75
76 inst.func_wrap(
77 "yield-now",
78 move |mut caller: StoreContextMut<'_, T>, (): ()| {
79 let host = get_host(caller.data_mut());
80 host.yield_now();
81 Ok(())
82 },
83 )?;
84
85 Ok(())
86 }
87
88 pub struct Component;
90
91 impl Component {
92 pub fn instantiate(
94 engine: &wasmtime::Engine,
95 component_wasm: &[u8],
96 ) -> AnyResult<WasmtimeComponent> {
97 Ok(WasmtimeComponent::from_binary(engine, component_wasm)?)
98 }
99 }
100
101 pub const PACKAGE_ID: &str = "greentic:component@0.4.0";
103 }
104);
105
106#[cfg(feature = "pack-export-v0-4")]
107declare_world!(
108 mod pack_export_v0_4,
109 path = "wit/greentic/pack-export@0.4.0",
110 world = "greentic:pack-export/pack-exports@0.4.0",
111 legacy = {
112 pub const PACKAGE_ID: &str = "greentic:pack-export@0.4.0";
114 }
115);
116
117#[cfg(feature = "types-core-v0-4")]
118declare_world!(
119 mod types_core_v0_4,
120 path = "wit/greentic/types-core@0.4.0",
121 world = "greentic:types-core/core@0.4.0",
122 legacy = {
123 pub const PACKAGE_ID: &str = "greentic:types-core@0.4.0";
125 }
126);
127
128#[cfg(feature = "host-import-v0-6")]
129declare_world!(
130 mod host_import_v0_6,
131 path = "wit/greentic/host-import@0.6.0",
132 world = "greentic:host-import/host-imports@0.6.0",
133 legacy = {
134 use wasmtime::component::Linker;
135 use wasmtime::{Result, StoreContextMut};
136
137 pub use bindings::greentic::host_import::{http, mcp, secrets, session, state, telemetry};
138 pub use bindings::greentic::interfaces_types::types as iface_types;
139 pub use bindings::greentic::types_core::types;
140
141 pub trait HostImports {
143 fn secrets_get(
144 &mut self,
145 key: String,
146 ctx: Option<types::TenantCtx>,
147 ) -> Result<Result<String, types::IfaceError>>;
148
149 fn telemetry_emit(
150 &mut self,
151 span_json: String,
152 ctx: Option<types::TenantCtx>,
153 ) -> Result<()>;
154
155 fn http_fetch(
156 &mut self,
157 req: http::HttpRequest,
158 ctx: Option<types::TenantCtx>,
159 ) -> Result<Result<http::HttpResponse, types::IfaceError>>;
160
161 fn mcp_exec(
162 &mut self,
163 component: String,
164 action: String,
165 args_json: String,
166 ctx: Option<types::TenantCtx>,
167 ) -> Result<Result<String, types::IfaceError>>;
168
169 fn state_get(
170 &mut self,
171 key: iface_types::StateKey,
172 ctx: Option<types::TenantCtx>,
173 ) -> Result<Result<String, types::IfaceError>>;
174
175 fn state_set(
176 &mut self,
177 key: iface_types::StateKey,
178 value_json: String,
179 ctx: Option<types::TenantCtx>,
180 ) -> Result<Result<state::OpAck, types::IfaceError>>;
181
182 fn session_update(
183 &mut self,
184 cursor: iface_types::SessionCursor,
185 ctx: Option<types::TenantCtx>,
186 ) -> Result<Result<String, types::IfaceError>>;
187 }
188
189 pub fn add_to_linker<T>(
191 linker: &mut Linker<T>,
192 get_host: impl Fn(&mut T) -> &mut (dyn HostImports + Send + Sync + 'static)
193 + Send
194 + Sync
195 + Copy
196 + 'static,
197 ) -> Result<()>
198 where
199 T: Send + 'static,
200 {
201 let mut secrets = linker.instance("greentic:host-import/secrets@0.6.0")?;
202 secrets.func_wrap(
203 "get",
204 move |mut caller: StoreContextMut<'_, T>, (key, ctx): (String, Option<types::TenantCtx>)| {
205 let host = get_host(caller.data_mut());
206 host.secrets_get(key, ctx).map(|res| (res,))
207 },
208 )?;
209
210 let mut telemetry = linker.instance("greentic:host-import/telemetry@0.6.0")?;
211 telemetry.func_wrap(
212 "emit",
213 move |mut caller: StoreContextMut<'_, T>, (span, ctx): (String, Option<types::TenantCtx>)| {
214 let host = get_host(caller.data_mut());
215 host.telemetry_emit(span, ctx)
216 },
217 )?;
218
219 let mut http_iface = linker.instance("greentic:host-import/http@0.6.0")?;
220 http_iface.func_wrap(
221 "fetch",
222 move |mut caller: StoreContextMut<'_, T>, (req, ctx): (http::HttpRequest, Option<types::TenantCtx>)| {
223 let host = get_host(caller.data_mut());
224 host.http_fetch(req, ctx).map(|res| (res,))
225 },
226 )?;
227
228 let mut mcp_iface = linker.instance("greentic:host-import/mcp@0.6.0")?;
229 mcp_iface.func_wrap(
230 "exec",
231 move |mut caller: StoreContextMut<'_, T>,
232 (component, action, args, ctx): (String, String, String, Option<types::TenantCtx>)| {
233 let host = get_host(caller.data_mut());
234 host.mcp_exec(component, action, args, ctx).map(|res| (res,))
235 },
236 )?;
237
238 let mut state_iface = linker.instance("greentic:host-import/state@0.6.0")?;
239 state_iface.func_wrap(
240 "get",
241 move |mut caller: StoreContextMut<'_, T>,
242 (key, ctx): (iface_types::StateKey, Option<types::TenantCtx>)| {
243 let host = get_host(caller.data_mut());
244 host.state_get(key, ctx).map(|res| (res,))
245 },
246 )?;
247 state_iface.func_wrap(
248 "set",
249 move |mut caller: StoreContextMut<'_, T>,
250 (key, value, ctx): (iface_types::StateKey, String, Option<types::TenantCtx>)| {
251 let host = get_host(caller.data_mut());
252 host.state_set(key, value, ctx).map(|res| (res,))
253 },
254 )?;
255
256 let mut session_iface = linker.instance("greentic:host-import/session@0.6.0")?;
257 session_iface.func_wrap(
258 "update",
259 move |mut caller: StoreContextMut<'_, T>,
260 (cursor, ctx): (iface_types::SessionCursor, Option<types::TenantCtx>)| {
261 let host = get_host(caller.data_mut());
262 host.session_update(cursor, ctx).map(|res| (res,))
263 },
264 )?;
265
266 Ok(())
267 }
268
269 pub const PACKAGE_ID: &str = "greentic:host-import@0.6.0";
271 }
272);
273
274#[cfg(feature = "host-import-v0-4")]
275declare_world!(
276 mod host_import_v0_4,
277 path = "wit/greentic/host-import@0.4.0",
278 world = "greentic:host-import/host-imports@0.4.0",
279 legacy = {
280 use wasmtime::component::Linker;
281 use wasmtime::{Result, StoreContextMut};
282
283 pub use bindings::greentic::host_import::{http, secrets, telemetry};
284 pub use bindings::greentic::types_core::types;
285
286 pub trait HostImports {
288 fn secrets_get(
289 &mut self,
290 key: String,
291 ctx: Option<types::TenantCtx>,
292 ) -> Result<Result<String, types::IfaceError>>;
293
294 fn telemetry_emit(
295 &mut self,
296 span_json: String,
297 ctx: Option<types::TenantCtx>,
298 ) -> Result<()>;
299
300 fn http_fetch(
301 &mut self,
302 req: http::HttpRequest,
303 ctx: Option<types::TenantCtx>,
304 ) -> Result<Result<http::HttpResponse, types::IfaceError>>;
305 }
306
307 pub fn add_to_linker<T>(
309 linker: &mut Linker<T>,
310 get_host: impl Fn(&mut T) -> &mut (dyn HostImports + Send + Sync + 'static)
311 + Send
312 + Sync
313 + Copy
314 + 'static,
315 ) -> Result<()>
316 where
317 T: Send + 'static,
318 {
319 let mut secrets = linker.instance("greentic:host-import/secrets@0.4.0")?;
320 secrets.func_wrap(
321 "get",
322 move |mut caller: StoreContextMut<'_, T>, (key, ctx): (String, Option<types::TenantCtx>)| {
323 let host = get_host(caller.data_mut());
324 host.secrets_get(key, ctx).map(|res| (res,))
325 },
326 )?;
327
328 let mut telemetry = linker.instance("greentic:host-import/telemetry@0.4.0")?;
329 telemetry.func_wrap(
330 "emit",
331 move |mut caller: StoreContextMut<'_, T>, (span, ctx): (String, Option<types::TenantCtx>)| {
332 let host = get_host(caller.data_mut());
333 host.telemetry_emit(span, ctx)
334 },
335 )?;
336
337 let mut http_iface = linker.instance("greentic:host-import/http@0.4.0")?;
338 http_iface.func_wrap(
339 "fetch",
340 move |mut caller: StoreContextMut<'_, T>, (req, ctx): (http::HttpRequest, Option<types::TenantCtx>)| {
341 let host = get_host(caller.data_mut());
342 host.http_fetch(req, ctx).map(|res| (res,))
343 },
344 )?;
345
346 Ok(())
347 }
348
349 pub const PACKAGE_ID: &str = "greentic:host-import@0.4.0";
351 }
352);
353
354#[cfg(feature = "host-import-v0-2")]
355declare_world!(
356 mod host_import_v0_2,
357 path = "wit/greentic/host-import@0.2.0",
358 world = "greentic:host-import/host-imports@0.2.0",
359 legacy = {
360 use wasmtime::component::Linker;
361 use wasmtime::{Result, StoreContextMut};
362
363 pub use bindings::greentic::host_import::imports;
364
365 pub trait HostImports {
367 fn secrets_get(
368 &mut self,
369 key: String,
370 ctx: Option<imports::TenantCtx>,
371 ) -> Result<Result<String, imports::IfaceError>>;
372
373 fn telemetry_emit(
374 &mut self,
375 span_json: String,
376 ctx: Option<imports::TenantCtx>,
377 ) -> Result<()>;
378
379 fn tool_invoke(
380 &mut self,
381 tool: String,
382 action: String,
383 args_json: String,
384 ctx: Option<imports::TenantCtx>,
385 ) -> Result<Result<String, imports::IfaceError>>;
386
387 fn http_fetch(
388 &mut self,
389 req: imports::HttpRequest,
390 ctx: Option<imports::TenantCtx>,
391 ) -> Result<Result<imports::HttpResponse, imports::IfaceError>>;
392 }
393
394 pub fn add_to_linker<T>(
396 linker: &mut Linker<T>,
397 get_host: impl Fn(&mut T) -> &mut (dyn HostImports + Send + Sync + 'static)
398 + Send
399 + Sync
400 + Copy
401 + 'static,
402 ) -> Result<()>
403 where
404 T: Send + 'static,
405 {
406 let mut inst = linker.instance("greentic:host-import/host-imports@0.2.0")?;
407
408 inst.func_wrap(
409 "secrets-get",
410 move |mut caller: StoreContextMut<'_, T>,
411 (key, ctx): (String, Option<imports::TenantCtx>)| {
412 let host = get_host(caller.data_mut());
413 host.secrets_get(key, ctx).map(|res| (res,))
414 },
415 )?;
416
417 inst.func_wrap(
418 "telemetry-emit",
419 move |mut caller: StoreContextMut<'_, T>,
420 (span, ctx): (String, Option<imports::TenantCtx>)| {
421 let host = get_host(caller.data_mut());
422 host.telemetry_emit(span, ctx)
423 },
424 )?;
425
426 inst.func_wrap(
427 "tool-invoke",
428 move |
429 mut caller: StoreContextMut<'_, T>,
430 (tool, action, args, ctx): (String, String, String, Option<imports::TenantCtx>),
431 | {
432 let host = get_host(caller.data_mut());
433 host.tool_invoke(tool, action, args, ctx).map(|res| (res,))
434 },
435 )?;
436
437 inst.func_wrap(
438 "http-fetch",
439 move |mut caller: StoreContextMut<'_, T>,
440 (req, ctx): (imports::HttpRequest, Option<imports::TenantCtx>)| {
441 let host = get_host(caller.data_mut());
442 host.http_fetch(req, ctx).map(|res| (res,))
443 },
444 )?;
445
446 Ok(())
447 }
448
449 pub const PACKAGE_ID: &str = "greentic:host-import@0.2.0";
451 }
452);
453
454#[cfg(feature = "runner-host-v1")]
455declare_world!(
456 mod runner_host_v1,
457 path = "wit/greentic/host@1.0.0",
458 world = "greentic:host/runner-host@1.0.0",
459 legacy = {
460 use std::vec::Vec;
461 use wasmtime::component::Linker;
462 use wasmtime::{Result, StoreContextMut};
463
464 pub use bindings::greentic::host::{http_v1, kv_v1, secrets_v1};
465
466 pub trait RunnerHost {
468 fn http_request(
469 &mut self,
470 method: String,
471 url: String,
472 headers: Vec<String>,
473 body: Option<Vec<u8>>,
474 ) -> Result<Result<Vec<u8>, String>>;
475
476 fn secret_get(&mut self, name: String) -> Result<Result<String, String>>;
477
478 fn kv_get(&mut self, ns: String, key: String) -> Result<Option<String>>;
479
480 fn kv_put(&mut self, ns: String, key: String, val: String) -> Result<()>;
481 }
482
483 pub fn add_to_linker<T>(
485 linker: &mut Linker<T>,
486 get_host: impl Fn(&mut T) -> &mut (dyn RunnerHost + Send + Sync + 'static)
487 + Send
488 + Sync
489 + Copy
490 + 'static,
491 ) -> Result<()>
492 where
493 T: Send + 'static,
494 {
495 let mut http = linker.instance("greentic:host/http-v1@1.0.0")?;
496 http.func_wrap(
497 "request",
498 move |mut caller: StoreContextMut<'_, T>,
499 (method, url, headers, body): (String, String, Vec<String>, Option<Vec<u8>>)| {
500 let host = get_host(caller.data_mut());
501 host.http_request(method, url, headers, body)
502 .map(|res| (res,))
503 },
504 )?;
505
506 let mut secrets = linker.instance("greentic:host/secrets-v1@1.0.0")?;
507 secrets.func_wrap(
508 "get",
509 move |mut caller: StoreContextMut<'_, T>, (name,): (String,)| {
510 let host = get_host(caller.data_mut());
511 host.secret_get(name).map(|res| (res,))
512 },
513 )?;
514
515 let mut kv = linker.instance("greentic:host/kv-v1@1.0.0")?;
516 kv.func_wrap(
517 "get",
518 move |mut caller: StoreContextMut<'_, T>, (ns, key): (String, String)| {
519 let host = get_host(caller.data_mut());
520 host.kv_get(ns, key).map(|res| (res,))
521 },
522 )?;
523 kv.func_wrap(
524 "put",
525 move |mut caller: StoreContextMut<'_, T>, (ns, key, val): (String, String, String)| {
526 let host = get_host(caller.data_mut());
527 host.kv_put(ns, key, val)
528 },
529 )?;
530
531 Ok(())
532 }
533
534 pub const PACKAGE_ID: &str = "greentic:host@1.0.0";
536 }
537);
538
539#[cfg(feature = "pack-export-v0-2")]
540declare_world!(
541 mod pack_export_v0_2,
542 path = "wit/greentic/pack-export@0.2.0",
543 world = "greentic:pack-export/pack-exports@0.2.0",
544 legacy = {
545 pub const PACKAGE_ID: &str = "greentic:pack-export@0.2.0";
547 }
548);
549
550#[cfg(feature = "types-core-v0-2")]
551declare_world!(
552 mod types_core_v0_2,
553 path = "wit/greentic/types-core@0.2.0",
554 world = "greentic:types-core/core@0.2.0",
555 legacy = {
556 pub const PACKAGE_ID: &str = "greentic:types-core@0.2.0";
558 }
559);
560
561#[cfg(feature = "secrets-v0-1")]
562declare_world!(
563 mod secrets_v0_1,
564 path = "wit/greentic/secrets@0.1.0",
565 world = "greentic:secrets/host@0.1.0",
566 legacy = {
567 pub const PACKAGE_ID: &str = "greentic:secrets@0.1.0";
569
570 pub const HOST_WORLD: &str =
572 include_str!("../wit/greentic/secrets@0.1.0/package.wit");
573
574 pub fn host_world() -> &'static str {
575 HOST_WORLD
576 }
577 }
578);
579
580#[cfg(feature = "oauth-v0-1")]
581declare_world!(
582 mod oauth_v0_1,
583 path = "wit/greentic/oauth@0.1.0",
584 world = "greentic:oauth/oauth@0.1.0",
585 legacy = {
586 pub const PACKAGE_ID: &str = "greentic:oauth@0.1.0";
588 }
589);
590
591#[cfg(feature = "oauth-broker-v1")]
592declare_world!(
593 mod oauth_broker_v1,
594 path = "wit/greentic/oauth-broker@1.0.0",
595 world = "greentic:oauth-broker/broker@1.0.0",
596 legacy = {
597 pub const PACKAGE_ID: &str = "greentic:oauth-broker@1.0.0";
599 }
600);
601
602#[cfg(feature = "component-lifecycle-v1")]
603declare_world!(
604 mod component_lifecycle_v1,
605 path = "wit/greentic/lifecycle@1.0.0",
606 world = "greentic:lifecycle/component-lifecycle@1.0.0",
607 legacy = {
608 pub const PACKAGE_ID: &str = "greentic:lifecycle@1.0.0";
610 }
611);
612
613#[cfg(feature = "events-v1")]
614declare_world!(
615 mod events_v1,
616 path = "wit/greentic/events@1.0.0",
617 world = "greentic:events/events@1.0.0",
618 legacy = {
619 pub const PACKAGE_ID: &str = "greentic:events@1.0.0";
621 }
622);
623
624#[cfg(feature = "events-broker-v1")]
625declare_world!(
626 mod events_broker_v1,
627 path = "wit/greentic/events@1.0.0",
628 world = "greentic:events/broker@1.0.0",
629 legacy = {
630 pub const PACKAGE_ID: &str = "greentic:events@1.0.0";
632 }
633);
634
635#[cfg(feature = "events-source-v1")]
636declare_world!(
637 mod events_source_v1,
638 path = "wit/greentic/events@1.0.0",
639 world = "greentic:events/source@1.0.0",
640 legacy = {
641 pub const PACKAGE_ID: &str = "greentic:events@1.0.0";
643 }
644);
645
646#[cfg(feature = "events-sink-v1")]
647declare_world!(
648 mod events_sink_v1,
649 path = "wit/greentic/events@1.0.0",
650 world = "greentic:events/sink@1.0.0",
651 legacy = {
652 pub const PACKAGE_ID: &str = "greentic:events@1.0.0";
654 }
655);
656
657#[cfg(feature = "secrets-store-v1")]
658declare_world!(
659 mod secrets_store_v1,
660 path = "wit/greentic/secrets-store@1.0.0",
661 world = "greentic:secrets/store@1.0.0",
662 legacy = {
663 pub const PACKAGE_ID: &str = "greentic:secrets@1.0.0";
665 }
666);
667
668#[cfg(feature = "state-store-v1")]
669declare_world!(
670 mod state_store_v1,
671 path = "wit/greentic/state-store@1.0.0",
672 world = "greentic:state/store@1.0.0",
673 legacy = {
674 pub const PACKAGE_ID: &str = "greentic:state@1.0.0";
675 }
676);
677
678#[cfg(feature = "messaging-session-v1")]
679declare_world!(
680 mod messaging_session_v1,
681 path = "wit/greentic/messaging-session@1.0.0",
682 world = "greentic:messaging/session@1.0.0",
683 legacy = {
684 pub const PACKAGE_ID: &str = "greentic:messaging@1.0.0";
685 }
686);
687
688#[cfg(feature = "events-emitter-v1")]
689declare_world!(
690 mod events_emitter_v1,
691 path = "wit/greentic/events@1.0.0",
692 world = "greentic:events/emitter@1.0.0",
693 legacy = {
694 pub const PACKAGE_ID: &str = "greentic:events@1.0.0";
695 }
696);
697
698#[cfg(feature = "events-bridge-v1")]
699declare_world!(
700 mod events_bridge_message_to_event_v1,
701 path = "wit/greentic/events-bridge@1.0.0",
702 world = "greentic:events-bridge/message-to-event-bridge@1.0.0",
703 legacy = {
704 pub const PACKAGE_ID: &str = "greentic:events-bridge@1.0.0";
705 }
706);
707
708#[cfg(feature = "events-bridge-v1")]
709declare_world!(
710 mod events_bridge_event_to_message_v1,
711 path = "wit/greentic/events-bridge@1.0.0",
712 world = "greentic:events-bridge/event-to-message-bridge@1.0.0",
713 legacy = {
714 pub const PACKAGE_ID: &str = "greentic:events-bridge@1.0.0";
715 }
716);
717
718#[cfg(feature = "http-client-v1")]
719declare_world!(
720 mod http_client_v1,
721 path = "wit/greentic/http-client@1.0.0",
722 world = "greentic:http/client@1.0.0",
723 legacy = {
724 pub const PACKAGE_ID: &str = "greentic:http@1.0.0";
725 }
726);
727
728#[cfg(feature = "telemetry-logger-v1")]
729declare_world!(
730 mod telemetry_logger_v1,
731 path = "wit/greentic/telemetry-logger@1.0.0",
732 world = "greentic:telemetry/logger@1.0.0",
733 legacy = {
734 pub const PACKAGE_ID: &str = "greentic:telemetry@1.0.0";
735 }
736);