aion_integrations/spec.rs
1//! The neutral run identity handed to a harness at [`crate::AgentHarness::start`].
2
3use aion_core::{ActivityId, Payload, WorkflowId};
4
5/// The neutral identity + input for one agent run (one activity attempt).
6///
7/// Carries only what every harness needs to run an attempt: the `(workflow, activity, attempt)`
8/// key, the activity-type name the engine dispatched, and the input [`Payload`]. It names **no**
9/// harness-specific configuration — an adapter holds any harness-specific settings itself
10/// (constructed when the [`crate::AgentHarness`] is built), keeping this spec harness-blind.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct AgentRunSpec {
13 /// The workflow this activity attempt belongs to.
14 pub workflow_id: WorkflowId,
15 /// The activity within the workflow.
16 pub activity_id: ActivityId,
17 /// The attempt number of the activity being run.
18 pub attempt: u32,
19 /// The activity-type name the engine dispatched to this run (e.g. `"dev"`).
20 ///
21 /// Neutral run identity, not harness configuration: it is the same type name the workflow
22 /// definition routed on, so an adapter can label or parameterise a run by what the engine
23 /// asked for without the spec learning anything harness-specific.
24 pub activity_type: String,
25 /// The activity input handed to the agent.
26 pub input: Payload,
27}
28
29impl AgentRunSpec {
30 /// Builds a run spec from the neutral run identity and input payload.
31 #[must_use]
32 pub fn new(
33 workflow_id: WorkflowId,
34 activity_id: ActivityId,
35 attempt: u32,
36 activity_type: impl Into<String>,
37 input: Payload,
38 ) -> Self {
39 Self {
40 workflow_id,
41 activity_id,
42 attempt,
43 activity_type: activity_type.into(),
44 input,
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use aion_core::{ActivityId, ContentType, Payload, WorkflowId};
52
53 use super::AgentRunSpec;
54
55 #[test]
56 fn spec_carries_run_identity_and_input() {
57 let workflow_id = WorkflowId::new_v4();
58 let activity_id = ActivityId::from_sequence_position(4);
59 let input = Payload::new(ContentType::Json, b"{}".to_vec());
60
61 let spec = AgentRunSpec::new(
62 workflow_id.clone(),
63 activity_id.clone(),
64 2,
65 "dev",
66 input.clone(),
67 );
68
69 assert_eq!(spec.workflow_id, workflow_id);
70 assert_eq!(spec.activity_id, activity_id);
71 assert_eq!(spec.attempt, 2);
72 assert_eq!(spec.activity_type, "dev");
73 assert_eq!(spec.input, input);
74 }
75}