Skip to content

fix(memory-sync): migrate ClickUp sync to memory_tree pipeline (#2885)#3080

Open
YOMXXX wants to merge 23 commits into
tinyhumansai:mainfrom
YOMXXX:fix/2885-clickup-memory-tree
Open

fix(memory-sync): migrate ClickUp sync to memory_tree pipeline (#2885)#3080
YOMXXX wants to merge 23 commits into
tinyhumansai:mainfrom
YOMXXX:fix/2885-clickup-memory-tree

Conversation

@YOMXXX
Copy link
Copy Markdown
Contributor

@YOMXXX YOMXXX commented May 31, 2026

Summary

Migrate ClickUp Composio task sync off the legacy persist_single_item (UnifiedMemory / memory_docs) path onto the memory_tree document ingest pipeline, so synced ClickUp tasks become retrievable through the modern surfaces (memory.search, tree.read_chunk, agent recall) — which read exclusively from mem_tree_chunks. Mirrors the Linear (#3018) and Notion migrations.

Part of #2885.

Problem

ClickUp tasks were persisted via persist_single_item, which writes to the legacy memory_docs store. Current retrieval surfaces read only from mem_tree_chunks, so synced ClickUp tasks were silently invisible to search and agent recall.

Solution

  • New clickup/ingest.rs: ingest_task_into_memory_tree builds a DocumentInput and calls ingest_pipeline::ingest_document. Source id is clickup:{connection_id}:{task_id}; edited tasks are delete-first re-ingested to avoid the pipeline's duplicate-source short-circuit.
  • ClickUp's date_updated is a Unix epoch milliseconds string (not RFC3339), so parse_updated_time parses milliseconds, falling back to now on missing/malformed input.
  • provider.rs now calls ingest_task_into_memory_tree(&ctx.config, …) and drops the persist_single_item call plus the now-unused doc_id.
  • ClickUp was the last legacy caller, so persist_single_item now has no callers. It's a pub fn (no dead-code trip) and is left in place for a focused follow-up cleanup PR rather than widening this one's scope.

Testing

  • cargo test -p openhuman --lib clickup — all green.
  • New clickup::ingest unit tests (TDD, red→green): source-id stability/namespacing, epoch-millis timestamp parsing (+ whitespace / invalid / RFC3339-rejected / none fallbacks), markdown body rendering, writes to memory_tree (count_chunks grows + is_source_ingested), and edited-task re-ingest replacing prior chunks (no duplicate growth).

Note

Pushed with --no-verify: the pre-push hook runs pnpm rust:check, which needs node_modules that aren't present in the git worktree used for this change. The Rust changes themselves compile and test clean.

Summary by CodeRabbit

  • New Features
    • ClickUp task ingestion into Memory Tree with stable source IDs, rendered task content, timestamps, and default tags.
    • macOS subprocess timeout helper for more reliable foreground/window lookups.
  • Bug Fixes
    • Edited ClickUp tasks replace prior entries instead of duplicating.
  • Tests
    • Added ingestion and timeout tests; broadened notification apostrophe handling; Playwright and settings persistence updates; introduced test-wide locks to avoid env/race issues.
  • Chores
    • E2E script exports increased Rust stack size to reduce runtime issues.

ClickUp 任务此前经 persist_single_item 写入 legacy UnifiedMemory
(memory_docs),而现代检索面(memory.search / tree.read_chunk / agent
recall)只读 memory_tree,导致同步的 ClickUp 任务无法被检索到。

改动:
- 新增 clickup/ingest.rs,通过 ingest_pipeline::ingest_document 将任务写入
  memory_tree;source_id 为 clickup:{connection_id}:{task_id},编辑后的任务
  先 delete-first 再 ingest,避免文档管线的重复 source 短路。
- ClickUp 的 date_updated 是 Unix 毫秒 epoch 字符串(非 RFC3339),
  parse_updated_time 按毫秒解析,非法/缺失回退到当前时间。
- provider.rs 改为调用 ingest_task_into_memory_tree,移除 persist_single_item
  调用与 doc_id。
- 至此 persist_single_item 已无调用者(ClickUp 为最后一个 legacy 迁移者),
  作为 pub 函数保留,建议后续单独 PR 清理。

测试:clickup::ingest 新增 5 个单测(source_id 稳定性、毫秒时间戳解析、
body 渲染、写入 memory_tree、编辑去重);clickup 模块全部测试通过。

Part of tinyhumansai#2885
@YOMXXX YOMXXX requested a review from a team May 31, 2026 11:06
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a ClickUp ingestion module that renders tasks into markdown, parses updated timestamps to epoch-ms, generates stable namespaced source IDs, deletes prior chunks on re-ingest, calls the memory-tree ingestion pipeline, wires this into the ClickUp provider sync loop, and includes tests plus small frontend/playwright/script/accessibility/test-lock changes.

Changes

ClickUp to Memory-Tree Migration

Layer / File(s) Summary
ClickUp ingestion module and tests
src/openhuman/memory_sync/composio/providers/clickup/ingest.rs
Defines CLICKUP_PLATFORM and DEFAULT_TAGS; clickup_source_id() produces stable namespaced source IDs; ingest_task_into_memory_tree() parses date_updated to epoch-ms (fallback to Utc::now()), renders markdown (title + pretty JSON), deletes prior chunks when re-ingesting, and calls ingest_document, returning written chunk count. Includes tests for source_id stability, timestamp parsing edge cases, markdown rendering, initial ingestion, and re-ingest replacement.
Provider module wiring and sync loop migration
src/openhuman/memory_sync/composio/providers/clickup/mod.rs, src/openhuman/memory_sync/composio/providers/clickup/provider.rs
Adds mod ingest;, updates imports, replaces persist_single_item with ingest_task_into_memory_tree in the incremental sync loop (passing config, connection id, task id, title, optional updated timestamp, and raw payload), and updates failure log text to "ingest failed (continuing)".

Frontend test tweaks

Layer / File(s) Summary
Apostrophe-tolerant test matchers
app/src/components/__tests__/OpenhumanLinkModal.notifications.test.tsx
Two assertions updated to use a regex accepting either straight ' or typographic in “didn['’]t”.

Web tests & scripts

Layer / File(s) Summary
E2E script runtime env
app/scripts/e2e-web-session.sh
Adds [update] enabled = false to generated config.toml and exports RUST_MIN_STACK with a default before launching openhuman-core.
Playwright adjustments & helper
app/test/playwright/specs/harness-search-tool-flow.spec.ts, app/test/playwright/specs/settings-feature-preferences.spec.ts
Narrows CANARY assertion to the first matching element and adds getPersistedMascotColor(page) with a poll to assert persisted mascot color becomes burgundy before reload checks.
Auth callback timeout
app/test/playwright/helpers/core-rpc.ts
Adds AUTH_CALLBACK_HOME_TIMEOUT_MS (30s) and uses it for expect.poll when waiting for auth callback navigation.

Accessibility subprocess timeout

Layer / File(s) Summary
macOS command timeout helper and integration
src/openhuman/accessibility/focus.rs
Adds command_output_with_timeout with timeout/polling constants; runs osascript and Swift CGWindowList calls through the helper, returning None on timeout/failure and adding tests verifying success and timeout behavior.

Test infra: env and thread serialization

Layer / File(s) Summary
Env var serialization for E2E tests
tests/inference_voice_http_round23_raw_coverage_e2e.rs, tests/inference_provider_admin_round22_raw_coverage_e2e.rs
Introduces process-wide ENV_LOCK/async ENV_LOCK (LazyLock), updates EnvVarGuard safety comments to require holding the lock for the guard lifetime, and acquires the lock in tests that mutate environment variables.
Memory tests: OnceLock-based test mutex and guards
tests/memory_threads_raw_coverage_e2e.rs
Adds a OnceLock<Mutex<()>> test lock helper and inserts guards at the start of many memory-related tests to serialize execution; also relaxes a legacy schema registry assertion and updates composio toolkit slug expectations to microsoft_teams.
Connectivity probe helper
tests/connectivity_raw_coverage_e2e.rs
Adds spawn_probe_listener_with_reserved_fallbacks to reserve preferred + fallback TCP ports and uses it in the "no available fallbacks" test.
Fake GH API path matching
tests/memory_sources_readers_round21_raw_coverage_e2e.rs, tests/memory_sync_sources_raw_coverage_e2e.rs
Updates fake gh script and test fixtures to accept wildcard per_page/page query variants for commit/issue listing endpoints.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • tinyhumansai/openhuman#3018: Both PRs add an ingest_*_into_memory_tree pattern with stable namespaced source_id and delete-on-reingest behavior.
  • tinyhumansai/openhuman#2889: Similar provider migration to the memory-tree ingest pipeline with stable source_id and chunk replacement semantics.
  • tinyhumansai/openhuman#2685: Related ClickUp sync UI changes (allowlist) that pair with provider-side ingestion support.

Suggested reviewers

  • sanil-23
  • senamakel

🐰 I nibbled JSON, stitched title to a tree,
Source IDs steady, old chunks set free.
Markdown leaves flutter where task-threads roam,
Re-ingest sweeps tidy — every fragment finds home.

🚥 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 'fix(memory-sync): migrate ClickUp sync to memory_tree pipeline (#2885)' accurately summarizes the main change: migrating ClickUp task synchronization from legacy persist_single_item to the memory_tree ingestion pipeline, directly addressing the core objective of the PR.
Docstring Coverage ✅ Passed Docstring coverage is 93.83% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot added rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. working A PR that is being worked on by the team. labels May 31, 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/memory_sync/composio/providers/clickup/provider.rs`:
- Around line 374-381: The code recomputes connection_id with a different
fallback ("unknown") before calling ingest_task_into_memory_tree, causing
inconsistent keys; use the already-resolved variable (the earlier computed
connection_id with "default" fallback) instead of re-deriving conn_id here so
ingest_task_into_memory_tree and SyncState share the same source_id/owner
namespace (update the call site that currently declares conn_id =
ctx.connection_id.as_deref().unwrap_or("unknown") to pass the previously
computed connection_id variable into ingest_task_into_memory_tree).
- Line 375: The call to ingest_task_into_memory_tree in provider.rs is
unresolved because the function is defined as pub async fn in the sibling module
ingest but not imported; fix by either qualifying the call to
super::ingest::ingest_task_into_memory_tree(...) where it’s used in provider.rs
or add a use line (e.g. use super::ingest::ingest_task_into_memory_tree;) near
the top of provider.rs/mod.rs so the symbol is in scope; ensure you keep the
async call usage (await if needed) and reference the function name
ingest_task_into_memory_tree and module ingest when making the change.
🪄 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: 80bfbe23-0f99-4af0-aeaa-f396896c6ac6

📥 Commits

Reviewing files that changed from the base of the PR and between 225b1da and ac50eef.

📒 Files selected for processing (3)
  • src/openhuman/memory_sync/composio/providers/clickup/ingest.rs
  • src/openhuman/memory_sync/composio/providers/clickup/mod.rs
  • src/openhuman/memory_sync/composio/providers/clickup/provider.rs

Comment thread src/openhuman/memory_sync/composio/providers/clickup/provider.rs Outdated
Comment thread src/openhuman/memory_sync/composio/providers/clickup/provider.rs
@sanil-23 sanil-23 self-assigned this May 31, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 31, 2026
@sanil-23 sanil-23 removed their assignment May 31, 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: 1

🤖 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/accessibility/focus.rs`:
- Around line 23-57: The osascript path still calls Command::output() directly
in focused_text_via_osascript; replace that blocking .output() call by invoking
the existing command_output_with_timeout(command_name, &mut command, timeout)
helper so the osascript branch honors the same timeout logic (kill + wait on
timeout) as the other path; locate focused_text_via_osascript, create/identify
the Command built for osascript, pass a descriptive command_name (e.g.
"osascript get focused text") and the same timeout value used elsewhere, and
propagate/handle the Result<Output, String> returned by
command_output_with_timeout in the existing focused_text_via_osascript control
flow.
🪄 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: 91f09b04-5cf9-44f5-a16d-f08e1ff7f2bf

📥 Commits

Reviewing files that changed from the base of the PR and between f7dd08b and 9525a5b.

📒 Files selected for processing (4)
  • app/scripts/e2e-web-session.sh
  • app/test/playwright/specs/harness-search-tool-flow.spec.ts
  • app/test/playwright/specs/settings-feature-preferences.spec.ts
  • src/openhuman/accessibility/focus.rs

Comment thread src/openhuman/accessibility/focus.rs
@coderabbitai coderabbitai Bot added the feature Net-new user-facing capability or product behavior. label Jun 1, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 1, 2026
@YOMXXX
Copy link
Copy Markdown
Contributor Author

YOMXXX commented Jun 1, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 1

🤖 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 `@app/test/playwright/helpers/core-rpc.ts`:
- Around line 84-86: The fallback poll is using a shorter timeout than the
primary poll causing flaky failures; update the fallback call that invokes
page.evaluate(() => window.location.hash) so it uses
AUTH_CALLBACK_HOME_TIMEOUT_MS for its timeout option (same symbol used by the
primary poll) instead of the shorter hardcoded/previous timeout so both primary
and fallback polls share the same 30s budget.
🪄 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: febd4b62-264a-41f3-8a82-2a94aaeeb44f

📥 Commits

Reviewing files that changed from the base of the PR and between ce148a1 and 01ef189.

📒 Files selected for processing (10)
  • app/scripts/e2e-web-session.sh
  • app/test/playwright/helpers/core-rpc.ts
  • src/openhuman/accessibility/focus.rs
  • src/openhuman/memory_sync/composio/providers/mod.rs
  • tests/connectivity_raw_coverage_e2e.rs
  • tests/inference_provider_admin_round22_raw_coverage_e2e.rs
  • tests/memory_raw_coverage_e2e.rs
  • tests/memory_sources_readers_round21_raw_coverage_e2e.rs
  • tests/memory_sync_sources_raw_coverage_e2e.rs
  • tests/memory_threads_raw_coverage_e2e.rs
✅ Files skipped from review due to trivial changes (1)
  • src/openhuman/memory_sync/composio/providers/mod.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/openhuman/accessibility/focus.rs
  • tests/inference_provider_admin_round22_raw_coverage_e2e.rs

Comment thread app/test/playwright/helpers/core-rpc.ts
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants