Skip to content

feat(composio): add Linear as a native memory provider#2452

Open
M3gA-Mind wants to merge 2 commits into
tinyhumansai:mainfrom
M3gA-Mind:feat/composio-linear-provider
Open

feat(composio): add Linear as a native memory provider#2452
M3gA-Mind wants to merge 2 commits into
tinyhumansai:mainfrom
M3gA-Mind:feat/composio-linear-provider

Conversation

@M3gA-Mind
Copy link
Copy Markdown
Contributor

@M3gA-Mind M3gA-Mind commented May 21, 2026

Summary

  • Add src/openhuman/composio/providers/linear/ — fifth native Composio memory provider joining gmail / notion / slack / clickup.
  • LinearProvider syncs issues assigned to the connected user via LINEAR_LIST_LINEAR_ISSUES with cursor-based incremental updates and per-item dedup (issue_id@updatedAt).
  • Viewer identity resolved via LINEAR_LIST_LINEAR_USERS { isMe: true } on each sync pass — validates the OAuth connection is live before paginating.
  • Daily request budget and MAX_PAGES_PER_SYNC = 20 caps prevent runaway API usage.
  • Migrates LINEAR_CURATED catalog from catalogs_productivity.rs into the provider module (consistent with gmail / notion / clickup / github pattern). Adds LINEAR_LIST_LINEAR_USERS to the curated surface.
  • Updates capability_matrix test to assert linear is a native provider with sync_interval_secs = 30 * 60.

Problem

Linear was exposed only via tool-calling (LINEAR_CURATED in catalogs_productivity.rs). Connected workspace issues never reached the Memory Tree on the periodic sync path, so the agent had no long-term memory of Linear issues — every conversation started cold.

Solution

Mirrors clickup/ as the template (most recent and structurally simplest native provider). Key adaptations for Linear:

  • No workspace enumeration needed — LINEAR_LIST_LINEAR_ISSUES accepts a cross-team assigneeId filter directly.
  • Cursor is an ISO-8601 updatedAt string (lexicographically sortable, same as Notion).
  • Source ID: composio-linear-issue-<issue_uuid> — stable per issue across syncs for upsert semantics.

Submission Checklist

  • Tests added: 36 unit tests across sync.rs (18 inline) and tests.rs (18) covering all extraction helpers, provider metadata, and curated catalog surface
  • Diff coverage ≥ 80% — all new sync helpers and trait methods exercised; cargo test passes clean
  • Coverage matrix updated — capability_matrix_includes_linear_as_native_memory_provider test added to mod.rs
  • All affected feature IDs from matrix listed under Related — N/A (new capability row, no pre-existing matrix entry)
  • No new external network dependencies — all Composio calls go through the existing ProviderContext::execute path
  • Manual smoke checklist updated — N/A: no release-cut surface changed
  • Linked issue closed via Closes #2400 in Related

Impact

  • Rust core only — no Tauri shell, no frontend changes.
  • Desktop: macOS / Windows / Linux.
  • First sync after on_connection_created ingests up to 100 assigned issues; subsequent syncs increment from the updatedAt cursor.

Related


AI Authored PR Metadata

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/composio-linear-provider
  • Commit SHA: (see branch head)

Validation Run

  • pnpm --filter openhuman-app format:check — N/A (Rust-only change)
  • pnpm typecheck — N/A (Rust-only change)
  • Focused tests: cargo test -p openhuman -- composio::providers::linear — 36 tests pass
  • Rust fmt/check: cargo fmt --all -- --check passes, cargo clippy -p openhuman clean
  • Tauri fmt/check: N/A (no Tauri shell changes)

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Linear issues assigned to the connected user are now ingested into Memory Tree on a 30-minute sync cycle
  • User-visible effect: The agent can recall and reason about the user's Linear issues from memory; no UI change needed

Parity Contract

  • Legacy behavior preserved: LINEAR_CURATED removed from catalogs_productivity.rs and re-pointed in catalog_for_toolkit — tool-calling surface for Linear is identical, just sourced from the provider module
  • Guard/fallback/dispatch parity: budget check, cursor comparison, and persist_single_item path match gmail / clickup patterns

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this one
  • Resolution: N/A

Summary by CodeRabbit

  • New Features
    • Added Linear provider: assigned Linear issues sync into your Memory Tree.
    • Incremental sync runs every 30 minutes with pagination and daily request budgeting.
    • Linear appears as a native provider and is registered by default, with an available curated set of Linear actions/tools.

Review Change Stack

Adds LinearProvider under src/openhuman/composio/providers/linear/,
joining gmail/notion/slack/clickup as the fifth toolkit with periodic
Memory Tree ingest. Syncs issues assigned to the connected user via
LINEAR_LIST_LINEAR_ISSUES, with cursor-based incremental updates,
daily budget enforcement, and per-item dedup.

Migrates LINEAR_CURATED catalog from catalogs_productivity.rs into
the provider module (consistent with gmail/notion/clickup), adds
LINEAR_LIST_LINEAR_USERS to the curated surface for viewer-id
resolution, and registers the provider in init_default_providers.

Closes tinyhumansai#2400
@M3gA-Mind M3gA-Mind requested a review from a team May 21, 2026 14:31
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4174b5d6-836c-46e7-b0c2-3f957f91f402

📥 Commits

Reviewing files that changed from the base of the PR and between cd2c968 and 86acfb0.

📒 Files selected for processing (1)
  • src/openhuman/composio/providers/linear/provider.rs

📝 Walkthrough

Walkthrough

Adds Linear as a native memory-ingest provider. LinearProvider incrementally syncs issues assigned to the authenticated user via cursored pagination and persists each issue into Memory Tree. Adds JSON extraction helpers, curated tools catalog, module wiring, registry registration, and capability-matrix integration.

Changes

Linear memory provider feature

Layer / File(s) Summary
Provider sync implementation and user profile fetching
src/openhuman/composio/providers/linear/provider.rs
LinearProvider struct, new()/Default, ComposioProvider impl: toolkit_slug="linear", curated_tools, sync_interval Some(1800), fetch_user_profile resolves viewer via LINEAR_LIST_LINEAR_USERS, sync loads SyncState, enforces budget, pages LINEAR_LIST_LINEAR_ISSUES filtered by assignee, deduplicates by (issue_id, updatedAt), persists items via persist_single_item, advances cursor, and returns SyncOutcome. Includes resolve_viewer_id helper.
JSON extraction helpers for Linear/Composio responses
src/openhuman/composio/providers/linear/sync.rs
Crate-visible helpers: extract_issues, extract_issue_title, extract_issue_updated, extract_viewer, extract_viewer_id, extract_pagination_cursor, now_ms. Probes multiple envelope/field-name variants; unit tests validate wrapped/unwrapped shapes and pagination behavior.
Linear curated tools catalog and module entry point
src/openhuman/composio/providers/linear/tools.rs, src/openhuman/composio/providers/linear/mod.rs
Adds LINEAR_CURATED constant (CuratedTool entries with Read/Write/Admin scopes) and linear/mod.rs that declares submodules, exposes tools, and re-exports LinearProvider and LINEAR_CURATED.
Provider module wiring and comprehensive tests
src/openhuman/composio/providers/linear/tests.rs, src/openhuman/composio/providers/mod.rs
Unit tests cover JSON extraction helpers, pagination cursor, viewer id extraction, provider metadata (toolkit_slug="linear", sync_interval=Some(1800)), curated catalog contents, and Default/new() parity. pub mod linear; added to providers/mod.rs.
Integration into provider ecosystem and capability matrix
src/openhuman/composio/providers/registry.rs, src/openhuman/composio/providers/mod.rs
Registers LinearProvider in init_default_providers; native-provider wiring recognizes "linear" for sync interval and native flag; catalog_for_toolkit returns linear::LINEAR_CURATED; adds a capability-matrix test asserting Linear is native with memory_ingest and 30-minute sync interval.
Remove legacy LINEAR_CURATED from centralized catalogs
src/openhuman/composio/providers/catalogs_productivity.rs, src/openhuman/composio/providers/catalogs.rs, src/openhuman/composio/providers/descriptions.rs
Removes centralized LINEAR_CURATED and its re-export; updates Linear description to mention syncing assigned issues into "Memory Tree".

Sequence Diagram (high-level sync flow)

