Use batch metadata for plugin app summaries (#34851)

## What changed

- Load app metadata for plugin read and install responses through the authenticated batch API, splitting requests into batches of 100 and retaining cached metadata if a batch fails.
- Preserve every declared app in plugin responses, using its ID as the fallback name and retaining categories from the plugin declaration when metadata is unavailable.
- Add `isEnabled`, `disabledReason`, and `isReadOnly` to `AppToolSummary`, with defaults that keep legacy responses compatible.

## Testing

- Cover plugin reads with more than 100 apps, partial batch failures, install-time authentication results, tool-state propagation, and legacy tool summaries.

GitOrigin-RevId: 14000df9c5c94dde781358e292a8bef741c5dd23
This commit is contained in:
stevenlee-oai
2026-07-23 00:44:35 +00:00
committed by copyberry
parent 0a0a9b6c8f
commit b72079a2cf
15 changed files with 549 additions and 239 deletions

View File

@@ -11,13 +11,16 @@ pub struct ConnectorToolSummary {
pub name: String,
pub title: Option<String>,
pub description: String,
pub is_enabled: bool,
pub disabled_reason: Option<String>,
pub is_read_only: bool,
}
/// Metadata returned by the app batch-read API.
///
/// This intentionally excludes connector runtime state, full actions, and model descriptions.
/// Tool summaries contain display text only, and icon URLs are already projected as public URLs by
/// the backend.
/// Tool summaries contain display text and enabled/read-only state only, and icon URLs are already
/// projected as public URLs by the backend.
#[derive(Debug, Clone, PartialEq)]
pub struct ConnectorMetadata {
pub id: String,
@@ -116,6 +119,9 @@ impl ConnectorMetadataStore {
}
}
// `apps_mcp_product_sku` affects which tools the batch API returns, but is intentionally omitted
// from this key because we assume an app-server does not change its product SKU after launch.
// If that assumption changes, the SKU must be included in the cache scope.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct ConnectorMetadataStoreScope {
backend_base_url: String,

View File

@@ -90,6 +90,9 @@ fn tool_inclusive_reads_require_cached_tool_summaries() {
name: "search".to_string(),
title: Some("Search".to_string()),
description: "Search the app".to_string(),
is_enabled: true,
disabled_reason: None,
is_read_only: true,
}]);
let ids = vec![
"metadata-only".to_string(),
@@ -133,6 +136,9 @@ fn metadata_only_commit_does_not_replace_fresh_tool_summaries() {
name: "search".to_string(),
title: Some("Search".to_string()),
description: "Search the app".to_string(),
is_enabled: true,
disabled_reason: None,
is_read_only: true,
}]);
let ids = vec!["with-tools".to_string()];