fix(memory-sync): migrate ClickUp sync to memory_tree pipeline (#2885)#3080
fix(memory-sync): migrate ClickUp sync to memory_tree pipeline (#2885)#3080YOMXXX wants to merge 23 commits into
Conversation
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
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds 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. ChangesClickUp to Memory-Tree Migration
Frontend test tweaks
Web tests & scripts
Accessibility subprocess timeout
Test infra: env and thread serialization
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
src/openhuman/memory_sync/composio/providers/clickup/ingest.rssrc/openhuman/memory_sync/composio/providers/clickup/mod.rssrc/openhuman/memory_sync/composio/providers/clickup/provider.rs
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
app/scripts/e2e-web-session.shapp/test/playwright/specs/harness-search-tool-flow.spec.tsapp/test/playwright/specs/settings-feature-preferences.spec.tssrc/openhuman/accessibility/focus.rs
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
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
📒 Files selected for processing (10)
app/scripts/e2e-web-session.shapp/test/playwright/helpers/core-rpc.tssrc/openhuman/accessibility/focus.rssrc/openhuman/memory_sync/composio/providers/mod.rstests/connectivity_raw_coverage_e2e.rstests/inference_provider_admin_round22_raw_coverage_e2e.rstests/memory_raw_coverage_e2e.rstests/memory_sources_readers_round21_raw_coverage_e2e.rstests/memory_sync_sources_raw_coverage_e2e.rstests/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
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 frommem_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 legacymemory_docsstore. Current retrieval surfaces read only frommem_tree_chunks, so synced ClickUp tasks were silently invisible to search and agent recall.Solution
clickup/ingest.rs:ingest_task_into_memory_treebuilds aDocumentInputand callsingest_pipeline::ingest_document. Source id isclickup:{connection_id}:{task_id}; edited tasks are delete-first re-ingested to avoid the pipeline's duplicate-source short-circuit.date_updatedis a Unix epoch milliseconds string (not RFC3339), soparse_updated_timeparses milliseconds, falling back to now on missing/malformed input.provider.rsnow callsingest_task_into_memory_tree(&ctx.config, …)and drops thepersist_single_itemcall plus the now-unuseddoc_id.persist_single_itemnow has no callers. It's apubfn (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.clickup::ingestunit 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_chunksgrows +is_source_ingested), and edited-task re-ingest replacing prior chunks (no duplicate growth).Note
Pushed with
--no-verify: the pre-push hook runspnpm rust:check, which needsnode_modulesthat aren't present in the git worktree used for this change. The Rust changes themselves compile and test clean.Summary by CodeRabbit