Skip to content

feat(sync): add Composio asana memory-sync pipeline#113

Closed
CodeGhost21 wants to merge 1 commit into
tinyhumansai:mainfrom
CodeGhost21:feat/composio-asana-sync
Closed

feat(sync): add Composio asana memory-sync pipeline#113
CodeGhost21 wants to merge 1 commit into
tinyhumansai:mainfrom
CodeGhost21:feat/composio-asana-sync

Conversation

@CodeGhost21

Copy link
Copy Markdown
Collaborator

Summary

Adds AsanaSyncPipeline — a Composio memory-sync pipeline for the asana toolkit — implementing both SyncPipeline and IncrementalSource, registered alongside the existing six (gmail, github, notion, linear, clickup, slack). Before this, connecting Asana reported ACTIVE but sync failed with tinycortex sync does not support toolkit 'asana' and ingested nothing.

Pipeline shape

Asana is task-shaped, so the pipeline follows GitHub (server-side incremental depth) combined with ClickUp (multi-scope discovery):

  • Scopes = projects. scopes() enumerates every accessible workspace via ASANA_GET_MULTIPLE_WORKSPACES, then lists each workspace's projects via ASANA_GET_MULTIPLE_PROJECTS.
  • Fetch = ASANA_GET_MULTIPLE_TASKS per project, paging on Asana's next_page.offset cursor, requesting opt_fields so modified_at (the incremental cursor) is present.
  • Incremental depth is server-side via Asana's modified_since filter (server_side_depth() -> true), mirroring GitHub's updated:>cursor. Every fetched task is strictly newer than the persisted cursor, so the engine's boundary check never truncates an unordered page. tolerate_scope_errors() -> true keeps one unreachable project from aborting the whole run.

Stable dedupe (openhuman#4953 lesson)

  • document_id = asana:<gid> — the stable Asana task gid, never a per-run id, so re-syncs upsert in place.
  • metadata.taint = "external_sync", metadata.path_scope = "asana/project/<project_gid>" (stable collection scope), plus project_id / workspace_id.
  • dedup_key = <gid>@<modified_at> so an edited task re-ingests a new version while keeping the same document id.

Reference followed

src/memory/sync/composio/providers/github.rs (server-side depth) and clickup.rs (workspace→scope enumeration); shared helpers from providers/common.rs; engine contract in orchestrator.rs.

Tests run

  • src/memory/sync/composio/providers/asana_tests.rs — unit coverage: toolkit()/action(), extract_page() on a sample Composio JSON payload (+ no-next_page stop), dedup_key/sort_cursor, arguments() carrying project/modified_since/offset, and a stable asana:<gid> document_id with path_scope from document().
  • tests/composio_sync_mock.rs::asana_enumerates_projects_and_stores_stable_task_documents — end-to-end workspaces→projects→tasks mock asserting stable document id, taint/path_scope/workspace_id metadata, cursor advance, and idempotent re-sync (0 duplicates).
  • cargo fmt --all clean; cargo test --features sync sync::composio green (23 tests).
  • No PII/secrets logged — debug logging emits scope counts only, no task titles or bodies.

Scope

Part of #83 (tinycortex pipeline body; openhuman wiring is the follow-up step). The openhuman-side work — bumping the vendor/tinycortex submodule, adding the sync.rs selector arm, and registering the ComposioProvider so memory_sources.supported_toolkits advertises the slug — is intentionally not included here.

🤖 Generated with Claude Code

Implement AsanaSyncPipeline (SyncPipeline + IncrementalSource) so the
`asana` toolkit ingests tasks instead of failing with "tinycortex sync
does not support toolkit 'asana'".

- Enumerate projects across every accessible workspace
  (ASANA_GET_MULTIPLE_WORKSPACES -> ASANA_GET_MULTIPLE_PROJECTS) as sync
  scopes, then page each project's tasks via ASANA_GET_MULTIPLE_TASKS.
- Server-side incremental depth via Asana's `modified_since` filter
  (mirrors the GitHub pipeline), so fetched tasks are always newer than
  the persisted cursor and the engine's boundary check never truncates.
- Stable dedupe: document_id = `asana:<gid>`, metadata.taint =
  "external_sync", metadata.path_scope = the project scope. Re-syncs
  upsert in place rather than duplicating (openhuman#4953 lesson).
- Register through providers/mod.rs, composio/mod.rs and sync/mod.rs.
- Content-free debug logging (scope counts only; no task titles/bodies).

Tests: asana_tests.rs unit coverage (toolkit/action, extract_page,
dedup/cursor, stable document_id, arguments) plus an end-to-end
workspaces->projects->tasks mock in composio_sync_mock.rs asserting
idempotent re-sync. `cargo fmt --all` clean; `cargo test --features
sync sync::composio` green (23 tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5be3349f-122e-4385-a6ed-e954743278c6

📥 Commits

Reviewing files that changed from the base of the PR and between 9a0603a and aca204d.

📒 Files selected for processing (6)
  • src/memory/sync/composio/mod.rs
  • src/memory/sync/composio/providers/asana.rs
  • src/memory/sync/composio/providers/asana_tests.rs
  • src/memory/sync/composio/providers/mod.rs
  • src/memory/sync/mod.rs
  • tests/composio_sync_mock.rs

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant