feat(composio): promote GitHub from catalog-only to native memory provider (#2413)

Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
This commit is contained in:
Justin
2026-05-24 23:24:09 -07:00
committed by GitHub
co-authored by Steven Enamakel
parent 03d689873a
commit bf2400f0f9
3 changed files with 38 additions and 12 deletions
@@ -11,7 +11,10 @@ pub fn toolkit_description(slug: &str) -> &'static str {
"Send, read, draft, reply, forward, and search emails; manage labels and threads"
}
"notion" => "Create, read, update, and search notion pages and notion databases",
"github" => "Manage repositories, issues, pull requests on GitHub",
"github" => {
"Manage repositories, issues, and pull requests on GitHub; sync \
assigned issues into Memory Tree"
}
"slack" => "Send messages, read channels, manage threads, and post updates in Slack",
"discord" => "Send messages, manage channels, and interact with Discord servers",
"google_calendar" => "Create, update, and query calendar events; check availability",
@@ -199,10 +199,6 @@ impl ComposioProvider for GitHubProvider {
// Build the base search query.
let query = match &state.cursor {
Some(cursor) => {
// GitHub's `updated:>` qualifier accepts ISO 8601 dates
// (YYYY-MM-DD or full datetime). Using the full stored cursor
// (e.g. `"2024-05-21T15:30:00Z"`) is accepted by the API and
// more precise than truncating to the day.
format!("involves:{login} updated:>{cursor}")
}
None => format!("involves:{login}"),
@@ -236,12 +232,15 @@ impl ComposioProvider for GitHubProvider {
"[composio:github] executing {ACTION_SEARCH_ISSUES}"
);
let resp = ctx
.execute(ACTION_SEARCH_ISSUES, Some(args))
.await
.map_err(|e| {
format!("[composio:github] {ACTION_SEARCH_ISSUES} page={page_num}: {e:#}")
})?;
let resp = match ctx.execute(ACTION_SEARCH_ISSUES, Some(args)).await {
Ok(resp) => resp,
Err(e) => {
let _ = state.save(&memory).await;
return Err(format!(
"[composio:github] {ACTION_SEARCH_ISSUES} page={page_num}: {e:#}"
));
}
};
state.record_requests(1);
if !resp.successful {
@@ -100,6 +100,7 @@ fn native_provider_sync_interval(toolkit: &str) -> Option<u64> {
"notion" => Some(notion::NotionProvider::new().sync_interval_secs()),
"slack" => Some(slack::SlackProvider::new().sync_interval_secs()),
"clickup" => Some(clickup::ClickUpProvider::new().sync_interval_secs()),
"github" => Some(github::GitHubProvider::new().sync_interval_secs()),
"linear" => Some(linear::LinearProvider::new().sync_interval_secs()),
_ => None,
}
@@ -107,7 +108,10 @@ fn native_provider_sync_interval(toolkit: &str) -> Option<u64> {
}
fn has_native_provider(toolkit: &str) -> bool {
matches!(toolkit, "gmail" | "notion" | "slack" | "clickup" | "linear")
matches!(
toolkit,
"gmail" | "notion" | "slack" | "clickup" | "github" | "linear"
)
}
/// Static overview of the Composio integrations supported by this core build.
@@ -499,6 +503,26 @@ mod tests {
assert!(linear.memory_ingest);
}
#[test]
fn capability_matrix_includes_github_as_native_memory_provider() {
let matrix = capability_matrix();
let github = matrix
.iter()
.find(|entry| entry.toolkit == "github")
.expect("github capability row");
assert!(github.native_provider, "github must be native");
assert!(github.curated_tools, "github must have a curated catalog");
assert!(
github.curated_tool_count > 0,
"github catalog must be non-empty"
);
assert!(github.user_profile);
assert!(github.initial_sync);
assert!(github.periodic_sync);
assert_eq!(github.sync_interval_secs, Some(30 * 60));
assert!(github.memory_ingest);
}
#[test]
fn toolkit_description_known_slugs_are_distinct_and_non_empty() {
let known = [