Skip to main content

artificial_types/fragments/
static_fragment.rs

1//! A minimal fragment that injects a *static* string into the prompt.
2//!
3//! Use this when you have pre-determined text (role description, safety
4//! notice, system instruction …) that never changes between invocations.
5//!
6//! ```rust
7//! use artificial_types::fragments::StaticFragment;
8//! use artificial_core::generic::GenericRole;
9//!
10//! let sys_msg = StaticFragment::new(
11//!     "You are a multilingual proof-reading engine.",
12//!     GenericRole::System,
13//! );
14//! ```
15//!
16//! # Why a dedicated type?
17//!
18//! 1. It keeps the [`IntoPrompt`] API symmetrical – every fragment, no matter
19//!    how simple, implements the same trait.
20//! 2. You can attach metadata (`role`) so the provider sees the correct
21//!    message type without manual wrapping.
22//! 3. Unlike `&'static str`, this struct can carry a *borrowed* slice with
23//!    lifetime `'a`, allowing the caller to reference larger inline strings
24//!    without `String` allocation.
25//!
26//! The `From<&str>` blanket impl defaults to `GenericRole::System` for
27//! convenience since system messages are the most common static fragments.
28
29use artificial_core::{
30    generic::{GenericMessage, GenericRole},
31    template::IntoPrompt,
32};
33
34/// A borrowed static string bundled with an LLM chat role.
35///
36/// The tuple struct keeps the footprint at *exactly two machine words*
37/// (`&str` + `GenericRole`) while still offering ergonomic constructors.
38pub struct StaticFragment<'a>((&'a str, GenericRole));
39
40/// Shorthand so you can write `StaticFragment::from("…")` without specifying
41/// the role each time.  Defaults to **system**.
42impl<'a> From<&'a str> for StaticFragment<'a> {
43    fn from(value: &'a str) -> Self {
44        Self((value, GenericRole::System))
45    }
46}
47
48impl<'a> StaticFragment<'a> {
49    /// Create a new fragment with explicit role.
50    pub fn new(value: &'a str, role: GenericRole) -> Self {
51        Self((value, role))
52    }
53}
54
55impl IntoPrompt for StaticFragment<'_> {
56    type Message = GenericMessage;
57
58    fn into_prompt(self) -> Vec<Self::Message> {
59        vec![GenericMessage::new(self.0.0.to_string(), self.0.1)]
60    }
61}