1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* Hanzo Cloud API
*
* The Hanzo Cloud API as a customer calls it: every operation under /v1/ except the operator's admin product, relay routes, legacy spellings and capabilities still reached by flag. Tagged by product: the first path segment after /v1/.
*
* The version of the OpenAPI document: v1
*
* Generated by: https://openapi-generator.tech
*/
use crate::models;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct SessionView {
/// Account is which subscription or API account under that provider served it. Together with Provider it is what a login revoke matches on to stop the sessions a withdrawn account was paying for.
#[serde(rename = "account", skip_serializing_if = "Option::is_none")]
pub account: Option<String>,
/// Actor is WHO this session belongs to, as \"org/sub\" — the same identity a run is billed under. A register that names none takes the calling principal. It is what scopes a login revoke, so a session with the wrong actor is a session the right person cannot stop.
#[serde(rename = "actor", skip_serializing_if = "Option::is_none")]
pub actor: Option<String>,
/// Agent is the label the surface running this session calls itself by (\"hanzo-dev\"), up to 128 characters. Required at register. It is free text, not a reference: it need not name a defined agent, and nothing resolves it.
#[serde(rename = "agent", skip_serializing_if = "Option::is_none")]
pub agent: Option<String>,
/// Children is the DIRECT fan-out — how many sessions name this one as parent — and not the size of the subtree. Read the tree for that.
#[serde(rename = "children", skip_serializing_if = "Option::is_none")]
pub children: Option<i32>,
/// CreatedAt is when the row was written, same format. Every path that opens a session stamps it and StartedAt from one clock reading, so the two are equal on every session this surface has ever produced.
#[serde(rename = "createdAt", skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
/// Cwd is the directory the session is working in NOW, not the one it started in: a linked shell moves around, and a card showing where `hanzo link` was run answers \"which work is this\" with something that was true once.
#[serde(rename = "cwd", skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
/// EndedAt is when it reached done or error, same format. Empty while it is still running or paused, which is how absence reads here: not over yet.
#[serde(rename = "endedAt", skip_serializing_if = "Option::is_none")]
pub ended_at: Option<String>,
/// Events is how many turns the session's log holds, counted at read time. It is the whole log, however few of them RecentEvents carries.
#[serde(rename = "events", skip_serializing_if = "Option::is_none")]
pub events: Option<i32>,
/// Execution context (mission-control): the machine/repo/cwd a card shows and the run-target a session is dispatched to. Omitted when a surface didn't report it.
#[serde(rename = "host", skip_serializing_if = "Option::is_none")]
pub host: Option<String>,
/// ID is the session's handle, minted here as \"sess_\" + 32 hex characters. Every later read, patch, event append and control command is addressed with it, and a caller cannot choose it.
#[serde(rename = "id", skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
/// LastEvent is the compact latest-activity line for the list projection (nil in register/patch/tree responses; set by list + detail). It lets a swipe card show a live one-line preview without fetching full detail.
#[serde(rename = "lastEvent", skip_serializing_if = "Option::is_none")]
pub last_event: Option<Box<models::LastEventView>>,
/// Org is the caller's OWN tenant, echoed so a client can build the public build URL (/builds/:org/:project) without a second call or a guess. It is never another tenant's — every read is org-scoped before it gets here.
#[serde(rename = "org", skip_serializing_if = "Option::is_none")]
pub org: Option<String>,
/// ParentSessionID is the session that spawned this one, making this a subagent of it. Empty means this session is a root — a flow of its own. A parent always belongs to the same org, so a tree never crosses a tenant.
#[serde(rename = "parentSessionId", skip_serializing_if = "Option::is_none")]
pub parent_session_id: Option<String>,
/// Progress is how far along this run is — a share of its goal, a phase, and a line saying what it is doing. Always present, so a board never branches on whether it is there; `phase` says \"unknown\" when nothing has estimated it. It is a MODEL ESTIMATE wherever `estimated` is true, and the row's own word where it is false. See progress.go.
#[serde(rename = "progress", skip_serializing_if = "Option::is_none")]
pub progress: Option<Box<models::SessionProgress>>,
/// The readable build: the product this session built and whether its story is public (provenance.go).
#[serde(rename = "project", skip_serializing_if = "Option::is_none")]
pub project: Option<String>,
/// Provider is the linked AI account's provider (claude | codex | hanzo | …) that served this run. Empty when the surface did not say.
#[serde(rename = "provider", skip_serializing_if = "Option::is_none")]
pub provider: Option<String>,
/// Published is the author's decision to let anyone read this session's story at the public build route. It only ever widens READ access to a session that already exists and grants nothing else; false, an unpublished session is invisible there no matter who asks. It cannot be true without a Project, because that route is keyed on (org, project).
#[serde(rename = "published", skip_serializing_if = "Option::is_none")]
pub published: Option<bool>,
/// Repo is the code the session is working on, as the surface reported it. It is truth the SURFACE states, so it is a label rather than something resolved here.
#[serde(rename = "repo", skip_serializing_if = "Option::is_none")]
pub repo: Option<String>,
/// Room is the collaborative room this run was started in (HIP-0523), empty when it came from anywhere else — a CLI, a schedule, an API call. It is what lets a workspace view show the runs of one room beside its messages.
#[serde(rename = "room", skip_serializing_if = "Option::is_none")]
pub room: Option<String>,
/// RootSessionID is the top of this session's tree, inherited from the parent and shared by every node in one flow. A root session's own id, when it has no parent. It is the key one indexed read pulls a whole flow by, and what ?root= narrows a list or a stream to.
#[serde(rename = "rootSessionId", skip_serializing_if = "Option::is_none")]
pub root_session_id: Option<String>,
/// StartedAt is when the session opened, RFC 3339 in UTC to the second.
#[serde(rename = "startedAt", skip_serializing_if = "Option::is_none")]
pub started_at: Option<String>,
/// Status is one of exactly four: running, paused, done, error. running and paused are LIVE; done and error are TERMINAL and monotonic — once a session reaches one it can never go back, because reopening a finished run would fabricate liveness. A control command never moves it: the surface running the agent reports the new status, and until it does the command is only recorded.
#[serde(rename = "status", skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
/// Target is the registered run-target this session is dispatched to — a machine the org claimed, resolved same-org when it was set, so it can never point at another tenant's computer. Empty means the session names no machine.
#[serde(rename = "target", skip_serializing_if = "Option::is_none")]
pub target: Option<String>,
/// TaskRunID is that workflow's particular run. A workflow is the definition and a run is one execution of it, which is why both are carried.
#[serde(rename = "taskRunId", skip_serializing_if = "Option::is_none")]
pub task_run_id: Option<String>,
/// TaskWorkflowID is the hanzoai/tasks durable workflow that actually EXECUTES this session — this registry is the view, control and stream layer over it. Set, a control command is FORWARDED to that engine; empty, the running surface polls for commands instead, which is every session today.
#[serde(rename = "taskWorkflowId", skip_serializing_if = "Option::is_none")]
pub task_workflow_id: Option<String>,
/// Terminal is where this session can be WATCHED — the URL the machine published for its live terminal. Omitted when it publishes none.
#[serde(rename = "terminal", skip_serializing_if = "Option::is_none")]
pub terminal: Option<String>,
/// Title is the human line a card shows (\"ship the landing page\"), up to 512 characters. Free text, and the one field a surface may rewrite as the work turns out to be something else.
#[serde(rename = "title", skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
/// UpdatedAt is the session's last-activity clock, same format. It moves on a write to the row — a status, a title, a re-dispatch — AND on every appended turn, because the append bumps it in the same transaction. The list is ordered on CreatedAt, so this is the field that says whether a session is still saying anything.
#[serde(rename = "updatedAt", skip_serializing_if = "Option::is_none")]
pub updated_at: Option<String>,
}
impl SessionView {
pub fn new() -> SessionView {
SessionView {
account: None,
actor: None,
agent: None,
children: None,
created_at: None,
cwd: None,
ended_at: None,
events: None,
host: None,
id: None,
last_event: None,
org: None,
parent_session_id: None,
progress: None,
project: None,
provider: None,
published: None,
repo: None,
room: None,
root_session_id: None,
started_at: None,
status: None,
target: None,
task_run_id: None,
task_workflow_id: None,
terminal: None,
title: None,
updated_at: None,
}
}
}