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