Skip to main content

systemprompt_models/brain/
enter.rs

1//! A fact a person types in, carried as the payload of a
2//! `brain.fact.entered` event.
3//!
4//! Copyright (c) systemprompt.io — Business Source License 1.1.
5//! See <https://systemprompt.io> for licensing details.
6
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9use systemprompt_identifiers::{FactKindId, TopicId, UserId};
10
11use super::event::{BrainEvent, BrainEventKind};
12use super::scope::FactScope;
13use super::subject::SubjectKey;
14
15/// The status an entered fact starts in.
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum EnteredStatus {
19    #[default]
20    Candidate,
21    Proposed,
22}
23
24/// A person-entered fact.
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26#[serde(deny_unknown_fields)]
27pub struct EnteredFact {
28    pub kind: FactKindId,
29    pub subject: SubjectKey,
30    // JSON: entered fields are checked against the kind declaration by the pipeline.
31    pub fields: serde_json::Map<String, serde_json::Value>,
32    pub scope: FactScope,
33    #[serde(default)]
34    pub topics: Vec<TopicId>,
35    #[serde(default)]
36    pub status: EnteredStatus,
37    #[serde(default)]
38    pub observed_at: Option<DateTime<Utc>>,
39}
40
41impl EnteredFact {
42    pub fn to_event(
43        &self,
44        actor: UserId,
45        occurred_at: DateTime<Utc>,
46    ) -> Result<BrainEvent, serde_json::Error> {
47        Ok(
48            BrainEvent::new(BrainEventKind::fact_entered(), actor, occurred_at)
49                .with_payload(serde_json::to_value(self)?),
50        )
51    }
52}