Skip to content

Commit 17a87ba

Browse files
gpui: carry the capture marker's automatic / audio / title fields
main's #7444 added automatic, preserveExistingAudio and initialTitle to CaptureLifecycleMarker. The shell writes them for its manual captures (false / true / the session title at start), parses them from the web view's markers and keeps them through recovery, so both shells read each other's markers unchanged. Co-authored-by: John Jeong <ComputelessComputer@users.noreply.github.com>
1 parent 01c634e commit 17a87ba

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

‎apps/desktop-gpui/src/capture_marker.rs‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ pub struct Marker {
3434
pub created_at: String,
3535
pub audio_offset_ms: i64,
3636
pub preserve_existing_transcript: bool,
37+
/// A scheduled auto-start (`startedAutomatically`); the shell only
38+
/// records manual captures.
39+
#[serde(default, skip_serializing_if = "Option::is_none")]
40+
pub automatic: Option<bool>,
41+
/// Whether audio existed before the capture (always kept for manual ones).
42+
#[serde(default, skip_serializing_if = "Option::is_none")]
43+
pub preserve_existing_audio: Option<bool>,
44+
/// The session title when the capture started.
45+
#[serde(default, skip_serializing_if = "Option::is_none")]
46+
pub initial_title: Option<String>,
3747
pub owner_user_id: String,
3848
pub memo: String,
3949
#[serde(default, skip_serializing_if = "Option::is_none")]
@@ -85,6 +95,9 @@ pub fn parse(value: &str, session_id: &str) -> Option<Marker> {
8595
created_at,
8696
audio_offset_ms,
8797
preserve_existing_transcript,
98+
automatic: raw.get("automatic").and_then(|v| v.as_bool()),
99+
preserve_existing_audio: raw.get("preserveExistingAudio").and_then(|v| v.as_bool()),
100+
initial_title: optional_string("initialTitle"),
88101
owner_user_id,
89102
memo,
90103
provider: optional_string("provider"),
@@ -152,6 +165,9 @@ mod tests {
152165
created_at: "2026-09-07T09:00:00.000Z".into(),
153166
audio_offset_ms: 0,
154167
preserve_existing_transcript: false,
168+
automatic: Some(false),
169+
preserve_existing_audio: Some(true),
170+
initial_title: Some("Standup".into()),
155171
owner_user_id: "u1".into(),
156172
memo: String::new(),
157173
provider: Some("deepgram".into()),
@@ -166,7 +182,7 @@ mod tests {
166182
let json = serde_json::to_string(&marker()).unwrap();
167183
assert_eq!(
168184
json,
169-
r#"{"version":1,"phase":"capturing","sessionId":"s1","transcriptId":"t1","startedAt":1700000000000,"createdAt":"2026-09-07T09:00:00.000Z","audioOffsetMs":0,"preserveExistingTranscript":false,"ownerUserId":"u1","memo":"","provider":"deepgram","model":"nova-3"}"#
185+
r#"{"version":1,"phase":"capturing","sessionId":"s1","transcriptId":"t1","startedAt":1700000000000,"createdAt":"2026-09-07T09:00:00.000Z","audioOffsetMs":0,"preserveExistingTranscript":false,"automatic":false,"preserveExistingAudio":true,"initialTitle":"Standup","ownerUserId":"u1","memo":"","provider":"deepgram","model":"nova-3"}"#
170186
);
171187
let mut finalizing = marker();
172188
finalizing.phase = Some(Phase::Finalizing);

‎apps/desktop-gpui/src/db.rs‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ impl ProviderSettings {
518518
#[derive(Debug, Clone, Default, PartialEq, Eq)]
519519
pub struct CaptureContext {
520520
pub owner_user_id: String,
521+
/// `initialTitle`: the session title when the capture starts.
522+
pub initial_title: Option<String>,
521523
pub participant_human_ids: Vec<String>,
522524
pub preserve_existing_transcript: bool,
523525
pub existing_audio_ms: i64,
@@ -3198,13 +3200,16 @@ impl Store {
31983200
let db = self.db.clone();
31993201
let session_dir = self.session_dir(&session_id);
32003202
self.runtime.spawn(async move {
3201-
let owner_user_id: String = sqlx::query_scalar(
3202-
"SELECT COALESCE(owner_user_id, '') FROM sessions WHERE id = ? AND deleted_at IS NULL",
3203+
let session: Option<(String, String)> = sqlx::query_as(
3204+
"SELECT COALESCE(owner_user_id, ''), title FROM sessions WHERE id = ? AND deleted_at IS NULL",
32033205
)
32043206
.bind(&session_id)
32053207
.fetch_optional(db.pool())
3206-
.await?
3207-
.unwrap_or_default();
3208+
.await?;
3209+
let (owner_user_id, initial_title) = match session {
3210+
Some((owner, title)) => (owner, Some(title)),
3211+
None => (String::new(), None),
3212+
};
32083213
let participant_human_ids: Vec<String> = sqlx::query_scalar(PARTICIPANT_HUMAN_IDS_SQL)
32093214
.bind(&session_id)
32103215
.fetch_all(db.pool())
@@ -3228,6 +3233,7 @@ impl Store {
32283233
};
32293234
Ok(CaptureContext {
32303235
owner_user_id,
3236+
initial_title,
32313237
participant_human_ids,
32323238
preserve_existing_transcript: has_transcript,
32333239
existing_audio_ms,

‎apps/desktop-gpui/src/workspace/recording.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ pub(crate) struct CaptureLifecycle {
209209
pub transcript_touched: bool,
210210
/// `ownerUserId` for the recovery marker.
211211
pub owner_user_id: String,
212+
/// `initialTitle` for the recovery marker.
213+
pub initial_title: Option<String>,
212214
}
213215

214216
impl CaptureLifecycle {
@@ -229,6 +231,10 @@ impl CaptureLifecycle {
229231
created_at: persistence.created_at.clone(),
230232
audio_offset_ms: self.existing_audio_ms.max(0),
231233
preserve_existing_transcript: self.preserve_existing_transcript,
234+
// The shell records manual captures only, which keep prior audio.
235+
automatic: Some(false),
236+
preserve_existing_audio: Some(true),
237+
initial_title: self.initial_title.clone(),
232238
owner_user_id: self.owner_user_id.clone(),
233239
memo: persistence.memo.clone(),
234240
provider: Some(persistence.provider.clone()).filter(|p| !p.is_empty()),
@@ -1252,6 +1258,7 @@ impl Workspace {
12521258
needs_batch_repair: true,
12531259
transcript_touched: created,
12541260
owner_user_id: marker.owner_user_id.clone(),
1261+
initial_title: marker.initial_title.clone(),
12551262
};
12561263
let recovered_summary_mode = marker.summary_mode.map(|mode| match mode {
12571264
crate::capture_marker::SummaryMode::Regenerate => {
@@ -1556,6 +1563,7 @@ impl Workspace {
15561563
needs_batch_repair: false,
15571564
transcript_touched: false,
15581565
owner_user_id: context.owner_user_id.clone(),
1566+
initial_title: context.initial_title.clone(),
15591567
},
15601568
});
15611569
// `lifecycle.persistMarker()`: the durable capture state

0 commit comments

Comments
 (0)