Skip to main content

cognee_http_server/dto/
activity.rs

1//! DTOs for the `GET /api/v1/activity/*` family.
2//!
3//! All ISO-8601 timestamp fields stay `Option<String>` to match Python's
4//! `.isoformat()` shape (with the literal `+00:00` suffix). This intentionally
5//! diverges from the OpenAPI `date-time` representation so the wire format is
6//! byte-equivalent across SDKs.
7
8use serde::Serialize;
9use utoipa::ToSchema;
10use uuid::Uuid;
11
12/// One row of `GET /api/v1/activity/pipeline-runs`.
13///
14/// Mirrors the Python dict at
15/// `cognee/api/v1/activity/routers/get_activity_router.py` lines 51–62.
16#[derive(Debug, Clone, Serialize, ToSchema)]
17#[serde(rename_all = "snake_case")]
18pub struct PipelineRunListItemDTO {
19    pub id: Uuid,
20    pub pipeline_name: String,
21    /// `DATASET_PROCESSING_*` enum string. `None` when the row's status is NULL.
22    pub status: Option<String>,
23    pub dataset_id: Option<Uuid>,
24    pub dataset_name: Option<String>,
25    pub owner_id: Option<Uuid>,
26    pub owner_email: Option<String>,
27    /// ISO-8601, e.g. `"2026-04-24T18:30:00+00:00"`.
28    pub created_at: Option<String>,
29    pub pipeline_run_id: Option<Uuid>,
30}
31
32/// One trace returned by `GET /api/v1/activity/spans`.
33///
34/// Wire shape matches Python's exporter dict at
35/// `get_activity_router.py` lines 88–96.
36#[derive(Debug, Clone, Serialize, ToSchema)]
37#[serde(rename_all = "snake_case")]
38pub struct TraceSummaryDTO {
39    pub trace_id: String,
40    pub root_name: Option<String>,
41    pub duration_ms: f64,
42    pub span_count: usize,
43    /// `"OK" | "ERROR" | "UNSET"`. `None` only when the trace has no spans.
44    pub status: Option<String>,
45    pub spans: Vec<RecordedSpanDTO>,
46}
47
48/// One span inside a [`TraceSummaryDTO`].
49#[derive(Debug, Clone, Serialize, ToSchema)]
50#[serde(rename_all = "snake_case")]
51pub struct RecordedSpanDTO {
52    pub name: String,
53    pub trace_id: String,
54    pub span_id: String,
55    pub parent_span_id: Option<String>,
56    pub start_time_ns: u64,
57    pub end_time_ns: u64,
58    pub duration_ms: f64,
59    /// Already redacted by `SpanBufferLayer::on_close`. Stringified to match
60    /// Python's already-stringified shape — `"OK" | "ERROR" | "UNSET"`.
61    pub status: String,
62    pub attributes: serde_json::Map<String, serde_json::Value>,
63}
64
65/// One row of `GET /api/v1/activity/users`.
66#[derive(Debug, Clone, Serialize, ToSchema)]
67#[serde(rename_all = "snake_case")]
68pub struct TenantUserDTO {
69    pub id: Uuid,
70    pub email: String,
71    pub is_superuser: bool,
72    pub created_at: Option<String>,
73}
74
75/// One row of `GET /api/v1/activity/agents`.
76///
77/// Mirrors Python's dict at L181–L194 of `get_activity_router.py`.
78#[derive(Debug, Clone, Serialize, ToSchema)]
79#[serde(rename_all = "snake_case")]
80pub struct AgentDTO {
81    pub id: Uuid,
82    pub email: String,
83    pub agent_type: String,
84    pub agent_short_id: String,
85    pub is_agent: bool,
86    pub is_default: bool,
87    /// `"LIVE"` if the user has at least one API key, else `"INACTIVE"`.
88    pub status: String,
89    pub api_key_count: u64,
90    pub created_at: Option<String>,
91}
92
93/// Body returned by `GET /api/v1/activity/spans` on the catch-all path.
94///
95/// Status stays 200 (Python parity). Body is the literal `{"error": "..."}`
96/// object (not an array) so existing dashboards continue to render.
97#[derive(Debug, Clone, Serialize, ToSchema)]
98#[serde(rename_all = "snake_case")]
99pub struct SpansErrorEnvelopeDTO {
100    pub error: String,
101}