sequenceDiagram
  participant Client as ProviderContext
  participant Provider as LinearProvider::sync
  participant State as SyncState
  participant LinearAPI as LINEAR_LIST_LINEAR_USERS / LINEAR_LIST_LINEAR_ISSUES
  participant Persister as persist_single_item

  Client->>Provider: sync(ctx, reason)
  Provider->>State: load & check daily budget
  Provider->>LinearAPI: LINEAR_LIST_LINEAR_USERS(isMe:true) -> viewer id
  Provider->>State: re-check budget
  Provider->>LinearAPI: LINEAR_LIST_LINEAR_ISSUES(assignee=viewer, cursor)
  loop per page
    LinearAPI->>Provider: issues + pageInfo
    Provider->>Provider: dedupe by issue_id@updatedAt
    Provider->>Persister: persist_single_item(issue)
  end
  Provider->>State: save cursor & usage
  Provider->>Client: SyncOutcome
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • graycyrus
  • senamakel

Poem

🐰 I nibble at JSON, hop through each page,
I fetch the viewer, then dance on the stage,
Issues hop into Memory Tree with delight,
Deduped and timestamped, tucked in for the night. 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: adding Linear as a native memory provider in the Composio integration.
Linked Issues check ✅ Passed The pull request implements all coding requirements from issue #2400: LinearProvider with sync logic, cursor-based pagination, assignee filtering, daily budget checks, dedup by issue_id@updatedAt, memory persistence, provider registration, LINEAR_CURATED migration, and comprehensive unit tests.
Out of Scope Changes check ✅ Passed All changes align with the PR objectives and linked issue #2400. No out-of-scope modifications detected; changes include LinearProvider implementation, registration, LINEAR_CURATED migration, tests, and documentation updates only.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 21, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/openhuman/composio/providers/linear/provider.rs`:
- Around line 313-319: The cursor is being advanced even when
persist_single_item fails, which can permanently skip items; modify the logic
around persist_single_item so that the cursor update/advance only occurs on
success (i.e., after persist_single_item returns Ok), and do not advance when it
returns Err (log and continue without moving the cursor). Update both
occurrences referenced near the persist_single_item call (the warning block
around tracing::warn! at the first occurrence and the similar block at lines
~346-348) so cursor advancement is gated on successful persistence.
- Around line 209-213: The loop is moving the String viewer_id into the json!
macro (in the args initialization) on the first iteration, causing subsequent
iterations to fail; fix it by passing a non-consuming reference or clone (e.g.,
use &viewer_id or viewer_id.clone()) when building args so viewer_id is not
moved; update the args construction where json!({ "assigneeId": viewer_id,
"first": page_size, "orderBy": "updatedAt" }) to use &viewer_id or
viewer_id.clone() instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b0118f1b-7908-4159-ad12-e34f6a1e6ddc

📥 Commits

Reviewing files that changed from the base of the PR and between ec9708a and cd2c968.

📒 Files selected for processing (10)
  • src/openhuman/composio/providers/catalogs.rs
  • src/openhuman/composio/providers/catalogs_productivity.rs
  • src/openhuman/composio/providers/descriptions.rs
  • src/openhuman/composio/providers/linear/mod.rs
  • src/openhuman/composio/providers/linear/provider.rs
  • src/openhuman/composio/providers/linear/sync.rs
  • src/openhuman/composio/providers/linear/tests.rs
  • src/openhuman/composio/providers/linear/tools.rs
  • src/openhuman/composio/providers/mod.rs
  • src/openhuman/composio/providers/registry.rs
💤 Files with no reviewable changes (1)
  • src/openhuman/composio/providers/catalogs_productivity.rs

Comment thread src/openhuman/composio/providers/linear/provider.rs
Comment thread src/openhuman/composio/providers/linear/provider.rs
- Use &viewer_id in json! macro inside pagination loop to avoid String
  move on first iteration (CodeRabbit critical, line 213)
- Track had_persist_failures and gate cursor advancement on zero
  failures; emit a warn log when keeping cursor for retry, preventing
  permanently skipped issues (CodeRabbit major, line 319)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Linear as a Composio memory provider (joining gmail / notion / slack / clickup)

1 participant