1use crate::compiler::{CompiledInstinct, CompiledResult};
4use crate::encoder::{cosine_similarity, SemanticVectorEncoder, VECTOR_DIM};
5use crate::guardrails::{GuardrailResult, GuardrailSuite};
6use crate::primitives::{Choice, ChoiceResult, Noul, NoulResult, Score, ScoreResult};
7
8#[derive(Clone, Debug, Default)]
10pub struct Reflex {
11 encoder: SemanticVectorEncoder,
12 guardrails: GuardrailSuite,
13 pub compiled_instinct: Option<CompiledInstinct>,
14}
15
16impl Reflex {
17 pub fn new() -> Self {
18 Self {
19 encoder: SemanticVectorEncoder::new(),
20 guardrails: GuardrailSuite::new(),
21 compiled_instinct: None,
22 }
23 }
24
25 pub fn with_compiled_model(compiled_instinct: CompiledInstinct) -> Self {
26 Self {
27 encoder: SemanticVectorEncoder::new(),
28 guardrails: GuardrailSuite::new(),
29 compiled_instinct: Some(compiled_instinct),
30 }
31 }
32
33 pub fn predict(&self, state: &str) -> Result<CompiledResult, String> {
35 match &self.compiled_instinct {
36 Some(model) => Ok(model.predict(state)),
37 None => Err("No compiled instinct model loaded. Use Reflex::with_compiled_model().".to_string()),
38 }
39 }
40
41 pub fn noul(&self, instructions: impl Into<String>, state: &str) -> NoulResult {
43 let noul = Noul::new(instructions);
44 let state_vec = self.encoder.encode(state);
45 noul.evaluate(state, &state_vec, &self.encoder)
46 }
47
48 pub fn choice(&self, instructions: impl Into<String>, options: Vec<String>, state: &str) -> ChoiceResult {
50 let choice = Choice::new(instructions, options);
51 let state_vec = self.encoder.encode(state);
52 choice.evaluate(state, &state_vec, &self.encoder)
53 }
54
55 pub fn score(&self, instructions: impl Into<String>, min_val: f32, max_val: f32, state: &str) -> ScoreResult {
57 let score = Score::new(instructions, min_val, max_val);
58 let state_vec = self.encoder.encode(state);
59 score.evaluate(state, &state_vec, &self.encoder)
60 }
61
62 pub fn guardrail(&self, text: &str) -> GuardrailResult {
64 self.guardrails.evaluate(text)
65 }
66
67 pub fn encode(&self, text: &str) -> [f32; VECTOR_DIM] {
69 self.encoder.encode(text)
70 }
71
72 pub fn similarity(&self, text_a: &str, text_b: &str) -> f32 {
74 let vec_a = self.encoder.encode(text_a);
75 let vec_b = self.encoder.encode(text_b);
76 cosine_similarity(&vec_a, &vec_b)
77 }
78}