core: type streaming session timestamps

This commit is contained in:
a.tolmachev
2026-04-13 05:47:42 +00:00
parent edf318ba67
commit 03cb109b40
10 changed files with 254 additions and 228 deletions
+30 -28
View File
@@ -741,8 +741,8 @@ async fn handle_session_start_call(
let next_index = preview_count;
let session_id =
StreamSessionId::new(format!("sess_{}", uuid::Uuid::now_v7().simple()));
let now = now_rfc3339();
let expires_at = add_millis(&now, streaming.max_session_lifetime_ms.unwrap_or(60_000));
let now = OffsetDateTime::now_utc();
let expires_at = add_millis(now, streaming.max_session_lifetime_ms.unwrap_or(60_000));
let session_record = StreamSession {
id: session_id.clone(),
workspace_id: tool.workspace_id.clone(),
@@ -759,9 +759,9 @@ async fn handle_session_start_call(
next_index,
batch_size,
}),
expires_at: expires_at.clone(),
last_poll_at: Some(now.clone()),
created_at: now.clone(),
expires_at,
last_poll_at: Some(now),
created_at: now,
closed_at: None,
};
@@ -778,7 +778,7 @@ async fn handle_session_start_call(
let output = json!({
"session_id": session_id.as_str(),
"status": "running",
"expires_at": expires_at,
"expires_at": format_rfc3339(expires_at),
"poll_after_ms": streaming.poll_interval_ms.unwrap_or(1000),
"preview": {
"summary": seed.summary,
@@ -873,7 +873,7 @@ async fn handle_session_poll_call(
);
};
let now = now_rfc3339();
let now = OffsetDateTime::now_utc();
let loaded = match state
.registry
.get_stream_session(&StreamSessionId::new(control.session_id.clone()))
@@ -902,7 +902,7 @@ async fn handle_session_poll_call(
);
}
if loaded.is_expired(&now) {
if loaded.is_expired(now) {
let _ = state
.registry
.update_stream_session_state(UpdateStreamSessionStateRequest {
@@ -926,7 +926,7 @@ async fn handle_session_poll_call(
);
}
if !loaded.can_poll(&now) {
if !loaded.can_poll(now) {
return tool_error_response(
message,
response_mode,
@@ -970,11 +970,11 @@ async fn handle_session_poll_call(
cursor: cursor.as_ref(),
state: &json!(state_payload),
expires_at: Some(&add_millis(
&now,
now,
streaming.max_session_lifetime_ms.unwrap_or(60_000),
)),
last_poll_at: Some(&now),
closed_at: matches!(next_status, StreamStatus::Stopped).then_some(now.as_str()),
closed_at: matches!(next_status, StreamStatus::Stopped).then_some(&now),
})
.await
{
@@ -985,7 +985,7 @@ async fn handle_session_poll_call(
let output = json!({
"session_id": updated.id.as_str(),
"status": serialize_stream_status(updated.status),
"expires_at": updated.expires_at,
"expires_at": format_rfc3339(updated.expires_at),
"summary": serde_json::from_value::<StoredSessionState>(updated.state.clone()).map(|value| value.summary).unwrap_or(Value::Null),
"items": items,
"cursor": updated.cursor,
@@ -1069,7 +1069,7 @@ async fn handle_session_stop_call(
.registry
.close_stream_session(
&StreamSessionId::new(control.session_id.clone()),
&now_rfc3339(),
&OffsetDateTime::now_utc(),
)
.await
{
@@ -1106,7 +1106,7 @@ async fn handle_async_job_start_call(
);
};
let now = now_rfc3339();
let now = OffsetDateTime::now_utc();
let job = AsyncJobHandle {
id: AsyncJobId::new(format!("job_{}", uuid::Uuid::now_v7().simple())),
workspace_id: tool.workspace_id.clone(),
@@ -1117,11 +1117,11 @@ async fn handle_async_job_start_call(
result: None,
error: None,
expires_at: Some(add_millis(
&now,
now,
streaming.max_session_lifetime_ms.unwrap_or(300_000),
)),
created_at: now.clone(),
updated_at: now.clone(),
created_at: now,
updated_at: now,
finished_at: None,
};
@@ -1156,7 +1156,7 @@ async fn handle_async_job_start_call(
}
Err(error) => Err(error),
};
let finished_at = now_rfc3339();
let finished_at = OffsetDateTime::now_utc();
let update_result = match result {
Ok(output) => {
@@ -1424,7 +1424,10 @@ async fn handle_async_job_cancel_call(
match state
.registry
.cancel_async_job(&AsyncJobId::new(control.job_id.clone()), &now_rfc3339())
.cancel_async_job(
&AsyncJobId::new(control.job_id.clone()),
&OffsetDateTime::now_utc(),
)
.await
{
Ok(()) => success_tool_response(
@@ -1909,21 +1912,20 @@ fn tool_error_response(
)
}
fn now_rfc3339() -> String {
OffsetDateTime::now_utc()
fn format_rfc3339(timestamp: OffsetDateTime) -> String {
timestamp
.format(&Rfc3339)
.unwrap_or_else(|_| "1970-01-01T00:00:00Z".to_owned())
}
fn add_millis(timestamp: &str, millis: u64) -> String {
let Ok(parsed) = OffsetDateTime::parse(timestamp, &Rfc3339) else {
return timestamp.to_owned();
};
fn now_rfc3339() -> String {
format_rfc3339(OffsetDateTime::now_utc())
}
fn add_millis(timestamp: OffsetDateTime, millis: u64) -> OffsetDateTime {
let delta = time::Duration::milliseconds(i64::try_from(millis).unwrap_or(i64::MAX));
(parsed + delta)
.format(&Rfc3339)
.unwrap_or_else(|_| timestamp.to_owned())
timestamp + delta
}
fn serialize_stream_status(status: StreamStatus) -> &'static str {