starweaver_runtime/output/
policy.rs1use std::sync::Arc;
2
3use starweaver_model::OutputMode;
4
5use super::{OutputFunction, OutputSchema, OutputValidator};
6
7pub type DynOutputFunction = Arc<dyn OutputFunction>;
9
10pub type OutputPolicyParts = (
12 Option<OutputSchema>,
13 Vec<Arc<dyn OutputValidator>>,
14 Vec<DynOutputFunction>,
15 Option<usize>,
16 Option<OutputMode>,
17 Option<bool>,
18 Option<bool>,
19);
20
21#[derive(Clone, Default)]
23pub struct OutputPolicy {
24 schema: Option<OutputSchema>,
25 validators: Vec<Arc<dyn OutputValidator>>,
26 functions: Vec<DynOutputFunction>,
27 retries: Option<usize>,
28 mode: Option<OutputMode>,
29 allow_text_output: Option<bool>,
30 allow_image_output: Option<bool>,
31}
32
33impl OutputPolicy {
34 #[must_use]
36 pub fn new() -> Self {
37 Self::default()
38 }
39
40 #[must_use]
42 pub fn structured(schema: OutputSchema) -> Self {
43 Self::new().with_schema(schema)
44 }
45
46 #[must_use]
48 pub fn typed<T>() -> Self
49 where
50 T: schemars::JsonSchema,
51 {
52 Self::structured(OutputSchema::typed::<T>())
53 }
54
55 #[must_use]
57 pub fn typed_named<T>(name: impl Into<String>) -> Self
58 where
59 T: schemars::JsonSchema,
60 {
61 Self::structured(OutputSchema::typed_named::<T>(name))
62 }
63
64 #[must_use]
66 pub fn text() -> Self {
67 Self::new().with_mode(OutputMode::Text)
68 }
69
70 #[must_use]
72 pub fn auto(schema: OutputSchema) -> Self {
73 Self::structured(schema).with_mode(OutputMode::Auto)
74 }
75
76 #[must_use]
78 pub fn native_json_schema(schema: OutputSchema) -> Self {
79 Self::structured(schema).with_mode(OutputMode::NativeJsonSchema)
80 }
81
82 #[must_use]
84 pub fn native_json_object(schema: OutputSchema) -> Self {
85 Self::structured(schema).with_mode(OutputMode::NativeJsonObject)
86 }
87
88 #[must_use]
90 pub fn tool(schema: OutputSchema) -> Self {
91 Self::structured(schema).with_mode(OutputMode::Tool)
92 }
93
94 #[must_use]
96 pub fn tool_or_text(schema: OutputSchema) -> Self {
97 Self::structured(schema)
98 .with_mode(OutputMode::ToolOrText)
99 .allow_text_output(true)
100 }
101
102 #[must_use]
104 pub fn prompted(schema: OutputSchema) -> Self {
105 Self::structured(schema).with_mode(OutputMode::Prompted)
106 }
107
108 #[must_use]
110 pub fn image() -> Self {
111 Self::new()
112 .with_mode(OutputMode::Image)
113 .allow_image_output(true)
114 .allow_text_output(false)
115 }
116
117 #[must_use]
119 pub fn with_schema(mut self, schema: OutputSchema) -> Self {
120 self.schema = Some(schema);
121 self
122 }
123
124 #[must_use]
126 pub const fn with_mode(mut self, mode: OutputMode) -> Self {
127 self.mode = Some(mode);
128 self
129 }
130
131 #[must_use]
133 pub const fn allow_text_output(mut self, allow: bool) -> Self {
134 self.allow_text_output = Some(allow);
135 self
136 }
137
138 #[must_use]
140 pub const fn allow_image_output(mut self, allow: bool) -> Self {
141 self.allow_image_output = Some(allow);
142 self
143 }
144
145 #[must_use]
147 pub fn with_validator(mut self, validator: Arc<dyn OutputValidator>) -> Self {
148 self.validators.push(validator);
149 self
150 }
151
152 #[must_use]
154 pub fn with_function(mut self, function: DynOutputFunction) -> Self {
155 self.functions.push(function);
156 self
157 }
158
159 #[must_use]
161 pub const fn with_retries(mut self, retries: usize) -> Self {
162 self.retries = Some(retries);
163 self
164 }
165
166 #[must_use]
168 pub const fn schema(&self) -> Option<&OutputSchema> {
169 self.schema.as_ref()
170 }
171
172 #[must_use]
174 pub fn validators(&self) -> &[Arc<dyn OutputValidator>] {
175 &self.validators
176 }
177
178 #[must_use]
180 pub fn functions(&self) -> &[DynOutputFunction] {
181 &self.functions
182 }
183
184 #[must_use]
186 pub const fn retries(&self) -> Option<usize> {
187 self.retries
188 }
189
190 #[must_use]
192 pub const fn mode(&self) -> Option<OutputMode> {
193 self.mode
194 }
195
196 #[must_use]
198 pub const fn text_output_allowed(&self) -> Option<bool> {
199 self.allow_text_output
200 }
201
202 #[must_use]
204 pub const fn image_output_allowed(&self) -> Option<bool> {
205 self.allow_image_output
206 }
207
208 pub(crate) fn into_parts(self) -> OutputPolicyParts {
209 (
210 self.schema,
211 self.validators,
212 self.functions,
213 self.retries,
214 self.mode,
215 self.allow_text_output,
216 self.allow_image_output,
217 )
218 }
219}