Skip to content

MSTeams: add upload session fallback for large files#32558

Closed
zwright8 wants to merge 1 commit intoopenclaw:mainfrom
zwright8:codex/pr26712-msteams-upload-fallback
Closed

MSTeams: add upload session fallback for large files#32558
zwright8 wants to merge 1 commit intoopenclaw:mainfrom
zwright8:codex/pr26712-msteams-upload-fallback

Conversation

@zwright8
Copy link
Copy Markdown

@zwright8 zwright8 commented Mar 3, 2026

Summary

Validation

  • pnpm exec vitest run extensions/msteams/src/graph-upload.test.ts

Context

This PR is one focused slice extracted from the previously oversized PR:

@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams size: M labels Mar 3, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 3, 2026

Greptile Summary

This PR adds a resumable Graph upload-session fallback to graph-upload.ts so that both OneDrive and SharePoint uploads automatically switch to chunked transfers for files larger than 4 MB. The refactor cleanly extracts uploadWithGraphSession, uploadSimpleOrChunked, and toUploadResult helpers, and tests cover the major paths (simple upload, multi-chunk upload, per-chunk retry, stall detection, session creation failure, and SharePoint).

Key observations:

  • The 5 MB chunk size (UPLOAD_SESSION_CHUNK_BYTES) is exactly 16 × 320 KiB, satisfying the Microsoft Graph requirement that all non-final ranges be multiples of 320 KiB.
  • Chunk uploads correctly omit the Authorization header, relying on the pre-authenticated upload session URL returned by Graph — this is intentional and correct per the API spec.
  • There is a subtle off-by-one: UPLOAD_SESSION_MAX_STALLS = 5 combined with the > guard actually allows 6 stalled retries before throwing. The test is internally consistent with this behaviour (6 stall mocks are queued), but the constant's name/value implies a limit of 5.

Confidence Score: 4/5

  • Safe to merge with one minor off-by-one fix recommended before landing
  • The core upload logic is correct, chunk alignment satisfies Graph API constraints, error handling and retry logic work as intended, and tests cover the main paths. The only issue is a semantic inconsistency in the stall-detection guard (> vs >=) that causes one extra retry beyond what the constant's value implies.
  • extensions/msteams/src/graph-upload.ts — stall-detection guard at line 125

Last reviewed commit: 5b6eee3

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile


