File size: 5,110 Bytes
afa0cbf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | use codex_app_server_protocol::AppBranding as ApiAppBranding;
use codex_app_server_protocol::AppInfo as ApiAppInfo;
use codex_app_server_protocol::AppMetadata as ApiAppMetadata;
use codex_app_server_protocol::AppReview as ApiAppReview;
use codex_app_server_protocol::AppScreenshot as ApiAppScreenshot;
use codex_app_server_protocol::AppToolSummary as ApiAppToolSummary;
use codex_app_server_protocol::ConnectorMetadata as ApiConnectorMetadata;
use codex_connectors::AppBranding;
use codex_connectors::AppInfo;
use codex_connectors::AppMetadata;
use codex_connectors::AppReview;
use codex_connectors::AppScreenshot;
use codex_connectors::ConnectorMetadata;
use codex_connectors::ConnectorToolSummary;
use codex_connectors::metadata::connector_install_url;
/// Converts connector-domain app metadata owned by `codex-connectors` into the app-server wire
/// type owned by `codex-app-server-protocol`.
///
/// The types stay separate so app-server protocol ownership does not leak into the connector
/// domain crate. Because this crate owns neither type, Rust's orphan rules require an explicit
/// conversion function instead of a `From` implementation.
pub(crate) fn app_info_to_api(app: AppInfo) -> ApiAppInfo {
let AppInfo {
id,
name,
description,
logo_url,
logo_url_dark,
icon_assets,
icon_dark_assets,
distribution_channel,
branding,
app_metadata,
labels,
install_url,
is_accessible,
is_enabled,
plugin_display_names,
} = app;
ApiAppInfo {
id,
name,
description,
logo_url,
logo_url_dark,
icon_assets,
icon_dark_assets,
distribution_channel,
branding: branding.map(app_branding_to_api),
app_metadata: app_metadata.map(app_metadata_to_api),
labels,
install_url,
is_accessible,
is_enabled,
plugin_display_names,
}
}
/// Converts metadata-only connector data into the app-server wire type.
///
/// Keeping this separate from app_info_to_api makes it impossible for app/read to accidentally
/// expose full runtime tool state from the broader app/list path.
pub(crate) fn connector_metadata_to_api(metadata: ConnectorMetadata) -> ApiConnectorMetadata {
let ConnectorMetadata {
id,
name,
description,
icon_url,
icon_url_dark,
distribution_channel,
tool_summaries,
} = metadata;
let install_url = Some(connector_install_url(&name, &id));
ApiConnectorMetadata {
id,
name,
description,
icon_url,
icon_url_dark,
distribution_channel,
install_url,
plugin_display_names: Vec::new(),
tool_summaries: tool_summaries.map(|tools| {
tools
.into_iter()
.map(|tool| {
let ConnectorToolSummary {
name,
title,
description,
is_enabled,
disabled_reason,
is_read_only,
} = tool;
ApiAppToolSummary {
name,
title,
description,
is_enabled,
disabled_reason,
is_read_only,
}
})
.collect()
}),
}
}
fn app_branding_to_api(branding: AppBranding) -> ApiAppBranding {
let AppBranding {
category,
developer,
website,
privacy_policy,
terms_of_service,
is_discoverable_app,
} = branding;
ApiAppBranding {
category,
developer,
website,
privacy_policy,
terms_of_service,
is_discoverable_app,
}
}
fn app_review_to_api(review: AppReview) -> ApiAppReview {
let AppReview { status } = review;
ApiAppReview { status }
}
fn app_screenshot_to_api(screenshot: AppScreenshot) -> ApiAppScreenshot {
let AppScreenshot {
url,
file_id,
user_prompt,
} = screenshot;
ApiAppScreenshot {
url,
file_id,
user_prompt,
}
}
fn app_metadata_to_api(metadata: AppMetadata) -> ApiAppMetadata {
let AppMetadata {
review,
categories,
sub_categories,
seo_description,
screenshots,
developer,
version,
version_id,
version_notes,
first_party_requires_install,
show_in_composer_when_unlinked,
} = metadata;
ApiAppMetadata {
review: review.map(app_review_to_api),
categories,
sub_categories,
seo_description,
screenshots: screenshots
.map(|screenshots| screenshots.into_iter().map(app_screenshot_to_api).collect()),
developer,
version,
version_id,
version_notes,
first_party_requires_install,
show_in_composer_when_unlinked,
}
}
|