mirror of
https://github.com/openai/codex.git
synced 2026-10-25 18:28:38 +00:00
Poll workspace messages on startup
This commit is contained in:
Generated
+1
@@ -3645,6 +3645,7 @@ dependencies = [
|
||||
"codex-app-server-client",
|
||||
"codex-app-server-protocol",
|
||||
"codex-arg0",
|
||||
"codex-backend-client",
|
||||
"codex-chatgpt",
|
||||
"codex-cli",
|
||||
"codex-cloud-requirements",
|
||||
|
||||
@@ -49,6 +49,43 @@ impl CodexWorkspaceMessagesResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod workspace_message_tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn workspace_messages_response_deserializes_headlines_and_announcements() {
|
||||
let response: CodexWorkspaceMessagesResponse = serde_json::from_value(serde_json::json!({
|
||||
"messages": [
|
||||
{
|
||||
"message_id": "headline-id",
|
||||
"message_type": "headline",
|
||||
"message_body": "Headline body"
|
||||
},
|
||||
{
|
||||
"message_id": "announcement-id",
|
||||
"message_type": "announcement",
|
||||
"message_body": "Announcement body"
|
||||
}
|
||||
]
|
||||
}))
|
||||
.expect("workspace messages response should deserialize");
|
||||
|
||||
let headlines = response
|
||||
.headlines()
|
||||
.map(|message| message.message_id.as_str())
|
||||
.collect::<Vec<_>>();
|
||||
let announcements = response
|
||||
.announcements()
|
||||
.map(|message| message.message_id.as_str())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(headlines, vec!["headline-id"]);
|
||||
assert_eq!(announcements, vec!["announcement-id"]);
|
||||
}
|
||||
}
|
||||
|
||||
/// Hand-rolled models for the Cloud Tasks task-details response.
|
||||
/// The generated OpenAPI models are pretty bad. This is a half-step
|
||||
/// towards hand-rolling them.
|
||||
|
||||
@@ -29,6 +29,7 @@ codex-ansi-escape = { workspace = true }
|
||||
codex-app-server-client = { workspace = true }
|
||||
codex-app-server-protocol = { workspace = true }
|
||||
codex-arg0 = { workspace = true }
|
||||
codex-backend-client = { workspace = true }
|
||||
codex-install-context = { workspace = true }
|
||||
codex-chatgpt = { workspace = true }
|
||||
codex-cloud-requirements = { workspace = true }
|
||||
|
||||
@@ -42,6 +42,7 @@ use codex_config::format_config_error_with_source;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_exec_server::EnvironmentManagerArgs;
|
||||
use codex_exec_server::ExecServerRuntimePaths;
|
||||
use codex_features::Feature;
|
||||
use codex_login::AuthConfig;
|
||||
use codex_login::default_client::set_default_client_residency_requirement;
|
||||
use codex_login::enforce_login_restrictions;
|
||||
@@ -190,6 +191,7 @@ mod version;
|
||||
mod voice;
|
||||
mod width;
|
||||
mod workspace_command;
|
||||
mod workspace_messages;
|
||||
#[cfg(target_os = "linux")]
|
||||
#[allow(dead_code)]
|
||||
mod voice {
|
||||
@@ -1106,6 +1108,9 @@ async fn run_ratatui_app(
|
||||
color_eyre::install()?;
|
||||
|
||||
tooltips::announcement::prewarm();
|
||||
if initial_config.features.enabled(Feature::WorkspaceMessages) {
|
||||
workspace_messages::prewarm_workspace_messages(&initial_config);
|
||||
}
|
||||
|
||||
// Forward panic reports through tracing so they appear in the UI status
|
||||
// line, but do not swallow the default/color-eyre panic handler.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
use crate::legacy_core::config::Config;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_backend_client::CodexWorkspaceMessagesResponse;
|
||||
use codex_login::AuthManager;
|
||||
use std::sync::OnceLock;
|
||||
use std::time::Duration;
|
||||
use tokio::time::timeout;
|
||||
|
||||
const WORKSPACE_MESSAGES_FETCH_TIMEOUT: Duration = Duration::from_millis(1000);
|
||||
|
||||
static WORKSPACE_MESSAGES: OnceLock<Option<CodexWorkspaceMessagesResponse>> = OnceLock::new();
|
||||
static WORKSPACE_MESSAGES_FETCH_STARTED: OnceLock<()> = OnceLock::new();
|
||||
|
||||
pub(crate) fn prewarm_workspace_messages(config: &Config) {
|
||||
if WORKSPACE_MESSAGES_FETCH_STARTED.set(()).is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
let config = config.clone();
|
||||
tokio::spawn(async move {
|
||||
let messages = timeout(
|
||||
WORKSPACE_MESSAGES_FETCH_TIMEOUT,
|
||||
fetch_workspace_messages(config),
|
||||
)
|
||||
.await
|
||||
.ok()
|
||||
.flatten();
|
||||
let _ = WORKSPACE_MESSAGES.set(messages);
|
||||
});
|
||||
}
|
||||
|
||||
async fn fetch_workspace_messages(config: Config) -> Option<CodexWorkspaceMessagesResponse> {
|
||||
let auth_manager =
|
||||
AuthManager::shared_from_config(&config, /*enable_codex_api_key_env*/ false).await;
|
||||
let auth = auth_manager.auth().await?;
|
||||
if !auth.uses_codex_backend() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let client = BackendClient::from_auth(config.chatgpt_base_url, &auth).ok()?;
|
||||
client.list_workspace_messages().await.ok()
|
||||
}
|
||||
Reference in New Issue
Block a user