if (nextChunkStart === chunkStart) {
stalledResponses += 1;
if (stalledResponses > UPLOAD_SESSION_MAX_STALLS) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Off-by-one: allows 6 stalls, not 5

UPLOAD_SESSION_MAX_STALLS is set to 5, but the guard uses strict greater-than (>), so stalledResponses must reach 6 before the error is thrown. This means the session is actually retried 6 times, not 5. The test confirms this (it provides 6 stalled responses before expecting the throw).

The constant's name and value imply the limit is 5, but the implementation allows one extra retry. Use >= to match the constant's intent:

Suggested change
if (stalledResponses > UPLOAD_SESSION_MAX_STALLS) {
if (stalledResponses >= UPLOAD_SESSION_MAX_STALLS) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/msteams/src/graph-upload.ts
Line: 125

Comment:
**Off-by-one: allows 6 stalls, not 5**

`UPLOAD_SESSION_MAX_STALLS` is set to `5`, but the guard uses strict greater-than (`>`), so `stalledResponses` must reach **6** before the error is thrown. This means the session is actually retried 6 times, not 5. The test confirms this (it provides 6 stalled responses before expecting the throw).

The constant's name and value imply the limit is 5, but the implementation allows one extra retry. Use `>=` to match the constant's intent:

```suggestion
        if (stalledResponses >= UPLOAD_SESSION_MAX_STALLS) {
```

How can I resolve this? If you propose a fix, please make it concise.

@zwright8 zwright8 force-pushed the codex/pr26712-msteams-upload-fallback branch from 5b6eee3 to 45bd05e Compare March 3, 2026 05:06
@BradGroux BradGroux self-assigned this Mar 10, 2026
@BradGroux
Copy link
Copy Markdown
Member

Hi @zwright8 — thanks for the submission. I’m the new Microsoft Teams maintainer for OpenClaw. Please give me a day or two to work through the open Teams backlog. Also, join the Twitter community for daily MS Teams feedback + updates: https://x.com/i/communities/2031170403607974228

1 similar comment
@BradGroux
Copy link
Copy Markdown
Member

Hi @zwright8 — thanks for the submission. I’m the new Microsoft Teams maintainer for OpenClaw. Please give me a day or two to work through the open Teams backlog. Also, join the Twitter community for daily MS Teams feedback + updates: https://x.com/i/communities/2031170403607974228

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 26, 2026

Codex review: found issues before merge.

What this changes:

The branch adds a Teams Graph upload-session fallback for OneDrive and SharePoint uploads over 4 MB, plus tests for simple uploads, chunked uploads, retry/stall behavior, session creation errors, and SharePoint.

Maintainer follow-up before merge:

This is an open implementation PR with a valid missing feature, maintainer assignment, and stale-branch integration issues; the next action is Teams maintainer rebase/review, not an autonomous cleanup close or standalone replacement job.

Security review:

Security review cleared: The diff adds Microsoft Graph upload-session calls and tests without new dependencies, workflow changes, package metadata changes, secret storage changes, or broader token scopes.

Review findings:

  • [P2] Preserve the User-Agent in upload helpers — extensions/msteams/src/graph-upload.ts:172-175
  • [P3] Enforce the stall cap at five responses — extensions/msteams/src/graph-upload.ts:125
Review details

Best possible solution:

Land a rebased Teams-only implementation that keeps direct /content uploads for small files, routes only larger OneDrive/SharePoint uploads through Graph upload sessions, preserves current User-Agent and resolveGraphChatId behavior/tests, and carries focused tests for session creation, chunk progression, retry/stall handling, errors, and SharePoint.

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

Yes. Current main can be inspected at the helper level: both upload helpers always issue a single /content PUT, and the PR's mocked tests exercise the missing upload-session path for larger buffers. I did not run tests because this review was required to stay read-only.

Is this the best way to solve the issue?

No, not as-is. The upload-session fallback belongs in the Teams upload helper, but this branch needs a rebase onto current main, must preserve the existing User-Agent and resolveGraphChatId behavior/tests, and should fix the stall guard before merge.

Full review comments:

  • [P2] Preserve the User-Agent in upload helpers — extensions/msteams/src/graph-upload.ts:172-175
    Current main imports buildUserAgent() and tests the OpenClaw User-Agent on Graph upload calls. The new shared upload helper sends simple upload requests without that header, and the session-creation helper does the same, so rebasing this patch as-is would regress Microsoft HTTP identification behavior.
    Confidence: 0.86
  • [P3] Enforce the stall cap at five responses — extensions/msteams/src/graph-upload.ts:125
    stalledResponses is incremented before this guard, but the comparison uses >, so UPLOAD_SESSION_MAX_STALLS = 5 permits six no-progress 202 responses. Use >= and update the test fixture count so the configured limit matches runtime behavior.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.86

Acceptance criteria:

  • pnpm test extensions/msteams/src/graph-upload.test.ts
  • pnpm exec oxfmt --check --threads=1 extensions/msteams/src/graph-upload.ts extensions/msteams/src/graph-upload.test.ts

What I checked:

  • Current OneDrive upload is direct-only: Current main still uploads OneDrive files with one authenticated PUT to /me/drive/root:/OpenClawShared/{filename}:/content; there is no size threshold, createUploadSession call, chunk loop, or nextExpectedRanges handling in this helper. (extensions/msteams/src/graph-upload.ts:42, 9061d1e4c3ee)
  • Current SharePoint upload is direct-only: Current main similarly uploads SharePoint files with one /content PUT to the configured site drive and does not route large buffers through an upload session. (extensions/msteams/src/graph-upload.ts:187, 9061d1e4c3ee)
  • Current tests protect User-Agent behavior: The current Teams upload tests assert the OpenClaw User-Agent header on OneDrive and SharePoint upload requests, while they do not cover upload-session chunk progression. (extensions/msteams/src/graph-upload.test.ts:30, 9061d1e4c3ee)
  • PR head implements the missing fallback: The PR head adds SIMPLE_UPLOAD_LIMIT_BYTES, UPLOAD_SESSION_CHUNK_BYTES, uploadWithGraphSession, and uploadSimpleOrChunked, then routes OneDrive and SharePoint uploads above the threshold to /createUploadSession. (extensions/msteams/src/graph-upload.ts:17, 45bd05e2a555)
  • PR head misses current User-Agent integration: The PR head has no buildUserAgent import and the new shared simple/session upload helpers send Microsoft requests without the current OpenClaw User-Agent header. (extensions/msteams/src/graph-upload.ts:170, 45bd05e2a555)
  • PR head has a stall-limit off-by-one: stalledResponses is incremented before the guard, but the guard uses > UPLOAD_SESSION_MAX_STALLS, so a constant value of 5 permits six no-progress responses before throwing; the existing review comment flags the same issue. (extensions/msteams/src/graph-upload.ts:125, 45bd05e2a555)

Likely related people:

  • BradGroux: The PR timeline shows BradGroux assigning himself and stating he is the Microsoft Teams maintainer, and the refreshed Microsoft tracker lists this PR under the Teams backlog with BradGroux as assignee. (role: Teams maintainer and assigned reviewer; confidence: high; files: extensions/msteams/src/graph-upload.ts, extensions/msteams/src/graph-upload.test.ts)
  • Peter Steinberger: The grafted local history shows the v2026.4.27 release snapshot adding the current Teams upload files under Peter Steinberger's release commit; this is useful routing evidence but not proof of original feature authorship. (role: release maintainer / current snapshot author; confidence: low; commits: cbc2ba093146; files: extensions/msteams/src/graph-upload.ts, extensions/msteams/src/graph-upload.test.ts)

Remaining risk / open question:

  • No live Microsoft tenant upload proof is present; mocked tests and Microsoft Graph docs support the path, but tenant policy differences could still need maintainer validation.
  • The branch is stale against current main, so conflict resolution around the existing graph-upload test file could accidentally drop newer User-Agent or chat-ID coverage.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9061d1e4c3ee.

@vincentkoc vincentkoc added the stale Marked as stale due to inactivity label Apr 26, 2026
@vincentkoc
Copy link
Copy Markdown
Member

This assigned pull request has been marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 27, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 27, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 28, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels Apr 28, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 29, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Apr 30, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This assigned pull request has been automatically marked as stale after being open for 27 days.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 30, 2026
@barnacle-openclaw
Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #clawtributors on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

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

Labels

channel: msteams Channel integration: msteams size: M stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants