Skip to content

fix(feishu): add pagination support for drive list and info#94000

Closed
ajwan8998 wants to merge 17 commits into
openclaw:mainfrom
ajwan8998:fix/issue-93928-feishu-drive-pagination
Closed

fix(feishu): add pagination support for drive list and info#94000
ajwan8998 wants to merge 17 commits into
openclaw:mainfrom
ajwan8998:fix/issue-93928-feishu-drive-pagination

Conversation

@ajwan8998

@ajwan8998 ajwan8998 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Feishu drive list and info actions do not handle pagination. When a folder has more files than the default API page size (10), list returns only the first page. info searches only the first page and falsely reports File not found for any file beyond page 1.

Root cause: listFolder and getFileInfo call client.drive.file.list() once without reading has_more or next_page_token. The Lark API supports cursor-based pagination but the tool ignores both cursor fields.

Changes

  • extensions/feishu/src/drive-schema.ts: add page_size, page_token, all to list action
  • extensions/feishu/src/drive.ts:
    • listFolder: pagination loop with MAX_LIST_PAGES = 100, cursor dedup via seenTokens
    • getFileInfo: iterate all pages before File not found, cursor dedup
  • extensions/feishu/src/drive.test.ts: pagination tests

Real behavior proof

  • Behavior addressed: Feishu drive silently ignores pagination, returns incomplete results.
  • Real environment tested: npx tsx -e with FeishuDriveSchema imported via TypeBox. Pagination logic replicated and verified with node --input-type=module. OpenClaw 2026.6.10, Node v24.
  • Evidence:
--- Schema (FeishuDriveSchema via TypeBox) ---
  list:  page_size=true page_token=true all=true  ✅

--- Pagination loop ---
  Normal pagination: page_0→page_1→page_2→(none)  ✅
  Duplicate cursor: page_0→page_1 (seen)→BREAK     ✅
  all=false: 1 page fetched (backward compatible)    ✅
  all=true:  iterates until has_more=false           ✅
  MAX_LIST_PAGES=100: caps at 100 iterations         ✅

Tests: node scripts/run-vitest.mjs extensions/feishu/src/drive.test.ts --run19 passed (19).

Evidence

$ npx tsx -e ...

=== FeishuDriveSchema runtime validation ===
  list:  page_size=true page_token=true all=true  ✅

=== Pagination with cursor dedup ===
  Normal:  page_0→page_1→page_2→(none) no false dedup  ✅
  Duplicate: page_0→"page_1"→seen "page_1"→BREAK       ✅

=== Code changes ===
  line 351: seenTokens set tracks requested page tokens
  line 381: break on duplicate token (listFolder)
  line 423-425: break on duplicate token (getFileInfo)

Tests: 19 passed (19)

What was not tested: End-to-end with a real Feishu tenant (requires credentials). Pagination loop verified through unit tests (19 passed) and isolated logic proof.

@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: S proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 17, 2026
@clawsweeper

clawsweeper Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 5:53 AM ET / 09:53 UTC.

Summary
The branch adds Feishu drive list cursor parameters and optional fetch-all pagination, paginates info lookups across drive.file.list pages, updates drive tests, and documents list pagination options.

PR surface: Source +69, Tests +213, Docs +14. Total +296 across 4 files.

Reproducibility: yes. source-reproducible: current main exposes no list cursor input, listFolder calls drive.file.list once, and getFileInfo searches one response before File not found. I did not run a live Feishu tenant reproduction.

Review metrics: 2 noteworthy metrics.

  • Feishu drive tool inputs: 4 added, 0 removed. The PR expands the model-facing Feishu drive action contract with list cursor inputs, automatic fetch-all, and scoped info lookup.
  • Automatic fetch-all mode: 1 added, capped at 100 pages. A single tool invocation can issue many external Feishu API requests, so maintainers should review the availability tradeoff before merge.

Stored data model
Persistent data-model change detected: vector/embedding metadata: extensions/feishu/src/drive.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #93928
Summary: This PR is the active candidate fix for the canonical Feishu drive list/info pagination bug; several earlier same-root-cause PRs are closed unmerged.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted live Feishu/Lark output, logs, terminal screenshot, or recording showing list and info against a real multi-page folder.
  • Guard or remove list.all so automatic pagination cannot repeat a cursorless page.
  • [P1] Fix the lint failures and update the drive skill info section for scoped folder_token lookups.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides unit/mocked and isolated terminal proof only and explicitly says no live Feishu tenant was tested. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The contributor proof remains unit/mocked and isolated terminal output; the PR body explicitly says no live Feishu tenant was tested.
  • [P1] The new list.all mode can spend up to 100 Feishu list requests from one tool call and still repeats the uncursored first page when has_more is true without next_page_token.
  • [P1] The exact PR head currently fails check-lint on two new single-line if guards in the Feishu drive pagination code.

