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