Skip to main content

wire/
message_hosted.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Local projections retained after hosted protocol mapping.
3
4use std::path::PathBuf;
5
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum HostedSpoolKind {
11    Spool,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct HostedSpoolInfo {
16    pub spool_id: String,
17    pub full_path: String,
18    pub kind: String,
19    pub is_repo: bool,
20    pub display_name: Option<String>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct HostedNamespaceInfo {
25    pub namespace_id: String,
26    pub kind: String,
27    pub slug: String,
28    pub parent_id: Option<String>,
29    pub display_name: Option<String>,
30    pub full_path: String,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct HostedRepositoryInfo {
35    pub repo_id: String,
36    pub namespace_id: String,
37    pub slug: String,
38    pub path: PathBuf,
39    pub full_path: String,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct HostedGrantInfo {
44    pub subject: String,
45    pub role: String,
46    #[serde(default)]
47    pub namespace_path: Option<String>,
48    #[serde(default)]
49    pub repo_path: Option<String>,
50}
51
52#[derive(Debug, Clone, Default, Serialize, Deserialize)]
53pub struct HarnessIdentity {
54    #[serde(default)]
55    pub harness: Option<String>,
56    #[serde(default)]
57    pub provider: Option<String>,
58    #[serde(default)]
59    pub model: Option<String>,
60    #[serde(default)]
61    pub thinking_level: Option<String>,
62    #[serde(default)]
63    pub policy: Option<String>,
64}
65
66#[derive(Debug, Clone, Default, Serialize, Deserialize)]
67pub struct UsageTotals {
68    #[serde(default)]
69    pub input_tokens: Option<u64>,
70    #[serde(default)]
71    pub output_tokens: Option<u64>,
72    #[serde(default)]
73    pub reasoning_tokens: Option<u64>,
74    #[serde(default)]
75    pub cache_creation_tokens: Option<u64>,
76    #[serde(default)]
77    pub cache_read_tokens: Option<u64>,
78    #[serde(default)]
79    pub tool_calls: Option<u32>,
80    #[serde(default)]
81    pub cost_micros_usd: Option<u64>,
82}
83
84#[derive(Debug, Clone, Default, Serialize, Deserialize)]
85pub struct ProgressCheckpoint {
86    #[serde(default)]
87    pub status: Option<String>,
88    #[serde(default)]
89    pub message: Option<String>,
90    #[serde(default)]
91    pub completed_steps: Option<u32>,
92    #[serde(default)]
93    pub total_steps: Option<u32>,
94    #[serde(default)]
95    pub touched_paths: Vec<String>,
96    pub recorded_at: String,
97}
98
99#[derive(Debug, Clone, Default, Serialize, Deserialize)]
100pub struct TranscriptAttachmentRef {
101    pub attachment_id: String,
102    #[serde(default)]
103    pub kind: Option<String>,
104    #[serde(default)]
105    pub summary: Option<String>,
106}
107
108#[derive(Debug, Clone, Default, Serialize, Deserialize)]
109pub struct SessionDiffSummary {
110    #[serde(default)]
111    pub changed_file_count: u32,
112    #[serde(default)]
113    pub added_files: u32,
114    #[serde(default)]
115    pub modified_files: u32,
116    #[serde(default)]
117    pub deleted_files: u32,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct WorktreeChangeBaseline {
122    pub path: String,
123    pub kind: String,
124}
125
126#[cfg(test)]
127mod tests {
128    use super::HostedSpoolKind;
129
130    #[test]
131    fn spool_kind_does_not_determine_repository_capability() {
132        let kind = HostedSpoolKind::Spool;
133        let encoded = rmp_serde::to_vec(&kind).expect("encode spool kind");
134        assert_eq!(
135            rmp_serde::from_slice::<HostedSpoolKind>(&encoded).expect("decode spool kind"),
136            kind
137        );
138        for is_repo in [false, true] {
139            let spool = super::HostedSpoolInfo {
140                spool_id: "id".into(),
141                full_path: "spool/alice/notes".into(),
142                kind: "spool".into(),
143                is_repo,
144                display_name: None,
145            };
146            let bytes = rmp_serde::to_vec(&spool).expect("encode spool");
147            let decoded: super::HostedSpoolInfo =
148                rmp_serde::from_slice(&bytes).expect("decode spool");
149            assert_eq!(decoded.is_repo, is_repo);
150            assert_eq!(decoded.kind, "spool");
151        }
152    }
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct SessionReportEnvelope {
157    pub version: u32,
158    pub heddle_session_id: String,
159    #[serde(default)]
160    pub heddle_segment_id: Option<String>,
161    #[serde(default)]
162    pub agent_session_id: Option<String>,
163    #[serde(default)]
164    pub client_instance_id: Option<String>,
165    #[serde(default)]
166    pub native_actor_key: Option<String>,
167    #[serde(default)]
168    pub native_parent_actor_key: Option<String>,
169    #[serde(default)]
170    pub native_instance_key: Option<String>,
171    pub repo_root: String,
172    #[serde(default)]
173    pub thread: Option<String>,
174    #[serde(default)]
175    pub thread_id: Option<String>,
176    #[serde(default)]
177    pub task: Option<String>,
178    #[serde(default)]
179    pub summary: Option<String>,
180    pub opened_at: String,
181    #[serde(default)]
182    pub closed_at: Option<String>,
183    #[serde(default)]
184    pub base_state_at_open: Option<String>,
185    #[serde(default)]
186    pub worktree_changes_at_open: Vec<WorktreeChangeBaseline>,
187    #[serde(default)]
188    pub head_state_at_close: Option<String>,
189    pub transport_mode: String,
190    pub transcript_mode: String,
191    #[serde(default)]
192    pub outcome: Option<String>,
193    #[serde(default)]
194    pub owns_session: bool,
195    pub harness: HarnessIdentity,
196    #[serde(default)]
197    pub progress: Vec<ProgressCheckpoint>,
198    #[serde(default)]
199    pub usage: UsageTotals,
200    #[serde(default)]
201    pub touched_paths: Vec<String>,
202    #[serde(default)]
203    pub changed_paths: Vec<String>,
204    #[serde(default)]
205    pub diff_summary: Option<SessionDiffSummary>,
206    #[serde(default)]
207    pub transcript_refs: Vec<TranscriptAttachmentRef>,
208    #[serde(default)]
209    pub last_progress_at: Option<String>,
210    #[serde(default)]
211    pub report_flush_state: Option<String>,
212    #[serde(default)]
213    pub attach_reason: Option<String>,
214    #[serde(default)]
215    pub attach_precedence: Vec<String>,
216    #[serde(default)]
217    pub winning_attach_rule: Option<String>,
218    #[serde(default)]
219    pub probe_source: Option<String>,
220    #[serde(default)]
221    pub probe_confidence: Option<f32>,
222    #[serde(default)]
223    pub pending_flush: bool,
224    #[serde(default)]
225    pub last_flushed_at: Option<String>,
226}