mirror of
https://github.com/openai/codex.git
synced 2026-10-21 12:10:06 +00:00
Track app/read request duration (#35048)
## What changed - Record `codex.apps.read.duration_ms` when `app/read` returns a response. - Tag the duration by the request's `include_tools` value. - Move the `app/read` handler into its own request-processor module. GitOrigin-RevId: e1563cd41c72ad03e7f5d5d33cd8a3b35e27984b
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
use super::*;
|
||||
use crate::app_info::app_info_to_api;
|
||||
use crate::app_info::connector_metadata_to_api;
|
||||
|
||||
mod installed;
|
||||
mod read;
|
||||
|
||||
pub(super) use read::APP_READ_MAX_IDS;
|
||||
|
||||
pub(crate) struct AppsRequestProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
@@ -35,80 +37,6 @@ impl AppsRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn apps_read(
|
||||
&self,
|
||||
params: AppsReadParams,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
let AppsReadParams {
|
||||
app_ids,
|
||||
include_tools,
|
||||
} = params;
|
||||
if app_ids.len() > APP_READ_MAX_IDS {
|
||||
return Err(invalid_params(format!(
|
||||
"app/read accepts at most {APP_READ_MAX_IDS} appIds"
|
||||
)));
|
||||
}
|
||||
|
||||
let mut seen_app_ids = HashSet::new();
|
||||
let app_ids = app_ids
|
||||
.into_iter()
|
||||
.filter(|app_id| seen_app_ids.insert(app_id.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
if !config
|
||||
.features
|
||||
.apps_enabled_for_auth(auth.as_ref().is_some_and(CodexAuth::uses_codex_backend))
|
||||
|| !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.await
|
||||
{
|
||||
return Ok(Some(
|
||||
AppsReadResponse {
|
||||
apps: Vec::new(),
|
||||
missing_app_ids: app_ids,
|
||||
}
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
let auth = auth
|
||||
.as_ref()
|
||||
.ok_or_else(|| internal_error("app/read requires ChatGPT auth".to_string()))?;
|
||||
|
||||
let connectors::ConnectorMetadataReadResult {
|
||||
apps,
|
||||
missing_app_ids,
|
||||
} = connectors::read_connector_metadata(&config, auth, &app_ids, include_tools)
|
||||
.await
|
||||
.map_err(|err| internal_error(format!("failed to read app metadata: {err}")))?;
|
||||
let loaded_plugins = self
|
||||
.thread_manager
|
||||
.plugins_manager()
|
||||
.plugins_for_config(&config.plugins_config_input())
|
||||
.await;
|
||||
let connector_snapshot =
|
||||
codex_connectors::ConnectorSnapshot::from_plugin_capability_summaries(
|
||||
loaded_plugins.capability_summaries(),
|
||||
);
|
||||
let apps = apps
|
||||
.into_iter()
|
||||
.map(|metadata| {
|
||||
let mut app = connector_metadata_to_api(metadata);
|
||||
app.plugin_display_names = connector_snapshot
|
||||
.plugin_display_names_for_connector_id(app.id.as_str())
|
||||
.to_vec();
|
||||
app
|
||||
})
|
||||
.collect();
|
||||
Ok(Some(
|
||||
AppsReadResponse {
|
||||
apps,
|
||||
missing_app_ids,
|
||||
}
|
||||
.into(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) async fn apps_list(
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
@@ -477,8 +405,6 @@ fn record_legacy_apps_installed_duration(started_at: Instant, reload: bool) {
|
||||
);
|
||||
}
|
||||
}
|
||||
pub(super) const APP_READ_MAX_IDS: usize = 100;
|
||||
|
||||
enum AppListLoadResult {
|
||||
Accessible(Result<AccessibleConnectorsStatus, String>),
|
||||
Directory(Result<Vec<AppInfo>, String>),
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
use super::*;
|
||||
use crate::app_info::connector_metadata_to_api;
|
||||
|
||||
pub(in crate::request_processors) const APP_READ_MAX_IDS: usize = 100;
|
||||
const APPS_READ_DURATION_METRIC: &str = "codex.apps.read.duration_ms";
|
||||
|
||||
impl AppsRequestProcessor {
|
||||
pub(crate) async fn apps_read(
|
||||
&self,
|
||||
params: AppsReadParams,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
let started_at = Instant::now();
|
||||
let AppsReadParams {
|
||||
app_ids,
|
||||
include_tools,
|
||||
} = params;
|
||||
if app_ids.len() > APP_READ_MAX_IDS {
|
||||
return Err(invalid_params(format!(
|
||||
"app/read accepts at most {APP_READ_MAX_IDS} appIds"
|
||||
)));
|
||||
}
|
||||
|
||||
let mut seen_app_ids = HashSet::new();
|
||||
let app_ids = app_ids
|
||||
.into_iter()
|
||||
.filter(|app_id| seen_app_ids.insert(app_id.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
if !config
|
||||
.features
|
||||
.apps_enabled_for_auth(auth.as_ref().is_some_and(CodexAuth::uses_codex_backend))
|
||||
|| !self
|
||||
.workspace_codex_plugins_enabled(&config, auth.as_ref())
|
||||
.await
|
||||
{
|
||||
let response = AppsReadResponse {
|
||||
apps: Vec::new(),
|
||||
missing_app_ids: app_ids,
|
||||
};
|
||||
record_apps_read_duration(started_at, include_tools);
|
||||
return Ok(Some(response.into()));
|
||||
}
|
||||
let auth = auth
|
||||
.as_ref()
|
||||
.ok_or_else(|| internal_error("app/read requires ChatGPT auth".to_string()))?;
|
||||
|
||||
let connectors::ConnectorMetadataReadResult {
|
||||
apps,
|
||||
missing_app_ids,
|
||||
} = connectors::read_connector_metadata(&config, auth, &app_ids, include_tools)
|
||||
.await
|
||||
.map_err(|err| internal_error(format!("failed to read app metadata: {err}")))?;
|
||||
let loaded_plugins = self
|
||||
.thread_manager
|
||||
.plugins_manager()
|
||||
.plugins_for_config(&config.plugins_config_input())
|
||||
.await;
|
||||
let connector_snapshot =
|
||||
codex_connectors::ConnectorSnapshot::from_plugin_capability_summaries(
|
||||
loaded_plugins.capability_summaries(),
|
||||
);
|
||||
let apps = apps
|
||||
.into_iter()
|
||||
.map(|metadata| {
|
||||
let mut app = connector_metadata_to_api(metadata);
|
||||
app.plugin_display_names = connector_snapshot
|
||||
.plugin_display_names_for_connector_id(app.id.as_str())
|
||||
.to_vec();
|
||||
app
|
||||
})
|
||||
.collect();
|
||||
let response = AppsReadResponse {
|
||||
apps,
|
||||
missing_app_ids,
|
||||
};
|
||||
record_apps_read_duration(started_at, include_tools);
|
||||
Ok(Some(response.into()))
|
||||
}
|
||||
}
|
||||
|
||||
fn record_apps_read_duration(started_at: Instant, include_tools: bool) {
|
||||
let include_tools = if include_tools { "true" } else { "false" };
|
||||
if let Some(metrics) = codex_otel::global() {
|
||||
let _ = metrics.record_duration(
|
||||
APPS_READ_DURATION_METRIC,
|
||||
started_at.elapsed(),
|
||||
&[("include_tools", include_tools)],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user