Skip to main content

kindling_types/
summary.rs

1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "ts-rs")]
4use ts_rs::TS;
5
6use crate::common::{Id, Timestamp};
7
8/// High-level description of a capsule's content (typically LLM-generated).
9///
10/// Mirrors `Summary` in `packages/kindling-core/src/types/summary.ts`.
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12#[cfg_attr(feature = "ts-rs", derive(TS), ts(export, export_to = "../bindings/"))]
13#[serde(rename_all = "camelCase")]
14pub struct Summary {
15    pub id: Id,
16    pub capsule_id: Id,
17    pub content: String,
18    /// Quality/confidence score in `[0.0, 1.0]`.
19    pub confidence: f64,
20    #[cfg_attr(feature = "ts-rs", ts(type = "number"))]
21    pub created_at: Timestamp,
22    pub evidence_refs: Vec<Id>,
23}
24
25/// Input for creating a new summary. Optional fields are auto-generated.
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27#[cfg_attr(feature = "ts-rs", derive(TS), ts(export, export_to = "../bindings/"))]
28#[serde(rename_all = "camelCase")]
29pub struct SummaryInput {
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    #[cfg_attr(feature = "ts-rs", ts(optional))]
32    pub id: Option<Id>,
33    pub capsule_id: Id,
34    pub content: String,
35    pub confidence: f64,
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    #[cfg_attr(feature = "ts-rs", ts(optional, type = "number"))]
38    pub created_at: Option<Timestamp>,
39    pub evidence_refs: Vec<Id>,
40}
41
42/// Validate that confidence score is in `[0.0, 1.0]` and not NaN.
43pub fn is_valid_confidence(value: f64) -> bool {
44    !value.is_nan() && (0.0..=1.0).contains(&value)
45}