1use crate::Embeddings;
7use crate::node::{Chunk, Node};
8use crate::{
9 SparseEmbeddings, indexing_defaults::IndexingDefaults, indexing_stream::IndexingStream,
10};
11use std::fmt::Debug;
12use std::sync::Arc;
13
14use crate::chat_completion::errors::LanguageModelError;
15use crate::prompt::Prompt;
16use anyhow::Result;
17use async_trait::async_trait;
18
19pub use dyn_clone::DynClone;
20#[cfg(feature = "test-utils")]
22#[doc(hidden)]
23use mockall::{mock, predicate::str};
24use schemars::{JsonSchema, schema_for};
25use serde::de::DeserializeOwned;
26
27#[async_trait]
28pub trait Transformer: Send + Sync + DynClone {
30 type Input: Chunk;
31 type Output: Chunk;
32
33 async fn transform_node(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>>;
34
35 fn concurrency(&self) -> Option<usize> {
37 None
38 }
39
40 fn name(&self) -> &'static str {
41 let name = std::any::type_name::<Self>();
42 name.split("::").last().unwrap_or(name)
43 }
44}
45
46dyn_clone::clone_trait_object!(<I, O> Transformer<Input = I, Output = O>);
47
48#[cfg(feature = "test-utils")]
49mock! {
50 #[derive(Debug)]
51 pub Transformer {}
52
53 #[async_trait]
54 impl Transformer for Transformer {
55 type Input = String;
56 type Output = String;
57
58 async fn transform_node(&self, node: Node<String>) -> Result<Node<String>>;
59 fn concurrency(&self) -> Option<usize>;
60 fn name(&self) -> &'static str;
61 }
62
63 impl Clone for Transformer {
64 fn clone(&self) -> Self;
65 }
66}
67
68#[async_trait]
69impl<I: Chunk, O: Chunk> Transformer for Box<dyn Transformer<Input = I, Output = O>> {
70 type Input = I;
71 type Output = O;
72
73 async fn transform_node(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>> {
74 self.as_ref().transform_node(node).await
75 }
76 fn concurrency(&self) -> Option<usize> {
77 self.as_ref().concurrency()
78 }
79 fn name(&self) -> &'static str {
80 self.as_ref().name()
81 }
82}
83
84#[async_trait]
85impl<I: Chunk, O: Chunk> Transformer for Arc<dyn Transformer<Input = I, Output = O>> {
86 type Input = I;
87 type Output = O;
88
89 async fn transform_node(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>> {
90 self.as_ref().transform_node(node).await
91 }
92 fn concurrency(&self) -> Option<usize> {
93 self.as_ref().concurrency()
94 }
95 fn name(&self) -> &'static str {
96 self.as_ref().name()
97 }
98}
99
100#[async_trait]
101impl<I: Chunk, O: Chunk> Transformer for &dyn Transformer<Input = I, Output = O> {
102 type Input = I;
103 type Output = O;
104
105 async fn transform_node(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>> {
106 (*self).transform_node(node).await
107 }
108 fn concurrency(&self) -> Option<usize> {
109 (*self).concurrency()
110 }
111}
112
113#[async_trait]
114impl<F> Transformer for F
117where
118 F: Fn(Node<String>) -> Result<Node<String>> + Send + Sync + Clone,
119{
120 type Input = String;
121 type Output = String;
122
123 async fn transform_node(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>> {
124 self(node)
125 }
126}
127
128#[async_trait]
129pub trait BatchableTransformer: Send + Sync + DynClone {
131 type Input: Chunk;
132 type Output: Chunk;
133
134 async fn batch_transform(&self, nodes: Vec<Node<Self::Input>>) -> IndexingStream<Self::Output>;
136
137 fn concurrency(&self) -> Option<usize> {
139 None
140 }
141
142 fn name(&self) -> &'static str {
143 let name = std::any::type_name::<Self>();
144 name.split("::").last().unwrap_or(name)
145 }
146
147 fn batch_size(&self) -> Option<usize> {
149 None
150 }
151}
152
153dyn_clone::clone_trait_object!(<I, O> BatchableTransformer<Input = I, Output = O>);
154
155#[cfg(feature = "test-utils")]
156mock! {
157 #[derive(Debug)]
158 pub BatchableTransformer {}
159
160 #[async_trait]
161 impl BatchableTransformer for BatchableTransformer {
162 type Input = String;
163 type Output = String;
164
165 async fn batch_transform(&self, nodes: Vec<Node<String>>) -> IndexingStream<String>;
166 fn name(&self) -> &'static str;
167 fn batch_size(&self) -> Option<usize>;
168 fn concurrency(&self) -> Option<usize>;
169 }
170
171 impl Clone for BatchableTransformer {
172 fn clone(&self) -> Self;
173 }
174}
175#[async_trait]
176impl<F> BatchableTransformer for F
178where
179 F: Fn(Vec<Node<String>>) -> IndexingStream<String> + Send + Sync + Clone,
180{
181 type Input = String;
182 type Output = String;
183
184 async fn batch_transform(&self, nodes: Vec<Node<String>>) -> IndexingStream<String> {
185 self(nodes)
186 }
187}
188
189#[async_trait]
190impl<I: Chunk, O: Chunk> BatchableTransformer
191 for Box<dyn BatchableTransformer<Input = I, Output = O>>
192{
193 type Input = I;
194 type Output = O;
195
196 async fn batch_transform(&self, nodes: Vec<Node<Self::Input>>) -> IndexingStream<Self::Output> {
197 self.as_ref().batch_transform(nodes).await
198 }
199 fn concurrency(&self) -> Option<usize> {
200 self.as_ref().concurrency()
201 }
202 fn name(&self) -> &'static str {
203 self.as_ref().name()
204 }
205}
206
207#[async_trait]
208impl<I: Chunk, O: Chunk> BatchableTransformer
209 for Arc<dyn BatchableTransformer<Input = I, Output = O>>
210{
211 type Input = I;
212 type Output = O;
213
214 async fn batch_transform(&self, nodes: Vec<Node<Self::Input>>) -> IndexingStream<Self::Output> {
215 self.as_ref().batch_transform(nodes).await
216 }
217 fn concurrency(&self) -> Option<usize> {
218 self.as_ref().concurrency()
219 }
220 fn name(&self) -> &'static str {
221 self.as_ref().name()
222 }
223}
224
225#[async_trait]
226impl<I: Chunk, O: Chunk> BatchableTransformer for &dyn BatchableTransformer<Input = I, Output = O> {
227 type Input = I;
228 type Output = O;
229
230 async fn batch_transform(&self, nodes: Vec<Node<Self::Input>>) -> IndexingStream<Self::Output> {
231 (*self).batch_transform(nodes).await
232 }
233 fn concurrency(&self) -> Option<usize> {
234 (*self).concurrency()
235 }
236}
237
238pub trait Loader: DynClone + Send + Sync {
240 type Output: Chunk;
241
242 fn into_stream(self) -> IndexingStream<Self::Output>;
243
244 fn into_stream_boxed(self: Box<Self>) -> IndexingStream<Self::Output> {
256 unimplemented!(
257 "Please implement into_stream_boxed for your loader, it needs to be implemented on the concrete type"
258 )
259 }
260
261 fn name(&self) -> &'static str {
262 let name = std::any::type_name::<Self>();
263 name.split("::").last().unwrap_or(name)
264 }
265}
266
267dyn_clone::clone_trait_object!(<O> Loader<Output = O>);
268
269#[cfg(feature = "test-utils")]
270mock! {
271 #[derive(Debug)]
272 pub Loader {}
273
274 #[async_trait]
275 impl Loader for Loader {
276 type Output = String;
277
278 fn into_stream(self) -> IndexingStream<String>;
279 fn into_stream_boxed(self: Box<Self>) -> IndexingStream<String>;
280 fn name(&self) -> &'static str;
281 }
282
283 impl Clone for Loader {
284 fn clone(&self) -> Self;
285 }
286}
287
288impl<O: Chunk> Loader for Box<dyn Loader<Output = O>> {
289 type Output = O;
290
291 fn into_stream(self) -> IndexingStream<Self::Output> {
292 Loader::into_stream_boxed(self)
293 }
294
295 fn into_stream_boxed(self: Box<Self>) -> IndexingStream<Self::Output> {
296 Loader::into_stream(*self)
297 }
298 fn name(&self) -> &'static str {
299 self.as_ref().name()
300 }
301}
302
303impl<O: Chunk> Loader for &dyn Loader<Output = O> {
304 type Output = O;
305
306 fn into_stream(self) -> IndexingStream<Self::Output> {
307 Loader::into_stream_boxed(Box::new(self))
308 }
309
310 fn into_stream_boxed(self: Box<Self>) -> IndexingStream<Self::Output> {
311 Loader::into_stream(*self)
312 }
313}
314
315#[async_trait]
316pub trait ChunkerTransformer: Send + Sync + DynClone {
318 type Input: Chunk;
319 type Output: Chunk;
320
321 async fn transform_node(&self, node: Node<Self::Input>) -> IndexingStream<Self::Output>;
322
323 fn concurrency(&self) -> Option<usize> {
325 None
326 }
327
328 fn name(&self) -> &'static str {
329 let name = std::any::type_name::<Self>();
330 name.split("::").last().unwrap_or(name)
331 }
332}
333
334dyn_clone::clone_trait_object!(<I, O> ChunkerTransformer<Input = I, Output = O>);
335
336#[cfg(feature = "test-utils")]
337mock! {
338 #[derive(Debug)]
339 pub ChunkerTransformer {}
340
341 #[async_trait]
342 impl ChunkerTransformer for ChunkerTransformer {
343 type Input = String;
344 type Output = String;
345
346 async fn transform_node(&self, node: Node<String>) -> IndexingStream<String>;
347 fn name(&self) -> &'static str;
348 fn concurrency(&self) -> Option<usize>;
349 }
350
351 impl Clone for ChunkerTransformer {
352 fn clone(&self) -> Self;
353 }
354}
355#[async_trait]
356impl<I: Chunk, O: Chunk> ChunkerTransformer for Box<dyn ChunkerTransformer<Input = I, Output = O>> {
357 type Input = I;
358 type Output = O;
359
360 async fn transform_node(&self, node: Node<I>) -> IndexingStream<O> {
361 self.as_ref().transform_node(node).await
362 }
363 fn concurrency(&self) -> Option<usize> {
364 self.as_ref().concurrency()
365 }
366 fn name(&self) -> &'static str {
367 self.as_ref().name()
368 }
369}
370
371#[async_trait]
372impl<I: Chunk, O: Chunk> ChunkerTransformer for Arc<dyn ChunkerTransformer<Input = I, Output = O>> {
373 type Input = I;
374 type Output = O;
375
376 async fn transform_node(&self, node: Node<I>) -> IndexingStream<O> {
377 self.as_ref().transform_node(node).await
378 }
379 fn concurrency(&self) -> Option<usize> {
380 self.as_ref().concurrency()
381 }
382 fn name(&self) -> &'static str {
383 self.as_ref().name()
384 }
385}
386
387#[async_trait]
388impl<I: Chunk, O: Chunk> ChunkerTransformer for &dyn ChunkerTransformer<Input = I, Output = O> {
389 type Input = I;
390 type Output = O;
391
392 async fn transform_node(&self, node: Node<I>) -> IndexingStream<O> {
393 (*self).transform_node(node).await
394 }
395 fn concurrency(&self) -> Option<usize> {
396 (*self).concurrency()
397 }
398}
399
400#[async_trait]
401impl<F> ChunkerTransformer for F
402where
403 F: Fn(Node<String>) -> IndexingStream<String> + Send + Sync + Clone,
404{
405 async fn transform_node(&self, node: Node<String>) -> IndexingStream<String> {
406 self(node)
407 }
408
409 type Input = String;
410
411 type Output = String;
412}
413
414#[async_trait]
415pub trait NodeCache: Send + Sync + Debug + DynClone {
420 type Input: Chunk;
421
422 async fn get(&self, node: &Node<Self::Input>) -> bool;
423 async fn set(&self, node: &Node<Self::Input>);
424
425 async fn set_by_id(&self, id: uuid::Uuid);
429
430 async fn clear(&self) -> Result<()> {
432 unimplemented!("Clear not implemented")
433 }
434
435 fn name(&self) -> &'static str {
436 let name = std::any::type_name::<Self>();
437 name.split("::").last().unwrap_or(name)
438 }
439}
440
441dyn_clone::clone_trait_object!(<T> NodeCache<Input = T>);
442
443#[cfg(feature = "test-utils")]
444mock! {
445 #[derive(Debug)]
446 pub NodeCache {}
447
448 #[async_trait]
449 impl NodeCache for NodeCache {
450 type Input = String;
451 async fn get(&self, node: &Node<String>) -> bool;
452 async fn set(&self, node: &Node<String>);
453 async fn set_by_id(&self, id: uuid::Uuid);
454 async fn clear(&self) -> Result<()>;
455 fn name(&self) -> &'static str;
456
457 }
458
459 impl Clone for NodeCache {
460 fn clone(&self) -> Self;
461 }
462}
463
464#[async_trait]
465impl<T: Chunk> NodeCache for Box<dyn NodeCache<Input = T>> {
466 type Input = T;
467
468 async fn get(&self, node: &Node<T>) -> bool {
469 self.as_ref().get(node).await
470 }
471 async fn set(&self, node: &Node<T>) {
472 self.as_ref().set(node).await;
473 }
474 async fn set_by_id(&self, id: uuid::Uuid) {
475 self.as_ref().set_by_id(id).await;
476 }
477 async fn clear(&self) -> Result<()> {
478 self.as_ref().clear().await
479 }
480 fn name(&self) -> &'static str {
481 self.as_ref().name()
482 }
483}
484
485#[async_trait]
486impl<T: Chunk> NodeCache for Arc<dyn NodeCache<Input = T>> {
487 type Input = T;
488 async fn get(&self, node: &Node<T>) -> bool {
489 self.as_ref().get(node).await
490 }
491 async fn set(&self, node: &Node<T>) {
492 self.as_ref().set(node).await;
493 }
494 async fn set_by_id(&self, id: uuid::Uuid) {
495 self.as_ref().set_by_id(id).await;
496 }
497 async fn clear(&self) -> Result<()> {
498 self.as_ref().clear().await
499 }
500 fn name(&self) -> &'static str {
501 self.as_ref().name()
502 }
503}
504
505#[async_trait]
506impl<T: Chunk> NodeCache for &dyn NodeCache<Input = T> {
507 type Input = T;
508 async fn get(&self, node: &Node<T>) -> bool {
509 (*self).get(node).await
510 }
511 async fn set(&self, node: &Node<T>) {
512 (*self).set(node).await;
513 }
514 async fn set_by_id(&self, id: uuid::Uuid) {
515 (*self).set_by_id(id).await;
516 }
517 async fn clear(&self) -> Result<()> {
518 (*self).clear().await
519 }
520}
521
522#[async_trait]
523pub trait EmbeddingModel: Send + Sync + Debug + DynClone {
526 async fn embed(&self, input: Vec<String>) -> Result<Embeddings, LanguageModelError>;
527
528 fn name(&self) -> &'static str {
529 let name = std::any::type_name::<Self>();
530 name.split("::").last().unwrap_or(name)
531 }
532}
533
534dyn_clone::clone_trait_object!(EmbeddingModel);
535
536#[cfg(feature = "test-utils")]
537mock! {
538 #[derive(Debug)]
539 pub EmbeddingModel {}
540
541 #[async_trait]
542 impl EmbeddingModel for EmbeddingModel {
543 async fn embed(&self, input: Vec<String>) -> Result<Embeddings, LanguageModelError>;
544 fn name(&self) -> &'static str;
545 }
546
547 impl Clone for EmbeddingModel {
548 fn clone(&self) -> Self;
549 }
550}
551
552#[async_trait]
553impl EmbeddingModel for Box<dyn EmbeddingModel> {
554 async fn embed(&self, input: Vec<String>) -> Result<Embeddings, LanguageModelError> {
555 self.as_ref().embed(input).await
556 }
557
558 fn name(&self) -> &'static str {
559 self.as_ref().name()
560 }
561}
562
563#[async_trait]
564impl EmbeddingModel for Arc<dyn EmbeddingModel> {
565 async fn embed(&self, input: Vec<String>) -> Result<Embeddings, LanguageModelError> {
566 self.as_ref().embed(input).await
567 }
568
569 fn name(&self) -> &'static str {
570 self.as_ref().name()
571 }
572}
573
574#[async_trait]
575impl EmbeddingModel for &dyn EmbeddingModel {
576 async fn embed(&self, input: Vec<String>) -> Result<Embeddings, LanguageModelError> {
577 (*self).embed(input).await
578 }
579}
580
581#[async_trait]
582pub trait SparseEmbeddingModel: Send + Sync + Debug + DynClone {
585 async fn sparse_embed(
586 &self,
587 input: Vec<String>,
588 ) -> Result<SparseEmbeddings, LanguageModelError>;
589
590 fn name(&self) -> &'static str {
591 let name = std::any::type_name::<Self>();
592 name.split("::").last().unwrap_or(name)
593 }
594}
595
596dyn_clone::clone_trait_object!(SparseEmbeddingModel);
597
598#[cfg(feature = "test-utils")]
599mock! {
600 #[derive(Debug)]
601 pub SparseEmbeddingModel {}
602
603 #[async_trait]
604 impl SparseEmbeddingModel for SparseEmbeddingModel {
605 async fn sparse_embed(&self, input: Vec<String>) -> Result<SparseEmbeddings, LanguageModelError>;
606 fn name(&self) -> &'static str;
607 }
608
609 impl Clone for SparseEmbeddingModel {
610 fn clone(&self) -> Self;
611 }
612}
613
614#[async_trait]
615impl SparseEmbeddingModel for Box<dyn SparseEmbeddingModel> {
616 async fn sparse_embed(
617 &self,
618 input: Vec<String>,
619 ) -> Result<SparseEmbeddings, LanguageModelError> {
620 self.as_ref().sparse_embed(input).await
621 }
622
623 fn name(&self) -> &'static str {
624 self.as_ref().name()
625 }
626}
627
628#[async_trait]
629impl SparseEmbeddingModel for Arc<dyn SparseEmbeddingModel> {
630 async fn sparse_embed(
631 &self,
632 input: Vec<String>,
633 ) -> Result<SparseEmbeddings, LanguageModelError> {
634 self.as_ref().sparse_embed(input).await
635 }
636
637 fn name(&self) -> &'static str {
638 self.as_ref().name()
639 }
640}
641
642#[async_trait]
643impl SparseEmbeddingModel for &dyn SparseEmbeddingModel {
644 async fn sparse_embed(
645 &self,
646 input: Vec<String>,
647 ) -> Result<SparseEmbeddings, LanguageModelError> {
648 (*self).sparse_embed(input).await
649 }
650}
651
652#[async_trait]
653pub trait SimplePrompt: Debug + Send + Sync + DynClone {
655 async fn prompt(&self, prompt: Prompt) -> Result<String, LanguageModelError>;
657
658 fn name(&self) -> &'static str {
659 let name = std::any::type_name::<Self>();
660 name.split("::").last().unwrap_or(name)
661 }
662}
663
664dyn_clone::clone_trait_object!(SimplePrompt);
665
666#[cfg(feature = "test-utils")]
667mock! {
668 #[derive(Debug)]
669 pub SimplePrompt {}
670
671 #[async_trait]
672 impl SimplePrompt for SimplePrompt {
673 async fn prompt(&self, prompt: Prompt) -> Result<String, LanguageModelError>;
674 fn name(&self) -> &'static str;
675 }
676
677 impl Clone for SimplePrompt {
678 fn clone(&self) -> Self;
679 }
680}
681
682#[async_trait]
683impl SimplePrompt for Box<dyn SimplePrompt> {
684 async fn prompt(&self, prompt: Prompt) -> Result<String, LanguageModelError> {
685 self.as_ref().prompt(prompt).await
686 }
687
688 fn name(&self) -> &'static str {
689 self.as_ref().name()
690 }
691}
692
693#[async_trait]
694impl SimplePrompt for Arc<dyn SimplePrompt> {
695 async fn prompt(&self, prompt: Prompt) -> Result<String, LanguageModelError> {
696 self.as_ref().prompt(prompt).await
697 }
698
699 fn name(&self) -> &'static str {
700 self.as_ref().name()
701 }
702}
703
704#[async_trait]
705impl SimplePrompt for &dyn SimplePrompt {
706 async fn prompt(&self, prompt: Prompt) -> Result<String, LanguageModelError> {
707 (*self).prompt(prompt).await
708 }
709}
710
711#[async_trait]
712pub trait Persist: Debug + Send + Sync + DynClone {
714 type Input: Chunk;
715 type Output: Chunk;
716
717 async fn setup(&self) -> Result<()>;
718 async fn store(&self, node: Node<Self::Input>) -> Result<Node<Self::Output>>;
719 async fn batch_store(&self, nodes: Vec<Node<Self::Input>>) -> IndexingStream<Self::Output>;
720 fn batch_size(&self) -> Option<usize> {
721 None
722 }
723
724 fn name(&self) -> &'static str {
725 let name = std::any::type_name::<Self>();
726 name.split("::").last().unwrap_or(name)
727 }
728}
729
730dyn_clone::clone_trait_object!(<I, O> Persist<Input = I, Output = O>);
731
732#[cfg(feature = "test-utils")]
733mock! {
734 #[derive(Debug)]
735 pub Persist {}
736
737 #[async_trait]
738 impl Persist for Persist {
739 type Input = String;
740 type Output = String;
741
742 async fn setup(&self) -> Result<()>;
743 async fn store(&self, node: Node<String>) -> Result<Node<String>>;
744 async fn batch_store(&self, nodes: Vec<Node<String>>) -> IndexingStream<String>;
745 fn batch_size(&self) -> Option<usize>;
746
747 fn name(&self) -> &'static str;
748 }
749
750 impl Clone for Persist {
751 fn clone(&self) -> Self;
752 }
753}
754
755#[async_trait]
756impl<I: Chunk, O: Chunk> Persist for Box<dyn Persist<Input = I, Output = O>> {
757 type Input = I;
758 type Output = O;
759
760 async fn setup(&self) -> Result<()> {
761 self.as_ref().setup().await
762 }
763 async fn store(&self, node: Node<I>) -> Result<Node<O>> {
764 self.as_ref().store(node).await
765 }
766 async fn batch_store(&self, nodes: Vec<Node<I>>) -> IndexingStream<O> {
767 self.as_ref().batch_store(nodes).await
768 }
769 fn batch_size(&self) -> Option<usize> {
770 self.as_ref().batch_size()
771 }
772 fn name(&self) -> &'static str {
773 self.as_ref().name()
774 }
775}
776
777#[async_trait]
778impl<I: Chunk, O: Chunk> Persist for Arc<dyn Persist<Input = I, Output = O>> {
779 type Input = I;
780 type Output = O;
781
782 async fn setup(&self) -> Result<()> {
783 self.as_ref().setup().await
784 }
785 async fn store(&self, node: Node<I>) -> Result<Node<O>> {
786 self.as_ref().store(node).await
787 }
788 async fn batch_store(&self, nodes: Vec<Node<I>>) -> IndexingStream<O> {
789 self.as_ref().batch_store(nodes).await
790 }
791 fn batch_size(&self) -> Option<usize> {
792 self.as_ref().batch_size()
793 }
794 fn name(&self) -> &'static str {
795 self.as_ref().name()
796 }
797}
798
799#[async_trait]
800impl<I: Chunk, O: Chunk> Persist for &dyn Persist<Input = I, Output = O> {
801 type Input = I;
802 type Output = O;
803
804 async fn setup(&self) -> Result<()> {
805 (*self).setup().await
806 }
807 async fn store(&self, node: Node<I>) -> Result<Node<O>> {
808 (*self).store(node).await
809 }
810 async fn batch_store(&self, nodes: Vec<Node<I>>) -> IndexingStream<O> {
811 (*self).batch_store(nodes).await
812 }
813 fn batch_size(&self) -> Option<usize> {
814 (*self).batch_size()
815 }
816}
817
818pub trait WithIndexingDefaults {
821 fn with_indexing_defaults(&mut self, _indexing_defaults: IndexingDefaults) {}
822}
823
824pub trait WithBatchIndexingDefaults {
827 fn with_indexing_defaults(&mut self, _indexing_defaults: IndexingDefaults) {}
828}
829
830impl<I, O> WithIndexingDefaults for dyn Transformer<Input = I, Output = O> {}
831impl<I, O> WithIndexingDefaults for Box<dyn Transformer<Input = I, Output = O>> {
832 fn with_indexing_defaults(&mut self, indexing_defaults: IndexingDefaults) {
833 self.as_mut().with_indexing_defaults(indexing_defaults);
834 }
835}
836impl<I, O> WithBatchIndexingDefaults for dyn BatchableTransformer<Input = I, Output = O> {}
837impl<I, O> WithBatchIndexingDefaults for Box<dyn BatchableTransformer<Input = I, Output = O>> {
838 fn with_indexing_defaults(&mut self, indexing_defaults: IndexingDefaults) {
839 self.as_mut().with_indexing_defaults(indexing_defaults);
840 }
841}
842
843impl<F> WithIndexingDefaults for F where F: Fn(Node<String>) -> Result<Node<String>> {}
844impl<F> WithBatchIndexingDefaults for F where F: Fn(Vec<Node<String>>) -> IndexingStream<String> {}
845
846#[cfg(feature = "test-utils")]
847impl WithIndexingDefaults for MockTransformer {}
848#[cfg(feature = "test-utils")]
850impl WithBatchIndexingDefaults for MockBatchableTransformer {}
851
852#[async_trait]
853pub trait StructuredPrompt: Debug + Send + Sync + DynClone {
855 async fn structured_prompt<T: DeserializeOwned + JsonSchema>(
856 &self,
857 prompt: Prompt,
858 ) -> Result<T, LanguageModelError>;
859
860 fn name(&self) -> &'static str {
861 let name = std::any::type_name::<Self>();
862 name.split("::").last().unwrap_or(name)
863 }
864}
865
866#[async_trait]
871pub trait DynStructuredPrompt: Debug + Send + Sync + DynClone {
872 async fn structured_prompt_dyn(
873 &self,
874 prompt: Prompt,
875 schema: schemars::Schema,
876 ) -> Result<serde_json::Value, LanguageModelError>;
877
878 fn name(&self) -> &'static str {
879 let name = std::any::type_name::<Self>();
880 name.split("::").last().unwrap_or(name)
881 }
882}
883
884dyn_clone::clone_trait_object!(DynStructuredPrompt);
885
886#[async_trait]
887impl<C> StructuredPrompt for C
888where
889 C: DynStructuredPrompt + Debug + Send + Sync + DynClone,
890{
891 async fn structured_prompt<T: DeserializeOwned + JsonSchema>(
892 &self,
893 prompt: Prompt,
894 ) -> Result<T, LanguageModelError> {
895 let schema = schema_for!(T);
897 let val = self.structured_prompt_dyn(prompt, schema).await?;
898
899 let parsed = serde_json::from_value(val).map_err(LanguageModelError::permanent)?;
900
901 Ok(parsed)
902 }
903}