@agent-native/core 0.94.0 → 0.94.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/docs/content/cloneable-saas.mdx +15 -15
  4. package/corpus/core/docs/content/creating-templates.mdx +1 -1
  5. package/corpus/core/docs/content/extensions.mdx +1 -1
  6. package/corpus/core/docs/content/local-file-mode.mdx +6 -6
  7. package/corpus/core/docs/content/locales/ar-SA/voice-input.mdx +2 -2
  8. package/corpus/core/docs/content/locales/de-DE/voice-input.mdx +2 -2
  9. package/corpus/core/docs/content/locales/es-ES/voice-input.mdx +2 -2
  10. package/corpus/core/docs/content/locales/fr-FR/voice-input.mdx +2 -2
  11. package/corpus/core/docs/content/locales/hi-IN/voice-input.mdx +2 -2
  12. package/corpus/core/docs/content/locales/ja-JP/voice-input.mdx +2 -2
  13. package/corpus/core/docs/content/locales/ko-KR/voice-input.mdx +2 -2
  14. package/corpus/core/docs/content/locales/pt-BR/voice-input.mdx +2 -2
  15. package/corpus/core/docs/content/locales/zh-CN/voice-input.mdx +2 -2
  16. package/corpus/core/docs/content/locales/zh-TW/voice-input.mdx +2 -2
  17. package/corpus/core/docs/content/sharing.mdx +4 -4
  18. package/corpus/core/docs/content/template-analytics.mdx +2 -2
  19. package/corpus/core/docs/content/template-calendar.mdx +4 -4
  20. package/corpus/core/docs/content/template-clips.mdx +2 -2
  21. package/corpus/core/docs/content/template-content.mdx +12 -11
  22. package/corpus/core/docs/content/template-mail.mdx +1 -1
  23. package/corpus/core/docs/content/template-slides.mdx +2 -2
  24. package/corpus/core/docs/content/voice-input.mdx +2 -2
  25. package/corpus/core/docs/content/workspace.mdx +1 -1
  26. package/corpus/core/package.json +1 -1
  27. package/corpus/core/src/client/AssistantChat.tsx +75 -1
  28. package/corpus/core/src/client/MultiTabAssistantChat.tsx +19 -1
  29. package/corpus/core/src/client/agent-chat.ts +6 -0
  30. package/corpus/core/src/client/composer/RealtimeVoiceMode.tsx +72 -2
  31. package/corpus/core/src/client/composer/realtime-voice-audio-level.ts +64 -0
  32. package/corpus/core/src/client/composer/realtime-voice-transcript.ts +134 -0
  33. package/corpus/core/src/client/composer/useRealtimeVoiceMode.tsx +220 -6
  34. package/corpus/core/src/client/use-chat-threads.ts +33 -9
  35. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +11 -5
  36. package/corpus/templates/clips/app/components/player/comments-panel.tsx +98 -1
  37. package/corpus/templates/clips/changelog/2026-07-10-comment-urls-open-as-clickable-links.md +6 -0
  38. package/corpus/templates/clips/changelog/2026-07-10-desktop-recording-uploads-now-show-a-brief-uploaded-state-wi.md +6 -0
  39. package/corpus/templates/clips/changelog/2026-07-10-desktop-recordings-now-retry-saving-their-locally-captured-t.md +6 -0
  40. package/corpus/templates/clips/changelog/2026-07-10-desktop-update-prompts-are-more-compact-and-easier-to-dismiss.md +6 -0
  41. package/corpus/templates/clips/changelog/2026-07-10-quiet-recordings-now-finish-saving-instead-of-getting-stuck.md +6 -0
  42. package/corpus/templates/clips/desktop/src/components/UpdateBanner.tsx +7 -4
  43. package/corpus/templates/clips/desktop/src/lib/recorder.ts +284 -85
  44. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +148 -40
  45. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +13 -13
  46. package/corpus/templates/clips/desktop/src/styles.css +83 -13
  47. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -28
  48. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +130 -65
  49. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +10 -4
  50. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +82 -1
  51. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +82 -1
  52. package/dist/client/AssistantChat.d.ts +6 -0
  53. package/dist/client/AssistantChat.d.ts.map +1 -1
  54. package/dist/client/AssistantChat.js +57 -1
  55. package/dist/client/AssistantChat.js.map +1 -1
  56. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  57. package/dist/client/MultiTabAssistantChat.js +9 -0
  58. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  59. package/dist/client/agent-chat.d.ts +6 -0
  60. package/dist/client/agent-chat.d.ts.map +1 -1
  61. package/dist/client/agent-chat.js.map +1 -1
  62. package/dist/client/composer/RealtimeVoiceMode.d.ts +3 -1
  63. package/dist/client/composer/RealtimeVoiceMode.d.ts.map +1 -1
  64. package/dist/client/composer/RealtimeVoiceMode.js +32 -3
  65. package/dist/client/composer/RealtimeVoiceMode.js.map +1 -1
  66. package/dist/client/composer/realtime-voice-audio-level.d.ts +14 -0
  67. package/dist/client/composer/realtime-voice-audio-level.d.ts.map +1 -0
  68. package/dist/client/composer/realtime-voice-audio-level.js +47 -0
  69. package/dist/client/composer/realtime-voice-audio-level.js.map +1 -0
  70. package/dist/client/composer/realtime-voice-transcript.d.ts +26 -0
  71. package/dist/client/composer/realtime-voice-transcript.d.ts.map +1 -0
  72. package/dist/client/composer/realtime-voice-transcript.js +103 -0
  73. package/dist/client/composer/realtime-voice-transcript.js.map +1 -0
  74. package/dist/client/composer/useRealtimeVoiceMode.d.ts +14 -0
  75. package/dist/client/composer/useRealtimeVoiceMode.d.ts.map +1 -1
  76. package/dist/client/composer/useRealtimeVoiceMode.js +177 -6
  77. package/dist/client/composer/useRealtimeVoiceMode.js.map +1 -1
  78. package/dist/client/use-chat-threads.d.ts.map +1 -1
  79. package/dist/client/use-chat-threads.js +26 -6
  80. package/dist/client/use-chat-threads.js.map +1 -1
  81. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  82. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +11 -5
  83. package/docs/content/cloneable-saas.mdx +15 -15
  84. package/docs/content/creating-templates.mdx +1 -1
  85. package/docs/content/extensions.mdx +1 -1
  86. package/docs/content/local-file-mode.mdx +6 -6
  87. package/docs/content/locales/ar-SA/voice-input.mdx +2 -2
  88. package/docs/content/locales/de-DE/voice-input.mdx +2 -2
  89. package/docs/content/locales/es-ES/voice-input.mdx +2 -2
  90. package/docs/content/locales/fr-FR/voice-input.mdx +2 -2
  91. package/docs/content/locales/hi-IN/voice-input.mdx +2 -2
  92. package/docs/content/locales/ja-JP/voice-input.mdx +2 -2
  93. package/docs/content/locales/ko-KR/voice-input.mdx +2 -2
  94. package/docs/content/locales/pt-BR/voice-input.mdx +2 -2
  95. package/docs/content/locales/zh-CN/voice-input.mdx +2 -2
  96. package/docs/content/locales/zh-TW/voice-input.mdx +2 -2
  97. package/docs/content/sharing.mdx +4 -4
  98. package/docs/content/template-analytics.mdx +2 -2
  99. package/docs/content/template-calendar.mdx +4 -4
  100. package/docs/content/template-clips.mdx +2 -2
  101. package/docs/content/template-content.mdx +12 -11
  102. package/docs/content/template-mail.mdx +1 -1
  103. package/docs/content/template-slides.mdx +2 -2
  104. package/docs/content/voice-input.mdx +2 -2
  105. package/docs/content/workspace.mdx +1 -1
  106. package/package.json +1 -1
  107. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +11 -5
