portalis_packaging/
lib.rs1use async_trait::async_trait;
6use portalis_core::{Agent, AgentCapability, AgentId, ArtifactMetadata, Result};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct PackagingInput {
11 pub wasm_bytes: Vec<u8>,
12 pub test_results: serde_json::Value,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct PackagingOutput {
17 pub package_bytes: Vec<u8>,
18 pub manifest: serde_json::Value,
19 pub metadata: ArtifactMetadata,
20}
21
22pub struct PackagingAgent {
23 id: AgentId,
24}
25
26impl PackagingAgent {
27 pub fn new() -> Self {
28 Self { id: AgentId::new() }
29 }
30}
31
32impl Default for PackagingAgent {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38#[async_trait]
39impl Agent for PackagingAgent {
40 type Input = PackagingInput;
41 type Output = PackagingOutput;
42
43 async fn execute(&self, input: Self::Input) -> Result<Self::Output> {
44 tracing::info!("Packaging WASM artifact");
45
46 let manifest = serde_json::json!({
47 "version": "0.1.0",
48 "wasm_size": input.wasm_bytes.len(),
49 "test_results": input.test_results,
50 });
51
52 let metadata = ArtifactMetadata::new(self.name())
53 .with_tag("size", input.wasm_bytes.len().to_string());
54
55 Ok(PackagingOutput {
56 package_bytes: input.wasm_bytes,
57 manifest,
58 metadata,
59 })
60 }
61
62 fn id(&self) -> AgentId {
63 self.id
64 }
65
66 fn name(&self) -> &str {
67 "PackagingAgent"
68 }
69
70 fn capabilities(&self) -> Vec<AgentCapability> {
71 vec![AgentCapability::Packaging]
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use serde_json::json;
79
80 #[tokio::test]
81 async fn test_package_creation() {
82 let agent = PackagingAgent::new();
83
84 let wasm_bytes = vec![0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00];
85 let test_results = json!({
86 "passed": 5,
87 "failed": 0
88 });
89
90 let input = PackagingInput {
91 wasm_bytes: wasm_bytes.clone(),
92 test_results,
93 };
94
95 let output = agent.execute(input).await.unwrap();
96
97 assert_eq!(output.package_bytes, wasm_bytes);
98 assert_eq!(output.manifest["version"], "0.1.0");
99 assert_eq!(output.manifest["wasm_size"], 8);
100 }
101
102 #[tokio::test]
103 async fn test_package_includes_test_results() {
104 let agent = PackagingAgent::new();
105
106 let test_results = json!({
107 "passed": 3,
108 "failed": 1
109 });
110
111 let input = PackagingInput {
112 wasm_bytes: vec![0x00; 100],
113 test_results: test_results.clone(),
114 };
115
116 let output = agent.execute(input).await.unwrap();
117
118 assert_eq!(output.manifest["test_results"], test_results);
119 assert_eq!(output.manifest["wasm_size"], 100);
120 }
121
122 #[test]
123 fn test_agent_metadata() {
124 let agent = PackagingAgent::new();
125
126 assert_eq!(agent.name(), "PackagingAgent");
127 assert_eq!(agent.capabilities(), vec![AgentCapability::Packaging]);
128 }
129}