Maintainer options:

  1. Guard Cursorless Fetch-All (recommended)
    Continue list.all only when has_more is true and the response includes a fresh unseen next_page_token, with regression coverage for the missing-cursor case.
  2. Remove Automatic Fetch-All
    Keep explicit page_size/page_token support and drop all:true if maintainers do not want one tool call to own multi-request external pagination.
  3. Accept The Bounded Call Cost
    Maintain all:true deliberately only after live Feishu proof or maintainer override confirms the external API behavior and the 100-call cap is acceptable.

Next step before merge

  • [P1] Human review is needed because automation cannot supply the contributor's live Feishu tenant proof or make the maintainer product call on automatic fetch-all, even though the remaining code/doc fixes are narrow.

Security
Cleared: No concrete security or supply-chain concern was found; the diff stays within Feishu plugin runtime, schema, tests, and skill docs without dependency or workflow changes.

Review findings

  • [P2] Stop all without a fresh cursor — extensions/feishu/src/drive.ts:381-382
  • [P2] Add braces around the initial token guard — extensions/feishu/src/drive.ts:353
  • [P2] Add braces around the returned token guard — extensions/feishu/src/drive.ts:386
Review details

Best possible solution:

Land a Feishu-plugin-local cursor pagination fix after live Feishu proof or maintainer override, a cursor-safe fetch-all decision, passing lint, and skill docs that match the new scoped info behavior.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible: current main exposes no list cursor input, listFolder calls drive.file.list once, and getFileInfo searches one response before File not found. I did not run a live Feishu tenant reproduction.

Is this the best way to solve the issue?

No. Cursor pagination and paginated info lookup are the right plugin-local repair, but the current PR still needs a cursorless fetch-all guard or product acceptance, lint repair, docs alignment, and live proof or override.

Full review comments:

  • [P2] Stop all without a fresh cursor — extensions/feishu/src/drive.ts:381-382
    With all: true, hasMore is set before checking whether the response returned a cursor. If Feishu sends has_more: true without next_page_token, the next loop repeats the uncursored folder request and appends duplicate first-page data until the 100-page cap.
    Confidence: 0.9
  • [P2] Add braces around the initial token guard — extensions/feishu/src/drive.ts:353
    The exact-head check-lint job reports eslint(curly) on this new one-line if, so the PR cannot pass lint until this guard uses braces.
    Confidence: 1
  • [P2] Add braces around the returned token guard — extensions/feishu/src/drive.ts:386
    The exact-head check-lint job also reports eslint(curly) on this new one-line if; wrap the branch in braces to clear the lint failure.
    Confidence: 1
  • [P3] Document scoped info lookups in the skill — extensions/feishu/src/drive-schema.ts:43-45
    The PR adds info.folder_token to the tool schema/runtime, but the bundled drive skill still says info searches root and tells agents to browse folders first. Update the skill so agents can use the new scoped lookup.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.91

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 738b2be4b49b.

Label changes

Label justifications:

  • P2: This is a normal-priority Feishu plugin bugfix for a clear source-reproducible drive list/info defect with limited blast radius.
  • merge-risk: 🚨 availability: The new list.all path can issue up to 100 external Feishu list calls and still needs a cursorless-response stop condition.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides unit/mocked and isolated terminal proof only and explicitly says no live Feishu tenant was tested. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +69, Tests +213, Docs +14. Total +296 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 112 43 +69
Tests 1 213 0 +213
Docs 1 16 2 +14
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 341 45 +296

What I checked:

  • Repository policy read: Root AGENTS.md and scoped extensions/AGENTS.md were read fully; plugin-boundary, dependency-contract, whole-path review, and real-proof rules applied to this review. (AGENTS.md:1, 738b2be4b49b)
  • Current main runtime remains first-page-only: Current main listFolder calls client.drive.file.list once, and getFileInfo searches only that single response before throwing File not found. (extensions/feishu/src/drive.ts:331, 738b2be4b49b)
  • Current main schema has no list cursor input: The current list action schema exposes only folder_token, so callers cannot feed a returned next_page_token back into feishu_drive list. (extensions/feishu/src/drive-schema.ts:23, 738b2be4b49b)
  • Latest release is still affected: v2026.6.10 has the same one-call drive list/info implementation and no list page_token schema, so the fix has not shipped. (extensions/feishu/src/drive.ts:331, aa69b12d0086)
  • Lark SDK pagination contract checked: The pinned @larksuiteoapi/node-sdk 1.66.0 type surface declares drive.file.list params page_size, page_token, and folder_token, and returns next_page_token plus has_more. (extensions/feishu/package.json:11, 738b2be4b49b)
  • PR head still repeats cursorless fetch-all pages: The PR sets hasMore from has_more && all before checking whether next_page_token is present; with has_more true and no cursor, the next iteration repeats the uncursored request until the cap. (extensions/feishu/src/drive.ts:381, 4122497f8e72)

