Skip to main content

greentic_flow/
model.rs

1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use std::collections::BTreeMap;
5
6fn default_parameters() -> Value {
7    Value::Object(Default::default())
8}
9
10fn default_entrypoints() -> IndexMap<String, Value> {
11    IndexMap::new()
12}
13
14fn default_routing() -> Value {
15    Value::Array(Vec::new())
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct FlowDoc {
20    pub id: String,
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub title: Option<String>,
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub description: Option<String>,
25    #[serde(rename = "type")]
26    pub flow_type: String,
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub start: Option<String>,
29    #[serde(default = "default_parameters")]
30    pub parameters: Value,
31    #[serde(default)]
32    pub tags: Vec<String>,
33    #[serde(default)]
34    pub schema_version: Option<u32>,
35    #[serde(default = "default_entrypoints")]
36    pub entrypoints: IndexMap<String, Value>,
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub meta: Option<Value>,
39    /// Slot definitions for utterance-driven prefill. Free-form `Value` to
40    /// avoid coupling greentic-flow to a specific extractor crate; expected
41    /// to be a JSON array of `SlotDefinition` objects matching the
42    /// `component-slot-extractor` wire shape (`name`, `slot_type`,
43    /// `pattern?`, `required`, `enum_values?`, `default_value?`).
44    /// Consumed by the canonical M2 chain: Fast2Flow `Dispatch{utterance}`
45    /// → slot-extractor node (utterance + this schema) → adaptive-card node
46    /// with `prefill = extractor output`.
47    #[serde(default, skip_serializing_if = "Option::is_none")]
48    pub slot_schema: Option<Value>,
49    pub nodes: IndexMap<String, NodeDoc>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, Default)]
53pub struct NodeDoc {
54    #[serde(default = "default_routing")]
55    pub routing: Value,
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub telemetry: Option<TelemetryDoc>,
58    #[serde(skip_serializing, skip_deserializing, default)]
59    pub operation: Option<String>,
60    #[serde(skip_serializing, skip_deserializing, default)]
61    pub payload: Value,
62    #[serde(flatten, default)]
63    pub raw: IndexMap<String, Value>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, Default)]
67pub struct TelemetryDoc {
68    #[serde(default)]
69    pub span_name: Option<String>,
70    #[serde(default)]
71    pub attributes: BTreeMap<String, String>,
72    #[serde(default)]
73    pub sampling: Option<String>,
74}