@@ -147,6 +147,33 @@ impl NativeUploadMode {
147
147
  Self::Streaming => "streaming",
148
148
  }
149
149
  }
150
+
151
+ fn from_reset_response(body: &str) -> Self {
152
+ let value = serde_json::from_str::<serde_json::Value>(body).ok();
153
+ let upload_mode = value
154
+ .as_ref()
155
+ .and_then(|value| value.get("uploadMode"))
156
+ .and_then(serde_json::Value::as_str)
157
+ .map(str::to_string);
158
+ Self::from_option(upload_mode)
159
+ }
160
+ }
161
+
162
+ #[cfg(test)]
163
+ mod native_upload_mode_tests {
164
+ use super::NativeUploadMode;
165
+
166
+ #[test]
167
+ fn uses_streaming_mode_when_retry_session_was_recreated() {
168
+ assert_eq!(
169
+ NativeUploadMode::from_reset_response(r#"{"uploadMode":"streaming"}"#),
170
+ NativeUploadMode::Streaming,
171
+ );
172
+ assert_eq!(
173
+ NativeUploadMode::from_reset_response(r#"{"ok":true}"#),
174
+ NativeUploadMode::Buffered,
175
+ );
176
+ }
150
177
  }
151
178
 
152
179
  #[derive(Default)]
@@ -2061,25 +2088,45 @@ pub async fn native_fullscreen_recording_retry_upload(
2061
2088
  saved.last_error = None;
2062
2089
  write_saved_recording_metadata(&app, &saved)?;
2063
2090
 
2064
- reset_upload_chunks(
2065
- &saved.server_url,
2066
- &saved.recording_id,
2067
- auth_token.as_deref().unwrap_or(""),
2068
- cookie.as_deref().unwrap_or(""),
2069
- )
2070
- .await
2071
- .map_err(|err| {
2072
- persist_saved_recording_error(&app, &mut saved, &err);
2073
- err
2074
- })?;
2091
+ // Preparation can normalize or transcode the saved recording. The
2092
+ // resumable session must be created with the MIME type we will actually
2093
+ // upload, not the source file's potentially stale MIME type.
2094
+ let result = async {
2095
+ let (prepared, retry_combined_path) = prepare_saved_recording_file(&app, &saved)?;
2096
+ let upload_mode = match reset_upload_chunks(
2097
+ &saved.server_url,
2098
+ &saved.recording_id,
2099
+ &prepared.mime_type,
2100
+ auth_token.as_deref().unwrap_or(""),
2101
+ cookie.as_deref().unwrap_or(""),
2102
+ )
2103
+ .await
2104
+ {
2105
+ Ok(upload_mode) => upload_mode,
2106
+ Err(err) => {
2107
+ cleanup_prepared_saved_recording_files(&prepared, retry_combined_path);
2108
+ return Err(err);
2109
+ }
2110
+ };
2075
2111
 
2076
- let result = upload_saved_recording_file(
2077
- &app,
2078
- &saved,
2079
- saved.server_url.clone(),
2080
- auth_token.unwrap_or_default(),
2081
- cookie.unwrap_or_default(),
2082
- )
2112
+ let upload_result = upload_prepared_recording_file(
2113
+ &app,
2114
+ &prepared,
2115
+ saved.server_url.clone(),
2116
+ saved.recording_id.clone(),
2117
+ auth_token.unwrap_or_default(),
2118
+ cookie.unwrap_or_default(),
2119
+ upload_mode,
2120
+ saved.duration_ms,
2121
+ saved.width,
2122
+ saved.height,
2123
+ saved.has_audio,
2124
+ saved.has_camera,
2125
+ )
2126
+ .await;
2127
+ cleanup_prepared_saved_recording_files(&prepared, retry_combined_path);
2128
+ upload_result
2129
+ }
2083
2130
  .await;
2084
2131
 
2085
2132
  match result {
@@ -3236,29 +3283,10 @@ async fn upload_recording_file(
3236
3283
  upload_result
3237
3284
  }
3238
3285
 
3239
- async fn upload_saved_recording_file(
3240
- app: &AppHandle,
3241
- saved: &SavedNativeRecording,
3242
- server_url: String,
3243
- auth_token: String,
3244
- cookie: String,
3245
- ) -> Result<NativeFullscreenUploadResult, String> {
3246
- let (prepared, retry_combined_path) = prepare_saved_recording_file(app, saved)?;
3247
- let upload_result = upload_prepared_recording_file(
3248
- app,
3249
- &prepared,
3250
- server_url,
3251
- saved.recording_id.clone(),
3252
- auth_token,
3253
- cookie,
3254
- NativeUploadMode::Buffered,
3255
- saved.duration_ms,
3256
- saved.width,
3257
- saved.height,
3258
- saved.has_audio,
3259
- saved.has_camera,
3260
- )
3261
- .await;
3286
+ fn cleanup_prepared_saved_recording_files(
3287
+ prepared: &PreparedRecordingFile,
3288
+ retry_combined_path: Option<PathBuf>,
3289
+ ) {
3262
3290
  if prepared.temporary {
3263
3291
  let _ = std::fs::remove_file(&prepared.path);
3264
3292
  }
@@ -3267,7 +3295,6 @@ async fn upload_saved_recording_file(
3267
3295
  let _ = std::fs::remove_file(path);
3268
3296
  }
3269
3297
  }
3270
- upload_result
3271
3298
  }
3272
3299
 
3273
3300
  fn prepare_saved_recording_file(
@@ -3509,9 +3536,10 @@ async fn upload_prepared_recording_file(
3509
3536
  async fn reset_upload_chunks(
3510
3537
  server_url: &str,
3511
3538
  recording_id: &str,
3539
+ mime_type: &str,
3512
3540
  auth_token: &str,
3513
3541
  cookie: &str,
3514
- ) -> Result<(), String> {
3542
+ ) -> Result<NativeUploadMode, String> {
3515
3543
  let base = server_url.trim_end_matches('/');
3516
3544
  let url = url::Url::parse(&format!("{base}/api/uploads/{recording_id}/reset-chunks"))
3517
3545
  .map_err(|e| format!("invalid reset URL: {e}"))?;
@@ -3523,7 +3551,10 @@ async fn reset_upload_chunks(
3523
3551
  .post(url)
3524
3552
  .header("Content-Type", "application/json")
3525
3553
  .header("X-Request-Source", "clips-desktop")
3526
- .body("{}");
3554
+ .json(&serde_json::json!({
3555
+ "requestStreaming": true,
3556
+ "mimeType": mime_type,
3557
+ }));
3527
3558
  let trimmed_token = auth_token.trim();
3528
3559
  if !trimmed_token.is_empty() {
3529
3560
  request = request.bearer_auth(trimmed_token);
@@ -3545,7 +3576,7 @@ async fn reset_upload_chunks(
3545
3576
  body.chars().take(400).collect::<String>()
3546
3577
  ));
3547
3578
  }
3548
- Ok(())
3579
+ Ok(NativeUploadMode::from_reset_response(&body))
3549
3580
  }
3550
3581
 
3551
3582
  async fn upload_thumbnail_bytes(
@@ -3912,6 +3943,27 @@ impl AudioSignalProbe {
3912
3943
  }
3913
3944
  }
3914
3945
 
3946
+ #[derive(Clone, Copy, Debug, PartialEq, Eq)]
3947
+ enum PreparedAudioSignalDecision {
3948
+ AcceptCandidate,
3949
+ UseOriginal,
3950
+ }
3951
+
3952
+ fn decide_prepared_audio_signal(
3953
+ candidate: AudioSignalProbe,
3954
+ source: Option<AudioSignalProbe>,
3955
+ ) -> PreparedAudioSignalDecision {
3956
+ if !candidate.has_audible_signal()
3957
+ && source
3958
+ .map(AudioSignalProbe::has_audible_signal)
3959
+ .unwrap_or(false)
3960
+ {
3961
+ PreparedAudioSignalDecision::UseOriginal
3962
+ } else {
3963
+ PreparedAudioSignalDecision::AcceptCandidate
3964
+ }
3965
+ }
3966
+
3915
3967
  fn parse_ffmpeg_volume_db(stderr: &str, label: &str) -> Option<f64> {
3916
3968
  stderr.lines().rev().find_map(|line| {
3917
3969
  let (_, value) = line.split_once(label)?;
@@ -3988,14 +4040,11 @@ fn verify_prepared_audio_signal(
3988
4040
  }
3989
4041
 
3990
4042
  let source_probe = audio_signal_probe_with_ffmpeg(ffmpeg_path, source_path);
3991
- let source_has_signal = source_probe
3992
- .as_ref()
3993
- .ok()
3994
- .copied()
3995
- .map(AudioSignalProbe::has_audible_signal)
3996
- .unwrap_or(false);
4043
+ let source_signal = source_probe.as_ref().ok().copied();
3997
4044
  let source_summary = describe_audio_signal_probe(source_probe);
3998
- if source_has_signal {
4045
+ if decide_prepared_audio_signal(candidate_probe, source_signal)
4046
+ == PreparedAudioSignalDecision::UseOriginal
4047
+ {
3999
4048
  eprintln!(
4000
4049
  "[clips-tray] AUDIO QUIET AFTER PREPARE: {label} is effectively silent ({}) but original has signal ({source_summary}) — uploading original instead",
4001
4050
  candidate_probe.summary()
@@ -4004,13 +4053,14 @@ fn verify_prepared_audio_signal(
4004
4053
  }
4005
4054
 
4006
4055
  eprintln!(
4007
- "[clips-tray] AUDIO CAPTURE TOO QUIET: prepared {label} has an audio track but no usable signal ({}) and original was not usable either ({source_summary})",
4056
+ "[clips-tray] AUDIO CAPTURE QUIET: prepared {label} has an audio track but no usable signal ({}) and original was not usable either ({source_summary}) — publishing the playable candidate",
4008
4057
  candidate_probe.summary()
4009
4058
  );
4010
- Err(format!(
4011
- "Recorded file contains an audio track, but the captured audio is too quiet to publish ({})",
4012
- candidate_probe.summary()
4013
- ))
4059
+ // Silence in both files is a capture outcome, not a processing regression.
4060
+ // Rejecting it strands the recording in `uploading`, and every retry fails
4061
+ // deterministically after re-running the same probes. Only fall back when
4062
+ // preparation removed signal that was present in the source.
4063
+ Ok(None)
4014
4064
  }
4015
4065
 
4016
4066
  fn prepare_recording_file(
@@ -4069,13 +4119,6 @@ fn prepare_recording_file(
4069
4119
 
4070
4120
  let mut smallest_attempt_bytes: Option<u64> = None;
4071
4121
  let ffmpeg_path = resolve_ffmpeg_path();
4072
- if has_audio {
4073
- if let Some(ffmpeg_path) = ffmpeg_path.as_deref() {
4074
- let raw_summary =
4075
- describe_audio_signal_probe(audio_signal_probe_with_ffmpeg(ffmpeg_path, path));
4076
- eprintln!("[clips-tray] raw recording audio signal before prepare: {raw_summary}");
4077
- }
4078
- }
4079
4122
 
4080
4123
  if !COMPRESSION_ENABLED || source_bytes < TRANSCODE_THRESHOLD_BYTES {
4081
4124
  if has_audio {
@@ -5125,7 +5168,8 @@ fn concat_mp4_segments(segments: &[PathBuf], output: &Path) -> Result<(), String
5125
5168
  #[cfg(test)]
5126
5169
  mod audio_track_probe_tests {
5127
5170
  use super::{
5128
- audio_filter_chain, mp4_has_audio_track, parse_ffmpeg_volume_db, AudioSignalProbe,
5171
+ audio_filter_chain, decide_prepared_audio_signal, mp4_has_audio_track,
5172
+ parse_ffmpeg_volume_db, AudioSignalProbe, PreparedAudioSignalDecision,
5129
5173
  AUDIO_DENOISE_FILTER, AUDIO_DOWNMIX_FILTER, AUDIO_DOWNMIX_MAKEUP_FILTER,
5130
5174
  AUDIO_LOUDNESS_FILTER, AUDIO_MIC_PREGAIN_FILTER,
5131
5175
  };
@@ -5301,6 +5345,27 @@ mod audio_track_probe_tests {
5301
5345
  assert!(!quiet_noise_peak.has_audible_signal());
5302
5346
  assert!(audible.has_audible_signal());
5303
5347
  }
5348
+
5349
+ #[test]
5350
+ fn publishes_quiet_recordings_but_preserves_audible_source_audio() {
5351
+ let silent = AudioSignalProbe {
5352
+ mean_volume_db: Some(f64::NEG_INFINITY),
5353
+ max_volume_db: Some(f64::NEG_INFINITY),
5354
+ };
5355
+ let audible = AudioSignalProbe {
5356
+ mean_volume_db: Some(-21.5),
5357
+ max_volume_db: Some(-1.4),
5358
+ };
5359
+
5360
+ assert_eq!(
5361
+ decide_prepared_audio_signal(silent, Some(silent)),
5362
+ PreparedAudioSignalDecision::AcceptCandidate,
5363
+ );
5364
+ assert_eq!(
5365
+ decide_prepared_audio_signal(silent, Some(audible)),
5366
+ PreparedAudioSignalDecision::UseOriginal,
5367
+ );
5368
+ }
5304
5369
  }
5305
5370
 
5306
5371
  #[cfg(test)]
@@ -64,7 +64,8 @@ pub fn show_meeting_notification_window(app: &AppHandle) -> Result<(), String> {
64
64
  return Ok(());
65
65
  }
66
66
 
67
- let win = WebviewWindowBuilder::new(
67
+ #[allow(unused_mut)]
68
+ let mut builder = WebviewWindowBuilder::new(
68
69
  app,
69
70
  MEETING_NOTIFICATION_LABEL,
70
71
  build_overlay_url("meeting-notif"),
@@ -77,9 +78,14 @@ pub fn show_meeting_notification_window(app: &AppHandle) -> Result<(), String> {
77
78
  .resizable(false)
78
79
  .shadow(false)
79
80
  .visible(false)
80
- .focused(false)
81
- .build()
82
- .map_err(|e| {
81
+ .focused(false);
82
+ // The reminder remains non-activating, but its first click should still
83
+ // reach the webview instead of only activating the window.
84
+ #[cfg(target_os = "macos")]
85
+ {
86
+ builder = builder.accept_first_mouse(true);
87
+ }
88
+ let win = builder.build().map_err(|e| {
83
89
  eprintln!("[clips-tray] meeting notification build failed: {e}");
84
90
  e.to_string()
85
91
  })?;
@@ -832,6 +832,57 @@ async function handleResumableChunk(
832
832
  return { ok: true, finalized: true, ...result };
833
833
  } catch (err) {
834
834
  console.error(`[resumable-chunk-${recordingId}] finalize failed:`, err);
835
+ const db = getDb();
836
+ const [committed] = await db
837
+ .select({
838
+ id: schema.recordings.id,
839
+ status: schema.recordings.status,
840
+ videoUrl: schema.recordings.videoUrl,
841
+ durationMs: schema.recordings.durationMs,
842
+ width: schema.recordings.width,
843
+ height: schema.recordings.height,
844
+ hasAudio: schema.recordings.hasAudio,
845
+ hasCamera: schema.recordings.hasCamera,
846
+ })
847
+ .from(schema.recordings)
848
+ .where(
849
+ and(
850
+ eq(schema.recordings.id, recordingId),
851
+ ownerEmailMatches(schema.recordings.ownerEmail, ownerEmail),
852
+ ),
853
+ );
854
+ if (committed?.status === "ready" && committed.videoUrl) {
855
+ console.warn(
856
+ `[resumable-chunk-${recordingId}] finalize reported an error after committing a ready recording; returning committed success.`,
857
+ { error: err instanceof Error ? err.message : String(err) },
858
+ );
859
+ await writeAppState(`recording-upload-${recordingId}`, {
860
+ recordingId,
861
+ status: "ready",
862
+ progress: 100,
863
+ videoUrl: committed.videoUrl,
864
+ finishedAt: new Date().toISOString(),
865
+ }).catch((stateErr) =>
866
+ console.warn(
867
+ `[resumable-chunk-${recordingId}] committed-ready state repair failed:`,
868
+ stateErr,
869
+ ),
870
+ );
871
+ return {
872
+ ok: true,
873
+ finalized: true,
874
+ recoveredAfterFinalizeError: true,
875
+ id: committed.id,
876
+ status: "ready",
877
+ videoUrl: committed.videoUrl,
878
+ durationMs: committed.durationMs,
879
+ width: committed.width,
880
+ height: committed.height,
881
+ hasAudio: committed.hasAudio,
882
+ hasCamera: committed.hasCamera,
883
+ };
884
+ }
885
+
835
886
  trackUploadBlockingFailure(ownerEmail, {
836
887
  stage: "finalize_recording",
837
888
  failureKind: "finalize_error",
@@ -839,10 +890,40 @@ async function handleResumableChunk(
839
890
  uploadMode: "resumable",
840
891
  errorMessage: err instanceof Error ? err.message : String(err),
841
892
  });
893
+ const failureReason =
894
+ err instanceof Error ? err.message : "Finalize failed";
895
+ const failedAt = new Date().toISOString();
896
+ await db
897
+ .update(schema.recordings)
898
+ .set({
899
+ status: "failed",
900
+ failureReason,
901
+ updatedAt: failedAt,
902
+ })
903
+ .where(
904
+ and(
905
+ eq(schema.recordings.id, recordingId),
906
+ ownerEmailMatches(schema.recordings.ownerEmail, ownerEmail),
907
+ ),
908
+ );
909
+ const failedUploadStateRaw = await readAppState(
910
+ `recording-upload-${recordingId}`,
911
+ ).catch(() => null);
912
+ const failedUploadState =
913
+ failedUploadStateRaw && typeof failedUploadStateRaw === "object"
914
+ ? (failedUploadStateRaw as Record<string, unknown>)
915
+ : {};
916
+ await writeAppState(`recording-upload-${recordingId}`, {
917
+ ...failedUploadState,
918
+ recordingId,
919
+ status: "failed",
920
+ failureReason,
921
+ updatedAt: failedAt,
922
+ });
842
923
  setResponseStatus(event, 500);
843
924
  return {
844
925
  ok: false,
845
- error: err instanceof Error ? err.message : "Finalize failed",
926
+ error: failureReason,
846
927
  };
847
928
  }
848
929
  }
@@ -28,7 +28,9 @@ import {
28
28
  writeAppState,
29
29
  deleteAppStateByPrefix,
30
30
  } from "@agent-native/core/application-state";
31
+ import { getActiveFileUploadProviderForRequest } from "@agent-native/core/file-upload";
31
32
  import { runWithRequestContext } from "@agent-native/core/server";
33
+ import type { UploadMode } from "@shared/recording-core.js";
32
34
  import { MAX_UPLOAD_BYTES as MAX_RECORDING_UPLOAD_BYTES } from "@shared/upload-limits.js";
33
35
  import { and, eq } from "drizzle-orm";
34
36
  import {
@@ -44,7 +46,12 @@ import {
44
46
  getEventOwnerContext,
45
47
  ownerEmailMatches,
46
48
  } from "../../../../lib/recordings.js";
47
- import { deleteResumableSession } from "../../../../lib/resumable-session.js";
49
+ import {
50
+ deleteResumableSession,
51
+ setResumableSession,
52
+ } from "../../../../lib/resumable-session.js";
53
+ import { shouldEnableStreamingUpload } from "../../../../lib/streaming-upload-mode.js";
54
+ import { allowsSqlRecordingChunkScratch } from "../../../../lib/video-storage.js";
48
55
 
49
56
  interface CompressionMeta {
50
57
  originalBytes?: number;
@@ -54,6 +61,16 @@ interface CompressionMeta {
54
61
  outputMimeType?: string;
55
62
  }
56
63
 
64
+ function normalizeVideoMimeType(value: unknown): string | null {
65
+ if (typeof value !== "string") return null;
66
+ const mimeType = value.split(";")[0]?.trim().toLowerCase();
67
+ return mimeType === "video/mp4" ||
68
+ mimeType === "video/quicktime" ||
69
+ mimeType === "video/webm"
70
+ ? mimeType
71
+ : null;
72
+ }
73
+
57
74
  function pickNumber(value: unknown): number | undefined {
58
75
  if (typeof value !== "number") return undefined;
59
76
  if (!Number.isFinite(value) || value < 0) return undefined;
@@ -77,6 +94,8 @@ export default defineEventHandler(async (event: H3Event) => {
77
94
  const { userEmail: ownerEmail, orgId } = await getEventOwnerContext(event);
78
95
  const body = (await readBody(event).catch(() => null)) as {
79
96
  compression?: CompressionMeta | null;
97
+ requestStreaming?: boolean;
98
+ mimeType?: string;
80
99
  } | null;
81
100
 
82
101
  // Sanitize compression metadata. The recorder is the only client we trust
@@ -117,6 +136,67 @@ export default defineEventHandler(async (event: H3Event) => {
117
136
  // accidentally route through handleResumableChunk with stale offsets.
118
137
  await deleteResumableSession(recordingId).catch(() => {});
119
138
 
139
+ let uploadMode: UploadMode = "buffered";
140
+ if (body?.requestStreaming === true) {
141
+ const mimeType = normalizeVideoMimeType(body.mimeType);
142
+ if (!mimeType) {
143
+ setResponseStatus(event, 400);
144
+ return { error: "A supported video mimeType is required for retry" };
145
+ }
146
+
147
+ const bufferedFallbackAvailable = allowsSqlRecordingChunkScratch();
148
+ const uploadProvider = await getActiveFileUploadProviderForRequest();
149
+ if (
150
+ shouldEnableStreamingUpload({
151
+ client: "desktop",
152
+ mimeType,
153
+ bufferedFallbackAvailable,
154
+ }) &&
155
+ uploadProvider?.resumable
156
+ ) {
157
+ try {
158
+ const extension = /mp4|quicktime/.test(mimeType) ? "mp4" : "webm";
159
+ const filename = `${recordingId}.${extension}`;
160
+ const session = await uploadProvider.resumable.startSession(
161
+ filename,
162
+ mimeType,
163
+ MAX_RECORDING_UPLOAD_BYTES,
164
+ );
165
+ await setResumableSession(recordingId, {
166
+ providerId: uploadProvider.id,
167
+ sessionId: session.sessionId,
168
+ meta: {
169
+ ...session.meta,
170
+ stableUrl: true,
171
+ recordAsset: false,
172
+ },
173
+ bytesUploaded: 0,
174
+ lastCommittedIndex: -1,
175
+ });
176
+ uploadMode = "streaming";
177
+ } catch (err) {
178
+ if (!bufferedFallbackAvailable) {
179
+ setResponseStatus(event, 502);
180
+ return {
181
+ error: `Could not restart recording upload: ${
182
+ err instanceof Error ? err.message : String(err)
183
+ }`,
184
+ };
185
+ }
186
+ console.warn(
187
+ `[reset-chunks-${recordingId}] resumable restart failed; using buffered retry:`,
188
+ err,
189
+ );
190
+ }
191
+ } else if (!bufferedFallbackAvailable) {
192
+ setResponseStatus(event, 409);
193
+ return {
194
+ error:
195
+ "Recording upload storage could not start a resumable retry session.",
196
+ };
197
+ }
198
+ }
199
+
120
200
  // Reset the per-recording upload progress so the UI poller sees the
121
201
  // re-upload restart from 0 and doesn't briefly show "100% then
122
202
  // re-running" on the post-compression chunked upload pass.
@@ -158,6 +238,7 @@ export default defineEventHandler(async (event: H3Event) => {
158
238
  recordingId,
159
239
  chunksCleared: cleared,
160
240
  compressionRecorded: !!compression,
241
+ uploadMode,
161
242
  };
162
243
  });
163
244
  });
@@ -34,6 +34,12 @@ export declare function reconnectProgressTimedOut(args: {
34
34
  now: number;
35
35
  thresholdMs?: number;
36
36
  }): boolean;
37
+ export declare function assistantMessageRunId(message: unknown): string | undefined;
38
+ export declare function shouldAcceptRunError(args: {
39
+ errorRunId?: string;
40
+ activeRunId?: string;
41
+ latestAssistantRunId?: string;
42
+ }): boolean;
37
43
  export declare function settleInterruptedAssistantToolCallsInRepo<T extends {
38
44
  messages?: unknown[];
39
45
  }>(repo: T): {
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/AssistantChat.tsx"],"names":[],"mappings":"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"}