rig_compose/
instructions.rs1use serde::{Deserialize, Serialize};
13use serde_json::Value;
14
15#[derive(Debug, Clone, Default, Serialize, Deserialize)]
17pub struct Instructions {
18 pub system_prompt: String,
20 pub response_schema: Option<Value>,
24 pub examples: Vec<(String, String)>,
27 pub metadata: Value,
30}
31
32impl Instructions {
33 pub fn new(system_prompt: impl Into<String>) -> Self {
34 Self {
35 system_prompt: system_prompt.into(),
36 response_schema: None,
37 examples: Vec::new(),
38 metadata: Value::Null,
39 }
40 }
41
42 pub fn with_response_schema(mut self, schema: Value) -> Self {
43 self.response_schema = Some(schema);
44 self
45 }
46
47 pub fn with_example(mut self, user: impl Into<String>, assistant: impl Into<String>) -> Self {
48 self.examples.push((user.into(), assistant.into()));
49 self
50 }
51
52 pub fn with_metadata(mut self, metadata: Value) -> Self {
53 self.metadata = metadata;
54 self
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use serde_json::json;
62
63 #[test]
64 fn builder_chains() {
65 let i = Instructions::new("you are a detector")
66 .with_response_schema(json!({"type": "object"}))
67 .with_example("hi", "hello")
68 .with_metadata(json!({"model": "x"}));
69 assert_eq!(i.system_prompt, "you are a detector");
70 assert!(i.response_schema.is_some());
71 assert_eq!(i.examples.len(), 1);
72 assert_eq!(i.metadata["model"], "x");
73 }
74
75 #[test]
76 fn round_trips_serde() {
77 let i = Instructions::new("x").with_example("a", "b");
78 let s = serde_json::to_string(&i).unwrap();
79 let back: Instructions = serde_json::from_str(&s).unwrap();
80 assert_eq!(back.examples.len(), 1);
81 }
82}