Skip to main content

objectiveai_sdk/
logs.rs

1//! SDK-side `logs` module.
2//!
3//! Hosts the structural types that every `*Log` data type needs to
4//! express its on-disk shape — primarily [`LogReference`] (`{type,
5//! path}`), the indexed variant [`IndexedLogReference`], and the
6//! constant `"reference"` discriminator [`LogReferenceTag`].
7//!
8//! These are pure data shapes. They live here in the SDK because the
9//! `*Log` types embed them as fields; the filesystem behavior that
10//! constructs the values (path joining, file writes, etc.) lives in
11//! `objectiveai-cli` per `feedback_extract_methods_relocate_to_cli`.
12//!
13//! On disk:
14//!
15//! ```json
16//! { "type": "reference", "path": "agents/completions/response/messages/assistant/acc-1_0.json" }
17//! ```
18//!
19//! For references that carry additional per-context metadata (an
20//! `index`, a `task_path`, an inline `error` or `output`, etc.), each
21//! chunk that needs them defines its own `LogReference` struct in a
22//! sibling `*_log_reference.rs` file — same name (`LogReference`),
23//! different module path.
24
25use schemars::JsonSchema;
26use serde::{Deserialize, Serialize};
27
28/// Plain on-disk pointer (`type` + `path` only).
29#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
30#[schemars(rename = "LogReference")]
31pub struct LogReference {
32    #[serde(rename = "type")]
33    pub r#type: LogReferenceTag,
34    /// Relative on-disk path of the referenced file (under
35    /// `${config_base_dir}/logs/`). Skipped when empty — the no-data
36    /// sentinel case used by some wrappers when the inner chunk has
37    /// no content to log.
38    #[serde(skip_serializing_if = "String::is_empty")]
39    #[schemars(extend("omitempty" = true))]
40    pub path: String,
41}
42
43impl LogReference {
44    pub fn new(path: String) -> Self {
45        Self {
46            r#type: LogReferenceTag::Reference,
47            path,
48        }
49    }
50}
51
52/// Constant `"reference"` discriminator — the `"type"` field on every
53/// `LogReference` variant.
54#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
55#[serde(rename_all = "lowercase")]
56#[schemars(rename = "LogReferenceTag")]
57pub enum LogReferenceTag {
58    Reference,
59}
60
61/// `LogReference` for log files keyed by an `index` — used by
62/// per-agent / per-invention completion wrappers that need to preserve
63/// their position within a parent collection (a vector completion's
64/// swarm-index, an invention's per-invention index, etc.).
65#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
66#[schemars(rename = "IndexedLogReference")]
67pub struct IndexedLogReference {
68    #[serde(rename = "type")]
69    pub r#type: LogReferenceTag,
70    #[serde(skip_serializing_if = "String::is_empty")]
71    #[schemars(extend("omitempty" = true))]
72    pub path: String,
73    pub index: u64,
74}
75
76impl IndexedLogReference {
77    pub fn new(path: String, index: u64) -> Self {
78        Self {
79            r#type: LogReferenceTag::Reference,
80            path,
81            index,
82        }
83    }
84}