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//!
7//! Copyright (c) systemprompt.io — Business Source License 1.1.
8//! See <https://systemprompt.io> for licensing details.
9
10use 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    "text".to_owned()
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
24pub struct TextArtifact {
25    #[serde(rename = "x-artifact-type")]
26    #[serde(default = "default_artifact_type")]
27    pub artifact_type: String,
28    pub content: String,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub title: Option<String>,
31    #[serde(skip)]
32    #[schemars(skip)]
33    metadata: ExecutionMetadata,
34}
35
36impl TextArtifact {
37    pub const ARTIFACT_TYPE_STR: &'static str = "text";
38
39    pub fn new(content: impl Into<String>) -> Self {
40        Self {
41            artifact_type: "text".to_owned(),
42            content: content.into(),
43            title: None,
44            metadata: ExecutionMetadata::default(),
45        }
46    }
47
48    pub fn with_request(mut self, ctx: &RequestContext) -> Self {
49        self.metadata = ExecutionMetadata::with_request(ctx);
50        self
51    }
52
53    pub fn with_title(mut self, title: impl Into<String>) -> Self {
54        self.title = Some(title.into());
55        self
56    }
57
58    pub fn with_execution_id(mut self, id: impl Into<String>) -> Self {
59        self.metadata.execution_id = Some(id.into());
60        self
61    }
62
63    pub fn with_skill(
64        mut self,
65        skill_id: impl Into<SkillId>,
66        skill_name: impl Into<String>,
67    ) -> Self {
68        self.metadata.skill_id = Some(skill_id.into());
69        self.metadata.skill_name = Some(skill_name.into());
70        self
71    }
72}
73
74impl Artifact for TextArtifact {
75    fn artifact_type(&self) -> ArtifactType {
76        ArtifactType::Text
77    }
78
79    fn to_schema(&self) -> JsonValue {
80        json!({
81            "type": "object",
82            "properties": {
83                "content": {
84                    "type": "string",
85                    "description": "Text content"
86                },
87                "title": {
88                    "type": "string",
89                    "description": "Optional title for the text"
90                }
91            },
92            "required": ["content"],
93            "x-artifact-type": "text"
94        })
95    }
96}