Likely related people:

  • doodlewind: GitHub path history shows commit 2267d58 introduced the community Feishu plugin, including drive runtime, schema, and bundled drive skill files. (role: introduced Feishu drive surface; confidence: high; commits: 2267d58afcc7; files: extensions/feishu/src/drive.ts, extensions/feishu/src/drive-schema.ts, extensions/feishu/skills/feishu-drive/SKILL.md)
  • wittam-01: Path history shows this contributor added and hardened Feishu drive comment/reply paths that already expose pagination in the same runtime and schema area. (role: adjacent Feishu drive contributor; confidence: medium; commits: 1b94e8ca14de, ce0ff42ff5ed; files: extensions/feishu/src/drive.ts, extensions/feishu/src/drive-schema.ts)
  • steipete: Recent Feishu history includes account-aware tool routing, schema dependency migration, and shared helper refactors around the same plugin runtime surfaces. (role: recent Feishu runtime contributor; confidence: medium; commits: 125dc322f5c5, 29a5ab9632b9, b2472d65607a; files: extensions/feishu/src/drive.ts, extensions/feishu/src/drive-schema.ts, extensions/feishu/src/tool-account.ts)
  • ZengWen-DT: Recent sibling Feishu wiki pagination work fixed the same has_more/page_token class for wiki list surfaces. (role: adjacent pagination fix author; confidence: medium; commits: 5f90f0895750; files: extensions/feishu/src/wiki.ts, extensions/feishu/src/wiki-schema.ts)
  • vincentkoc: A member comment records branch maintenance and validation for this PR's active review lane, and path history shows recent plugin hardening work. (role: recent reviewer and branch-maintenance contact; confidence: medium; commits: 6600c8671514, 5f3b8b41004c; files: extensions/feishu/src/drive.ts, extensions/feishu/src/drive.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

ajwan8998 and others added 7 commits June 17, 2026 22:28
drive list and drive info only checked the first page of results
(default page size 10). When a folder contained more files than one
page, list would silently return incomplete results and info would
throw 'File not found' for files on subsequent pages.

Fix:
- listFolder: add pagination loop with has_more/next_page_token
- getFileInfo: search across all pages using pagination
- drive-schema: add page_size, page_token, all parameters to list action

Closes: openclaw#93928

Co-Authored-By: Claude <[email protected]>
@vincentkoc

Copy link
Copy Markdown
Member

Clownfish 🐠 reef update

Thanks for the contribution here. Clownfish nudged this branch back into the current, so the original PR can stay the review lane.

Source PR: #94000
Validation: pnpm test extensions/feishu/src/drive.test.ts; pnpm check:changed
Credit remains with the original contribution. Clownfish is just doing the branch-maintenance snorkel.

fish notes: model gpt-5.5, reasoning medium; reviewed against 6600c86.

@vincentkoc
vincentkoc force-pushed the fix/issue-93928-feishu-drive-pagination branch from dadddf3 to 6600c86 Compare June 17, 2026 22:28
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 17, 2026
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jun 19, 2026
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 19, 2026
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Add MAX_LIST_PAGES cap (100) to the all-pages pagination loop so a
repeated or missing next_page_token from the Feishu API does not
cause unbounded requests.
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. and removed triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jun 20, 2026
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

4 similar comments
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Guard against API returning repeated cursors: track seen page tokens
and break on duplicates. Prevents duplicate file entries and wasteful
repeated requests even before MAX_LIST_PAGES is reached.

Closes: openclaw#93928
@ajwan8998

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

The manual list continuation portion landed through #101572 as commit 69b9932fae45423e5ee6b391406a3f09eb466a4c.

Closing this broader candidate rather than landing its automatic all mode and root-scanning info loop. Feishu bot credentials do not have a browsable root, so the remaining info behavior needs a folder-aware contract and focused proof instead of silently draining an unsupported root listing. #93928 remains open for that narrower follow-up.

Thank you @ajwan8998 for the implementation and regression investigation.

@steipete steipete closed this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: blank-template Candidate: PR template appears mostly untouched.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants