mirror of
https://github.com/openai/codex.git
synced 2026-11-03 08:22:30 +00:00
[apps] Improve app listing filtering. (#11697)
- [x] If an installed app is not on the app listing, remove it from the final list.
This commit is contained in:
1 parent
c54a4ec078
commit
8468871e2b
5 files changed
+67
-9
No files matched your search
@@ -4724,9 +4724,10 @@ impl CodexMessageProcessor {
|
|||||||
all_connectors: Option<&[AppInfo]>,
|
all_connectors: Option<&[AppInfo]>,
|
||||||
accessible_connectors: Option<&[AppInfo]>,
|
accessible_connectors: Option<&[AppInfo]>,
|
||||||
) -> Vec<AppInfo> {
|
) -> Vec<AppInfo> {
|
||||||
|
let all_connectors_loaded = all_connectors.is_some();
|
||||||
let all = all_connectors.map_or_else(Vec::new, <[AppInfo]>::to_vec);
|
let all = all_connectors.map_or_else(Vec::new, <[AppInfo]>::to_vec);
|
||||||
let accessible = accessible_connectors.map_or_else(Vec::new, <[AppInfo]>::to_vec);
|
let accessible = accessible_connectors.map_or_else(Vec::new, <[AppInfo]>::to_vec);
|
||||||
connectors::merge_connectors_with_accessible(all, accessible)
|
connectors::merge_connectors_with_accessible(all, accessible, all_connectors_loaded)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paginate_apps(
|
fn paginate_apps(
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::sync::Mutex as StdMutex;
|
use std::sync::Mutex as StdMutex;
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ pub async fn list_connectors(config: &Config) -> anyhow::Result<Vec<AppInfo>> {
|
|||||||
let connectors = connectors_result?;
|
let connectors = connectors_result?;
|
||||||
let accessible = accessible_result?;
|
let accessible = accessible_result?;
|
||||||
Ok(with_app_enabled_state(
|
Ok(with_app_enabled_state(
|
||||||
merge_connectors_with_accessible(connectors, accessible),
|
merge_connectors_with_accessible(connectors, accessible, true),
|
||||||
config,
|
config,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -185,7 +186,20 @@ fn write_cached_all_connectors(cache_key: AllConnectorsCacheKey, connectors: &[A
|
|||||||
pub fn merge_connectors_with_accessible(
|
pub fn merge_connectors_with_accessible(
|
||||||
connectors: Vec<AppInfo>,
|
connectors: Vec<AppInfo>,
|
||||||
accessible_connectors: Vec<AppInfo>,
|
accessible_connectors: Vec<AppInfo>,
|
||||||
|
all_connectors_loaded: bool,
|
||||||
) -> Vec<AppInfo> {
|
) -> Vec<AppInfo> {
|
||||||
|
let accessible_connectors = if all_connectors_loaded {
|
||||||
|
let connector_ids: HashSet<&str> = connectors
|
||||||
|
.iter()
|
||||||
|
.map(|connector| connector.id.as_str())
|
||||||
|
.collect();
|
||||||
|
accessible_connectors
|
||||||
|
.into_iter()
|
||||||
|
.filter(|connector| connector_ids.contains(connector.id.as_str()))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
accessible_connectors
|
||||||
|
};
|
||||||
let merged = merge_connectors(connectors, accessible_connectors);
|
let merged = merge_connectors(connectors, accessible_connectors);
|
||||||
filter_disallowed_connectors(merged)
|
filter_disallowed_connectors(merged)
|
||||||
}
|
}
|
||||||
@@ -406,4 +420,41 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
assert_eq!(filtered, vec![app("delta")]);
|
assert_eq!(filtered, vec![app("delta")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn merged_app(id: &str, is_accessible: bool) -> AppInfo {
|
||||||
|
AppInfo {
|
||||||
|
id: id.to_string(),
|
||||||
|
name: id.to_string(),
|
||||||
|
description: None,
|
||||||
|
logo_url: None,
|
||||||
|
logo_url_dark: None,
|
||||||
|
distribution_channel: None,
|
||||||
|
install_url: Some(connector_install_url(id, id)),
|
||||||
|
is_accessible,
|
||||||
|
is_enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn excludes_accessible_connectors_not_in_all_when_all_loaded() {
|
||||||
|
let merged = merge_connectors_with_accessible(
|
||||||
|
vec![app("alpha")],
|
||||||
|
vec![app("alpha"), app("beta")],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert_eq!(merged, vec![merged_app("alpha", true)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn keeps_accessible_connectors_not_in_all_while_all_loading() {
|
||||||
|
let merged = merge_connectors_with_accessible(
|
||||||
|
vec![app("alpha")],
|
||||||
|
vec![app("alpha"), app("beta")],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
merged,
|
||||||
|
vec![merged_app("alpha", true), merged_app("beta", true)]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3387,7 +3387,7 @@ mod tests {
|
|||||||
let mut app = make_test_app().await;
|
let mut app = make_test_app().await;
|
||||||
let codex_home = tempdir()?;
|
let codex_home = tempdir()?;
|
||||||
app.config.codex_home = codex_home.path().to_path_buf();
|
app.config.codex_home = codex_home.path().to_path_buf();
|
||||||
let app_id = "connector_1".to_string();
|
let app_id = "unit_test_refresh_in_memory_config_connector".to_string();
|
||||||
|
|
||||||
assert_eq!(app_enabled_in_effective_config(&app.config, &app_id), None);
|
assert_eq!(app_enabled_in_effective_config(&app.config, &app_id), None);
|
||||||
|
|
||||||
|
|||||||
@@ -4582,6 +4582,7 @@ impl ChatWidget {
|
|||||||
let connectors = connectors::merge_connectors_with_accessible(
|
let connectors = connectors::merge_connectors_with_accessible(
|
||||||
all_connectors,
|
all_connectors,
|
||||||
accessible_connectors,
|
accessible_connectors,
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
Ok(ConnectorsSnapshot { connectors })
|
Ok(ConnectorsSnapshot { connectors })
|
||||||
}
|
}
|
||||||
@@ -6736,6 +6737,7 @@ impl ChatWidget {
|
|||||||
snapshot.connectors = connectors::merge_connectors_with_accessible(
|
snapshot.connectors = connectors::merge_connectors_with_accessible(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
snapshot.connectors,
|
snapshot.connectors,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
snapshot.connectors =
|
snapshot.connectors =
|
||||||
|
|||||||
@@ -3868,11 +3868,13 @@ async fn apps_popup_refreshes_when_connectors_snapshot_updates() {
|
|||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||||
chat.config.features.enable(Feature::Apps);
|
chat.config.features.enable(Feature::Apps);
|
||||||
chat.bottom_pane.set_connectors_enabled(true);
|
chat.bottom_pane.set_connectors_enabled(true);
|
||||||
|
let notion_id = "unit_test_apps_popup_refresh_connector_1";
|
||||||
|
let linear_id = "unit_test_apps_popup_refresh_connector_2";
|
||||||
|
|
||||||
chat.on_connectors_loaded(
|
chat.on_connectors_loaded(
|
||||||
Ok(ConnectorsSnapshot {
|
Ok(ConnectorsSnapshot {
|
||||||
connectors: vec![codex_chatgpt::connectors::AppInfo {
|
connectors: vec![codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_1".to_string(),
|
id: notion_id.to_string(),
|
||||||
name: "Notion".to_string(),
|
name: "Notion".to_string(),
|
||||||
description: Some("Workspace docs".to_string()),
|
description: Some("Workspace docs".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
@@ -3905,7 +3907,7 @@ async fn apps_popup_refreshes_when_connectors_snapshot_updates() {
|
|||||||
Ok(ConnectorsSnapshot {
|
Ok(ConnectorsSnapshot {
|
||||||
connectors: vec![
|
connectors: vec![
|
||||||
codex_chatgpt::connectors::AppInfo {
|
codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_1".to_string(),
|
id: notion_id.to_string(),
|
||||||
name: "Notion".to_string(),
|
name: "Notion".to_string(),
|
||||||
description: Some("Workspace docs".to_string()),
|
description: Some("Workspace docs".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
@@ -3916,7 +3918,7 @@ async fn apps_popup_refreshes_when_connectors_snapshot_updates() {
|
|||||||
is_enabled: true,
|
is_enabled: true,
|
||||||
},
|
},
|
||||||
codex_chatgpt::connectors::AppInfo {
|
codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_2".to_string(),
|
id: linear_id.to_string(),
|
||||||
name: "Linear".to_string(),
|
name: "Linear".to_string(),
|
||||||
description: Some("Project tracking".to_string()),
|
description: Some("Project tracking".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
@@ -3947,10 +3949,12 @@ async fn apps_refresh_failure_keeps_existing_full_snapshot() {
|
|||||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
|
||||||
chat.config.features.enable(Feature::Apps);
|
chat.config.features.enable(Feature::Apps);
|
||||||
chat.bottom_pane.set_connectors_enabled(true);
|
chat.bottom_pane.set_connectors_enabled(true);
|
||||||
|
let notion_id = "unit_test_apps_refresh_failure_connector_1";
|
||||||
|
let linear_id = "unit_test_apps_refresh_failure_connector_2";
|
||||||
|
|
||||||
let full_connectors = vec![
|
let full_connectors = vec![
|
||||||
codex_chatgpt::connectors::AppInfo {
|
codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_1".to_string(),
|
id: notion_id.to_string(),
|
||||||
name: "Notion".to_string(),
|
name: "Notion".to_string(),
|
||||||
description: Some("Workspace docs".to_string()),
|
description: Some("Workspace docs".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
@@ -3961,7 +3965,7 @@ async fn apps_refresh_failure_keeps_existing_full_snapshot() {
|
|||||||
is_enabled: true,
|
is_enabled: true,
|
||||||
},
|
},
|
||||||
codex_chatgpt::connectors::AppInfo {
|
codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_2".to_string(),
|
id: linear_id.to_string(),
|
||||||
name: "Linear".to_string(),
|
name: "Linear".to_string(),
|
||||||
description: Some("Project tracking".to_string()),
|
description: Some("Project tracking".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
@@ -3982,7 +3986,7 @@ async fn apps_refresh_failure_keeps_existing_full_snapshot() {
|
|||||||
chat.on_connectors_loaded(
|
chat.on_connectors_loaded(
|
||||||
Ok(ConnectorsSnapshot {
|
Ok(ConnectorsSnapshot {
|
||||||
connectors: vec![codex_chatgpt::connectors::AppInfo {
|
connectors: vec![codex_chatgpt::connectors::AppInfo {
|
||||||
id: "connector_1".to_string(),
|
id: notion_id.to_string(),
|
||||||
name: "Notion".to_string(),
|
name: "Notion".to_string(),
|
||||||
description: Some("Workspace docs".to_string()),
|
description: Some("Workspace docs".to_string()),
|
||||||
logo_url: None,
|
logo_url: None,
|
||||||
|
|||||||
Reference in new issue
Block a user