Skip to main content

systemprompt_models/artifacts/text/
mod.rs

1//! Text artifact: a titled block of free-form text returned by skills and
2//! tools.
3//!
4//! [`TextArtifact`] is the builder-style producer carrying optional title and
5//! execution metadata.
6
7use 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    "text".to_owned()
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
21pub struct TextArtifact {
22    #[serde(rename = "x-artifact-type")]
23    #[serde(default = "default_artifact_type")]
24    pub artifact_type: String,
25    pub content: String,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub title: Option<String>,
28    #[serde(skip)]
29    #[schemars(skip)]
30    metadata: ExecutionMetadata,
31}
32
33impl TextArtifact {
34    pub const ARTIFACT_TYPE_STR: &'static str = "text";
35
36    pub fn new(content: impl Into<String>) -> Self {
37        Self {
38            artifact_type: "text".to_owned(),
39            content: content.into(),
40            title: None,
41            metadata: ExecutionMetadata::default(),
42        }
43    }
44
45    pub fn with_request(mut self, ctx: &RequestContext) -> Self {
46        self.metadata = ExecutionMetadata::with_request(ctx);
47        self
48    }
49
50    pub fn with_title(mut self, title: impl Into<String>) -> Self {
51        self.title = Some(title.into());
52        self
53    }
54
55    pub fn with_execution_id(mut self, id: impl Into<String>) -> Self {
56        self.metadata.execution_id = Some(id.into());
57        self
58    }
59
60    pub fn with_skill(
61        mut self,
62        skill_id: impl Into<SkillId>,
63        skill_name: impl Into<String>,
64    ) -> Self {
65        self.metadata.skill_id = Some(skill_id.into());
66        self.metadata.skill_name = Some(skill_name.into());
67        self
68    }
69}
70
71impl Artifact for TextArtifact {
72    fn artifact_type(&self) -> ArtifactType {
73        ArtifactType::Text
74    }
75
76    fn to_schema(&self) -> JsonValue {
77        json!({
78            "type": "object",
79            "properties": {
80                "content": {
81                    "type": "string",
82                    "description": "Text content"
83                },
84                "title": {
85                    "type": "string",
86                    "description": "Optional title for the text"
87                }
88            },
89            "required": ["content"],
90            "x-artifact-type": "text"
91        })
92    }
93}