archetype flows behave like the built-ins: switch off per archetype or per agent, board cards, duplicate
The document's disabled list takes archetype:<archetype>/<flow> (off for every member) and the same with @<agent> (off for one member); a key naming nothing is ignored. GET /api/notify/flows lists the archetype flows with their members, the board draws a card for each with a switch, a checkbox per agent and duplicate, and the dry run counts their hits. The flows keep following the archetype.
This commit is contained in:
parent
1efbb72fdd
commit
68c24643f6
1 changed files with 908 additions and 102 deletions
|
|
@ -9,11 +9,12 @@
|
|||
//! result here, so the create screen lists archetypes from a value that a
|
||||
//! create would accept.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use swarm_wire::agent_archetype::ArchetypeRef;
|
||||
use swarm_wire::agent_inference::AgentInference;
|
||||
use swarm_wire::agent_limits::AgentCaps;
|
||||
use swarm_wire::notify_flows::Flow;
|
||||
use swarm_wire::notify_flows::{Flow, archetype_flow_key};
|
||||
|
||||
/// The KV bucket archetype sources are published into, keyed by source name.
|
||||
pub const BUCKET: &str = "agent-archetypes";
|
||||
|
|
@ -70,6 +71,67 @@ pub struct ArchetypeMeta {
|
|||
pub flows: Vec<Flow>,
|
||||
}
|
||||
|
||||
/// One flow an archetype carries, with the agents of that archetype.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ArchetypeFlow {
|
||||
pub archetype: String,
|
||||
/// As the archetype declares it, under its own `id`.
|
||||
pub flow: Flow,
|
||||
/// The agents whose archetype this is, by name.
|
||||
pub members: Vec<String>,
|
||||
}
|
||||
|
||||
impl ArchetypeFlow {
|
||||
/// The name the flow goes by, see [`archetype_flow_key`].
|
||||
#[must_use]
|
||||
pub fn key(&self) -> String {
|
||||
archetype_flow_key(&self.archetype, &self.flow.id)
|
||||
}
|
||||
}
|
||||
|
||||
/// The flows to run: each enabled flow of each archetype that has an agent
|
||||
/// in `refs` (agent to archetype), with those agents, and why any flow was
|
||||
/// left out. A flow that fails [`Flow::validate_archetype`] or repeats an id
|
||||
/// of its archetype is left out.
|
||||
#[must_use]
|
||||
pub fn flows_of(
|
||||
refs: &BTreeMap<String, ArchetypeRef>,
|
||||
records: &BTreeMap<String, SourceRecord>,
|
||||
) -> (Vec<ArchetypeFlow>, Vec<String>) {
|
||||
let mut agents: BTreeMap<(&str, &str), Vec<String>> = BTreeMap::new();
|
||||
for (agent, r) in refs {
|
||||
agents
|
||||
.entry((r.source.as_str(), r.name.as_str()))
|
||||
.or_default()
|
||||
.push(agent.clone());
|
||||
}
|
||||
let mut active = Vec::new();
|
||||
let mut skipped = Vec::new();
|
||||
for ((source, name), members) in agents {
|
||||
let Some(meta) = records
|
||||
.get(source)
|
||||
.and_then(|record| record.archetypes.get(name))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let mut ids = BTreeSet::new();
|
||||
for flow in meta.flows.iter().filter(|f| f.enabled) {
|
||||
if !ids.insert(flow.id.as_str()) {
|
||||
skipped.push(format!("{name}: flow {}: its id is used twice", flow.id));
|
||||
} else if let Err(why) = flow.validate_archetype() {
|
||||
skipped.push(format!("{name}: flow {}: {why}", flow.id));
|
||||
} else {
|
||||
active.push(ArchetypeFlow {
|
||||
archetype: name.to_owned(),
|
||||
flow: flow.clone(),
|
||||
members: members.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
(active, skipped)
|
||||
}
|
||||
|
||||
/// Open the archetype bucket for writing, creating it if nothing has yet.
|
||||
///
|
||||
/// **Controller-side only.** `history: 1`: a reader wants the current value.
|
||||
|
|
|
|||
Loading…
Reference in a new issue