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}