Skip to content

feat: support OpenAI file library APIs#606

Open
qchuchu wants to merge 2 commits intomainfrom
feat/file-library-apis
Open

feat: support OpenAI file library APIs#606
qchuchu wants to merge 2 commits intomainfrom
feat/file-library-apis

Conversation

@qchuchu
Copy link
Copy Markdown
Contributor

@qchuchu qchuchu commented Mar 25, 2026

Summary

  • Add selectFiles() to useFiles() hook — opens ChatGPT's file library picker (with feature detection for hosts that don't support it yet)
  • Add { library?: boolean } option to upload() — saves uploads to the user's ChatGPT file library
  • Extend FileMetadata type with optional fileName and mimeType fields
  • Update getFileDownloadUrl to document expanded scope (uploads, selected files, tool/file params)
  • Extract trackFileIds helper in AppsSdkAdaptor to DRY widget state updates

Closes #605

Test plan

  • Unit tests pass (pnpm test)
  • Build passes (pnpm build)
  • Manual test in everything example app on ChatGPT (note: selectFiles is documented but not yet available in the host runtime)

🤖 Generated with Claude Code

Greptile Summary

This PR extends useFiles() with two new capabilities: a selectFiles() method that opens ChatGPT's file library picker (with proper feature detection for older host versions) and a { library?: boolean } option on upload() to persist files to the user's library. FileMetadata is also enriched with optional fileName and mimeType fields.

Key changes:

  • AppsSdkAdaptor extracts the repeated widgetState imageIds update into a private trackFileIds helper used by both uploadFile and the new selectFiles — a clean DRY improvement
  • McpAppAdaptor adds a correctly-throwing selectFiles stub, consistent with the existing pattern for other unsupported file methods
  • New unit tests cover the library upload option and selectFiles success path; the switch from vi.resetAllMocks() to vi.clearAllMocks() leaves a dynamically-added OpenaiMock.selectFiles property alive across subsequent tests, which could interfere with testing the unsupported-host code path in the future
  • Documentation and example app are updated thoroughly

Confidence Score: 4/5

  • PR is safe to merge; the one minor concern is a test isolation issue that doesn't affect production behavior.
  • The implementation is clean, feature detection is correctly applied, the trackFileIds refactor is a net improvement, and the MCP stub follows the established pattern. The only flag is a P2 test hygiene issue: vi.clearAllMocks() doesn't remove the selectFiles property added in one test, leaving it visible to subsequent tests and making the unsupported-host path untestable without a cleanup step.
  • packages/core/src/web/hooks/use-files.test.ts — mock cleanup for the dynamically-added selectFiles property
Prompt To Fix All With AI
This is a comment left during a code review.
Path: packages/core/src/web/hooks/use-files.test.ts
Line: 45-56

Comment:
**Test mock leaks to sibling tests**

`OpenaiMock.selectFiles` is assigned inside this test body, but `vi.clearAllMocks()` (changed from `vi.resetAllMocks()`) only clears call history — it does not remove properties added to `OpenaiMock`. Because `OpenaiMock` is shared across all tests in the suite, any test that runs *after* this one will observe `window.openai.selectFiles` as defined, even if the test doesn't expect it to be.

In practice this means the "unsupported host" code path in `AppsSdkAdaptor.selectFiles` (the `!window.openai.selectFiles` guard) can never be exercised by a future test without an explicit cleanup step. Consider either:

1. Deleting the property in `afterEach` (or resetting it to `undefined`), or
2. Moving the assignment into `beforeEach` alongside the other mock setup and using `vi.resetAllMocks()` (which would clear the mock implementation) combined with a per-test override.

```suggestion
  it("should select files from ChatGPT", async () => {
    const selectedFiles = [
      { fileId: "file_1", fileName: "doc.pdf", mimeType: "application/pdf" },
    ];
    OpenaiMock.selectFiles = vi.fn().mockResolvedValue(selectedFiles);

    const { result } = renderHook(() => useFiles());

    const files = await result.current.selectFiles();
    expect(OpenaiMock.selectFiles).toHaveBeenCalled();
    expect(files).toEqual(selectedFiles);

    delete OpenaiMock.selectFiles;
  });
```

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

Reviews (1): Last reviewed commit: "feat: support OpenAI file library APIs (..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

…ry option)

Closes #605

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mintlify
Copy link
Copy Markdown
Contributor

mintlify bot commented Mar 25, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
skybridge-staging 🟢 Ready View Preview Mar 25, 2026, 8:40 AM

@qchuchu qchuchu self-assigned this Mar 25, 2026
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.

feat: support new OpenAI file library APIs (selectFiles, uploadFile library option)

1 participant