systemprompt_models/artifacts/image/
mod.rs1use crate::artifacts::metadata::ExecutionMetadata;
11use crate::artifacts::traits::Artifact;
12use crate::artifacts::types::ArtifactType;
13use crate::execution::context::RequestContext;
14use schemars::JsonSchema;
15use serde::{Deserialize, Serialize};
16use serde_json::{Value as JsonValue, json};
17use systemprompt_identifiers::SkillId;
18
19fn default_artifact_type() -> String {
20 "image".to_owned()
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
24pub struct ImageArtifact {
25 #[serde(rename = "x-artifact-type")]
26 #[serde(default = "default_artifact_type")]
27 pub artifact_type: String,
28 pub src: String,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub alt: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub caption: Option<String>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub width: Option<u32>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub height: Option<u32>,
37 #[serde(skip)]
38 #[schemars(skip)]
39 metadata: ExecutionMetadata,
40}
41
42impl ImageArtifact {
43 pub const ARTIFACT_TYPE_STR: &'static str = "image";
44
45 pub fn new(src: impl Into<String>) -> Self {
46 Self {
47 artifact_type: "image".to_owned(),
48 src: src.into(),
49 alt: None,
50 caption: None,
51 width: None,
52 height: None,
53 metadata: ExecutionMetadata::default(),
54 }
55 }
56
57 pub fn with_request(mut self, ctx: &RequestContext) -> Self {
58 self.metadata = ExecutionMetadata::with_request(ctx);
59 self
60 }
61
62 pub fn with_alt(mut self, alt: impl Into<String>) -> Self {
63 self.alt = Some(alt.into());
64 self
65 }
66
67 pub fn with_caption(mut self, caption: impl Into<String>) -> Self {
68 self.caption = Some(caption.into());
69 self
70 }
71
72 pub const fn with_dimensions(mut self, width: u32, height: u32) -> Self {
73 self.width = Some(width);
74 self.height = Some(height);
75 self
76 }
77
78 pub fn with_execution_id(mut self, id: impl Into<String>) -> Self {
79 self.metadata.execution_id = Some(id.into());
80 self
81 }
82
83 pub fn with_skill(
84 mut self,
85 skill_id: impl Into<SkillId>,
86 skill_name: impl Into<String>,
87 ) -> Self {
88 self.metadata.skill_id = Some(skill_id.into());
89 self.metadata.skill_name = Some(skill_name.into());
90 self
91 }
92}
93
94impl Artifact for ImageArtifact {
95 fn artifact_type(&self) -> ArtifactType {
96 ArtifactType::Image
97 }
98
99 fn to_schema(&self) -> JsonValue {
101 json!({
102 "type": "object",
103 "properties": {
104 "src": {
105 "type": "string",
106 "description": "Image source URL or base64 data URI"
107 },
108 "alt": {
109 "type": "string",
110 "description": "Alt text for accessibility"
111 },
112 "caption": {
113 "type": "string",
114 "description": "Caption displayed below the image"
115 },
116 "width": {
117 "type": "integer",
118 "description": "Image width in pixels"
119 },
120 "height": {
121 "type": "integer",
122 "description": "Image height in pixels"
123 }
124 },
125 "required": ["src"],
126 "x-artifact-type": "image"
127 })
128 }
129}