1use crate::schema::graph::SchemaGraph;
38use crate::schema::schema_type::SchemaType;
39use crate::schema::schema_value::SchemaValue;
40use serde::{Deserialize, Serialize};
41
42pub mod argv;
43pub mod canonical;
44pub mod compatibility;
45pub mod constraints;
46mod process_exit_status;
47pub use process_exit_status::ProcessExitStatus;
48#[cfg(feature = "full")]
49mod protobuf;
50pub mod validation;
51#[cfg(all(
52 any(feature = "guest", feature = "host"),
53 not(all(feature = "guest", feature = "host"))
54))]
55pub mod wit;
56
57#[derive(
59 Debug,
60 Clone,
61 Copy,
62 PartialEq,
63 Eq,
64 Hash,
65 PartialOrd,
66 Ord,
67 Serialize,
68 Deserialize,
69 golem_schema_derive::IntoSchema,
70 golem_schema_derive::FromSchema,
71)]
72#[cfg_attr(
73 feature = "full",
74 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
75)]
76#[cfg_attr(feature = "full", desert(transparent))]
77#[serde(transparent)]
78pub struct CommandIndex(pub i32);
79
80impl CommandIndex {
81 pub fn as_usize(self) -> Option<usize> {
83 usize::try_from(self.0).ok()
84 }
85}
86
87#[derive(
89 Debug,
90 Clone,
91 PartialEq,
92 Serialize,
93 Deserialize,
94 golem_schema_derive::IntoSchema,
95 golem_schema_derive::FromSchema,
96)]
97#[cfg_attr(
98 feature = "full",
99 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
100)]
101#[cfg_attr(feature = "full", desert(evolution()))]
102pub struct Tool {
103 pub version: String,
104 pub requires_filesystem: bool,
105 pub commands: CommandTree,
106 #[serde(default = "SchemaGraph::empty")]
115 pub schema: SchemaGraph,
116}
117
118impl Tool {
119 pub fn name(&self) -> Option<&str> {
121 self.commands.nodes.first().map(|node| node.name.as_str())
122 }
123}
124
125#[derive(
127 Debug,
128 Clone,
129 PartialEq,
130 Serialize,
131 Deserialize,
132 golem_schema_derive::IntoSchema,
133 golem_schema_derive::FromSchema,
134)]
135#[cfg_attr(
136 feature = "full",
137 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
138)]
139#[cfg_attr(feature = "full", desert(evolution()))]
140pub struct ToolMiddleware {
141 pub name: String,
142 pub version: String,
143 pub aliases: Vec<String>,
144 pub doc: Doc,
145 pub scope: ToolMiddlewareScope,
146 pub parameter_schema: SchemaGraph,
147}
148
149#[derive(
150 Debug,
151 Clone,
152 PartialEq,
153 Serialize,
154 Deserialize,
155 golem_schema_derive::IntoSchema,
156 golem_schema_derive::FromSchema,
157)]
158#[cfg_attr(
159 feature = "full",
160 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
161)]
162#[cfg_attr(feature = "full", desert(evolution()))]
163#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
164pub enum ToolMiddlewareScope {
165 Monomorphic(Box<MonomorphicToolMiddlewareScope>),
166 Universal,
167}
168
169#[derive(
170 Debug,
171 Clone,
172 PartialEq,
173 Serialize,
174 Deserialize,
175 golem_schema_derive::IntoSchema,
176 golem_schema_derive::FromSchema,
177)]
178#[cfg_attr(
179 feature = "full",
180 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
181)]
182#[cfg_attr(feature = "full", desert(evolution()))]
183pub struct MonomorphicToolMiddlewareScope {
184 pub presented: Tool,
185 pub expected: Option<Tool>,
186}
187
188#[derive(
190 Debug,
191 Clone,
192 PartialEq,
193 Serialize,
194 Deserialize,
195 golem_schema_derive::IntoSchema,
196 golem_schema_derive::FromSchema,
197)]
198#[cfg_attr(
199 feature = "full",
200 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
201)]
202#[cfg_attr(feature = "full", desert(evolution()))]
203pub struct CommandTree {
204 pub nodes: Vec<CommandNode>,
205}
206
207#[derive(
211 Debug,
212 Clone,
213 PartialEq,
214 Serialize,
215 Deserialize,
216 golem_schema_derive::IntoSchema,
217 golem_schema_derive::FromSchema,
218)]
219#[cfg_attr(
220 feature = "full",
221 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
222)]
223#[cfg_attr(feature = "full", desert(evolution()))]
224pub struct CommandNode {
225 pub name: String,
226 pub aliases: Vec<String>,
227 pub doc: Doc,
228 pub globals: Globals,
229 pub subcommands: Vec<CommandIndex>,
230 pub body: Option<CommandBody>,
231}
232
233#[derive(
234 Debug,
235 Clone,
236 PartialEq,
237 Default,
238 Serialize,
239 Deserialize,
240 golem_schema_derive::IntoSchema,
241 golem_schema_derive::FromSchema,
242)]
243#[cfg_attr(
244 feature = "full",
245 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
246)]
247#[cfg_attr(feature = "full", desert(evolution()))]
248pub struct Globals {
249 pub options: Vec<OptionSpec>,
250 pub flags: Vec<FlagSpec>,
251}
252
253#[derive(
254 Debug,
255 Clone,
256 PartialEq,
257 Serialize,
258 Deserialize,
259 golem_schema_derive::IntoSchema,
260 golem_schema_derive::FromSchema,
261)]
262#[cfg_attr(
263 feature = "full",
264 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
265)]
266#[cfg_attr(feature = "full", desert(evolution()))]
267pub struct CommandBody {
268 pub positionals: Positionals,
269 pub options: Vec<OptionSpec>,
270 pub flags: Vec<FlagSpec>,
271 pub constraints: Vec<Constraint>,
272 pub stdin: Option<StreamSpec>,
273 pub stdout: Option<StreamSpec>,
274 pub stderr: Option<StreamSpec>,
275 pub result: Option<ResultSpec>,
276 pub errors: Vec<ErrorCase>,
277 pub annotations: Option<CommandAnnotations>,
278}
279
280#[derive(
283 Debug,
284 Clone,
285 Copy,
286 PartialEq,
287 Eq,
288 Serialize,
289 Deserialize,
290 golem_schema_derive::IntoSchema,
291 golem_schema_derive::FromSchema,
292)]
293#[cfg_attr(
294 feature = "full",
295 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
296)]
297#[cfg_attr(feature = "full", desert(evolution()))]
298pub struct CommandAnnotations {
299 pub read_only: bool,
300 pub destructive: bool,
301 pub idempotent: bool,
302 pub open_world: bool,
303}
304
305#[derive(
306 Debug,
307 Clone,
308 PartialEq,
309 Default,
310 Serialize,
311 Deserialize,
312 golem_schema_derive::IntoSchema,
313 golem_schema_derive::FromSchema,
314)]
315#[cfg_attr(
316 feature = "full",
317 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
318)]
319#[cfg_attr(feature = "full", desert(evolution()))]
320pub struct Positionals {
321 pub fixed: Vec<Positional>,
322 pub tail: Option<TailPositional>,
323}
324
325#[derive(
326 Debug,
327 Clone,
328 PartialEq,
329 Serialize,
330 Deserialize,
331 golem_schema_derive::IntoSchema,
332 golem_schema_derive::FromSchema,
333)]
334#[cfg_attr(
335 feature = "full",
336 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
337)]
338#[cfg_attr(feature = "full", desert(evolution()))]
339pub struct Positional {
340 pub name: String,
341 pub doc: Doc,
342 pub value_name: Option<String>,
343 pub type_: SchemaType,
345 pub default: Option<SchemaValue>,
347 pub required: bool,
348 pub accepts_stdio: bool,
350}
351
352#[derive(
353 Debug,
354 Clone,
355 PartialEq,
356 Serialize,
357 Deserialize,
358 golem_schema_derive::IntoSchema,
359 golem_schema_derive::FromSchema,
360)]
361#[cfg_attr(
362 feature = "full",
363 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
364)]
365#[cfg_attr(feature = "full", desert(evolution()))]
366pub struct TailPositional {
367 pub name: String,
368 pub doc: Doc,
369 pub value_name: Option<String>,
370 pub item_type: SchemaType,
372 pub min: u32,
373 pub max: Option<u32>,
374 pub separator: Option<String>,
378 pub verbatim: bool,
380 pub accepts_stdio: bool,
382}
383
384#[derive(
385 Debug,
386 Clone,
387 PartialEq,
388 Serialize,
389 Deserialize,
390 golem_schema_derive::IntoSchema,
391 golem_schema_derive::FromSchema,
392)]
393#[cfg_attr(
394 feature = "full",
395 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
396)]
397#[cfg_attr(feature = "full", desert(evolution()))]
398pub struct OptionSpec {
399 pub long: String,
400 pub short: Option<char>,
401 pub aliases: Vec<String>,
402 pub doc: Doc,
403 pub value_name: Option<String>,
404 pub shape: OptionShape,
405 pub default: Option<SchemaValue>,
407 pub required: bool,
408 pub env_var: Option<String>,
409}
410
411#[derive(
412 Debug,
413 Clone,
414 PartialEq,
415 Serialize,
416 Deserialize,
417 golem_schema_derive::IntoSchema,
418 golem_schema_derive::FromSchema,
419)]
420#[cfg_attr(
421 feature = "full",
422 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
423)]
424#[cfg_attr(feature = "full", desert(evolution()))]
425#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
426pub enum OptionShape {
427 Scalar(SchemaType),
429 OptionalScalar(SchemaType),
431 RepeatableList(RepeatableListShape),
434 RepeatableMap(RepeatableMapShape),
437}
438
439#[derive(
440 Debug,
441 Clone,
442 PartialEq,
443 Serialize,
444 Deserialize,
445 golem_schema_derive::IntoSchema,
446 golem_schema_derive::FromSchema,
447)]
448#[cfg_attr(
449 feature = "full",
450 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
451)]
452#[cfg_attr(feature = "full", desert(evolution()))]
453pub struct RepeatableListShape {
454 pub repetition: Repetition,
455 pub item_type: SchemaType,
457}
458
459#[derive(
460 Debug,
461 Clone,
462 PartialEq,
463 Serialize,
464 Deserialize,
465 golem_schema_derive::IntoSchema,
466 golem_schema_derive::FromSchema,
467)]
468#[cfg_attr(
469 feature = "full",
470 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
471)]
472#[cfg_attr(feature = "full", desert(evolution()))]
473pub struct RepeatableMapShape {
474 pub repetition: Repetition,
475 pub map_type: SchemaType,
477 pub duplicate_key_policy: DuplicateKeyPolicy,
479}
480
481#[derive(
483 Debug,
484 Clone,
485 Copy,
486 PartialEq,
487 Eq,
488 Serialize,
489 Deserialize,
490 golem_schema_derive::IntoSchema,
491 golem_schema_derive::FromSchema,
492)]
493#[cfg_attr(
494 feature = "full",
495 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
496)]
497#[cfg_attr(feature = "full", desert(evolution()))]
498#[serde(rename_all = "kebab-case")]
499pub enum DuplicateKeyPolicy {
500 Reject,
502 LastWins,
504}
505
506#[derive(
507 Debug,
508 Clone,
509 Copy,
510 PartialEq,
511 Eq,
512 Serialize,
513 Deserialize,
514 golem_schema_derive::IntoSchema,
515 golem_schema_derive::FromSchema,
516)]
517#[cfg_attr(
518 feature = "full",
519 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
520)]
521#[cfg_attr(feature = "full", desert(evolution()))]
522#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
523pub enum Repetition {
524 Repeated,
526 Delimited(char),
528 Either(char),
530}
531
532#[derive(
533 Debug,
534 Clone,
535 PartialEq,
536 Serialize,
537 Deserialize,
538 golem_schema_derive::IntoSchema,
539 golem_schema_derive::FromSchema,
540)]
541#[cfg_attr(
542 feature = "full",
543 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
544)]
545#[cfg_attr(feature = "full", desert(evolution()))]
546pub struct FlagSpec {
547 pub long: String,
548 pub short: Option<char>,
549 pub aliases: Vec<String>,
550 pub doc: Doc,
551 pub shape: FlagShape,
552 pub env_var: Option<String>,
553}
554
555#[derive(
556 Debug,
557 Clone,
558 Copy,
559 PartialEq,
560 Eq,
561 Serialize,
562 Deserialize,
563 golem_schema_derive::IntoSchema,
564 golem_schema_derive::FromSchema,
565)]
566#[cfg_attr(
567 feature = "full",
568 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
569)]
570#[cfg_attr(feature = "full", desert(evolution()))]
571#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
572pub enum FlagShape {
573 BoolFlag(BoolFlagShape),
574 CountFlag(Option<u32>),
576}
577
578#[derive(
579 Debug,
580 Clone,
581 Copy,
582 PartialEq,
583 Eq,
584 Serialize,
585 Deserialize,
586 golem_schema_derive::IntoSchema,
587 golem_schema_derive::FromSchema,
588)]
589#[cfg_attr(
590 feature = "full",
591 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
592)]
593#[cfg_attr(feature = "full", desert(evolution()))]
594pub struct BoolFlagShape {
595 pub default: bool,
596 pub negatable: bool,
598}
599
600#[derive(
601 Debug,
602 Clone,
603 PartialEq,
604 Serialize,
605 Deserialize,
606 golem_schema_derive::IntoSchema,
607 golem_schema_derive::FromSchema,
608)]
609#[cfg_attr(
610 feature = "full",
611 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
612)]
613#[cfg_attr(feature = "full", desert(evolution()))]
614#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
615pub enum Ref {
616 Present(String),
617 ValueIs(ValueIsRef),
618}
619
620#[derive(
621 Debug,
622 Clone,
623 PartialEq,
624 Serialize,
625 Deserialize,
626 golem_schema_derive::IntoSchema,
627 golem_schema_derive::FromSchema,
628)]
629#[cfg_attr(
630 feature = "full",
631 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
632)]
633#[cfg_attr(feature = "full", desert(evolution()))]
634pub struct ValueIsRef {
635 pub name: String,
636 pub value: SchemaValue,
638}
639
640#[derive(
641 Debug,
642 Clone,
643 PartialEq,
644 Serialize,
645 Deserialize,
646 golem_schema_derive::IntoSchema,
647 golem_schema_derive::FromSchema,
648)]
649#[cfg_attr(
650 feature = "full",
651 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
652)]
653#[cfg_attr(feature = "full", desert(evolution()))]
654#[serde(tag = "kind", content = "value", rename_all = "kebab-case")]
655pub enum Constraint {
656 RequiresAll(Vec<Ref>),
657 AllOrNone(Vec<Ref>),
658 RequiresAny(Vec<Ref>),
659 MutexGroups(Vec<RefGroup>),
660 Implies(ImpliesC),
661 Forbids(ForbidsC),
662}
663
664#[derive(
665 Debug,
666 Clone,
667 PartialEq,
668 Serialize,
669 Deserialize,
670 golem_schema_derive::IntoSchema,
671 golem_schema_derive::FromSchema,
672)]
673#[cfg_attr(
674 feature = "full",
675 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
676)]
677#[cfg_attr(feature = "full", desert(evolution()))]
678pub struct RefGroup {
679 pub refs: Vec<Ref>,
680}
681
682#[derive(
683 Debug,
684 Clone,
685 PartialEq,
686 Serialize,
687 Deserialize,
688 golem_schema_derive::IntoSchema,
689 golem_schema_derive::FromSchema,
690)]
691#[cfg_attr(
692 feature = "full",
693 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
694)]
695#[cfg_attr(feature = "full", desert(evolution()))]
696pub struct ImpliesC {
697 pub lhs_quant: Quantifier,
698 pub lhs: Vec<Ref>,
699 pub rhs_quant: Quantifier,
700 pub rhs: Vec<Ref>,
701}
702
703#[derive(
704 Debug,
705 Clone,
706 PartialEq,
707 Serialize,
708 Deserialize,
709 golem_schema_derive::IntoSchema,
710 golem_schema_derive::FromSchema,
711)]
712#[cfg_attr(
713 feature = "full",
714 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
715)]
716#[cfg_attr(feature = "full", desert(evolution()))]
717pub struct ForbidsC {
718 pub lhs_quant: Quantifier,
719 pub lhs: Vec<Ref>,
720 pub rhs: Vec<Ref>,
721}
722
723#[derive(
724 Debug,
725 Clone,
726 Copy,
727 PartialEq,
728 Eq,
729 Serialize,
730 Deserialize,
731 golem_schema_derive::IntoSchema,
732 golem_schema_derive::FromSchema,
733)]
734#[cfg_attr(
735 feature = "full",
736 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
737)]
738#[cfg_attr(feature = "full", desert(evolution()))]
739#[serde(rename_all = "kebab-case")]
740pub enum Quantifier {
741 All,
742 Any,
743}
744
745#[derive(
746 Debug,
747 Clone,
748 PartialEq,
749 Eq,
750 Serialize,
751 Deserialize,
752 golem_schema_derive::IntoSchema,
753 golem_schema_derive::FromSchema,
754)]
755#[cfg_attr(
756 feature = "full",
757 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
758)]
759#[cfg_attr(feature = "full", desert(evolution()))]
760pub struct StreamSpec {
761 pub doc: Doc,
762 pub mime: Vec<String>,
763 pub required: bool,
764}
765
766#[derive(
767 Debug,
768 Clone,
769 PartialEq,
770 Serialize,
771 Deserialize,
772 golem_schema_derive::IntoSchema,
773 golem_schema_derive::FromSchema,
774)]
775#[cfg_attr(
776 feature = "full",
777 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
778)]
779#[cfg_attr(feature = "full", desert(evolution()))]
780#[serde(rename = "ToolResultSpec")]
781pub struct ResultSpec {
782 pub type_: SchemaType,
784 pub doc: Doc,
785 pub formatters: Vec<Formatter>,
786 pub default_formatter: String,
787}
788
789#[derive(
790 Debug,
791 Clone,
792 PartialEq,
793 Eq,
794 Serialize,
795 Deserialize,
796 golem_schema_derive::IntoSchema,
797 golem_schema_derive::FromSchema,
798)]
799#[cfg_attr(
800 feature = "full",
801 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
802)]
803#[cfg_attr(feature = "full", desert(evolution()))]
804pub struct Formatter {
805 pub name: String,
806 pub doc: Doc,
807}
808
809#[derive(
810 Debug,
811 Clone,
812 PartialEq,
813 Serialize,
814 Deserialize,
815 golem_schema_derive::IntoSchema,
816 golem_schema_derive::FromSchema,
817)]
818#[cfg_attr(
819 feature = "full",
820 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
821)]
822#[cfg_attr(feature = "full", desert(evolution()))]
823pub struct ErrorCase {
824 pub name: String,
825 pub doc: Doc,
826 pub kind: ErrorKind,
827 pub exit_code: u8,
828 pub payload: Option<SchemaType>,
830}
831
832#[derive(
833 Debug,
834 Clone,
835 Copy,
836 PartialEq,
837 Eq,
838 Serialize,
839 Deserialize,
840 golem_schema_derive::IntoSchema,
841 golem_schema_derive::FromSchema,
842)]
843#[cfg_attr(
844 feature = "full",
845 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
846)]
847#[cfg_attr(feature = "full", desert(evolution()))]
848#[serde(rename_all = "kebab-case")]
849pub enum ErrorKind {
850 UsageError,
851 RuntimeError,
852}
853
854#[derive(
855 Debug,
856 Clone,
857 PartialEq,
858 Eq,
859 Default,
860 Serialize,
861 Deserialize,
862 golem_schema_derive::IntoSchema,
863 golem_schema_derive::FromSchema,
864)]
865#[cfg_attr(
866 feature = "full",
867 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
868)]
869#[cfg_attr(feature = "full", desert(evolution()))]
870pub struct Doc {
871 pub summary: String,
872 pub description: String,
873 pub examples: Vec<Example>,
874}
875
876#[derive(
877 Debug,
878 Clone,
879 PartialEq,
880 Eq,
881 Serialize,
882 Deserialize,
883 golem_schema_derive::IntoSchema,
884 golem_schema_derive::FromSchema,
885)]
886#[cfg_attr(
887 feature = "full",
888 derive(desert_rust::BinaryCodec, golem_schema_derive::PoemSchema)
889)]
890#[cfg_attr(feature = "full", desert(evolution()))]
891pub struct Example {
892 pub title: String,
893 pub body: String,
894}