Skip to content

File Uploads

File uploads are Library-owned today. They let a user add a local device file to an eligible connected provider. The uploaded provider file is then indexed through the normal connector sync/embedding path for private chat focus and retrieval.

  • User file uploads require a connected file provider that supports uploads and has indexed Library ingestion enabled.
  • Current upload support is Google Drive upload access through the shared provider-backed upload adapter registry.
  • A read-only Google Drive connection is not an upload destination. The upload UI can show it as an access-upgrade candidate and start reauthorization; the connector setting is changed to upload-capable only after the linked account has the required upload scope.
  • Changing an upload-capable connector back to read-only removes upload eligibility inside the app immediately. It does not silently remove provider OAuth scopes that were already granted; users who need provider-side write access removed must revoke the app grant with the provider or relink the account.
  • OneDrive can be used for file browsing, Library add, and focus through the connector resource interface, but it is not currently an upload destination because the OneDrive write-scope upload adapter is not implemented.
  • The Library upload picker reads one upload-source contract from the API. Rows marked Ready can be opened as destinations and are intentionally shown before setup or unavailable rows; ties use connector display name and resolved linked-account label instead of backend recency. Non-ready rows use state-specific affordances: adapter-supported read-only rows can offer Enable uploads, upload-capable rows with indexed Library ingestion off explain that indexing must be changed from connector settings without auto-enabling it, and unsupported providers such as current OneDrive stay visible as passive not-supported rows with no connector-settings action.
  • Destination and folder selection reuse the shared connector drilldown browser in current-folder mode. The browser starts at upload-capable connector destinations; opening one selects that destination after its folder listing loads. Clicking or tapping a folder row opens that folder, and the current folder becomes the upload target only after navigation finishes. Folder rows can show direct child file/folder counts from the shared connector resource-list contract; even folders with zero child folders can be opened so users can choose them as the upload destination. The upload flow chooses one destination folder, does not use the Library/focus transfer list, and upload eligibility still comes from the provider-backed write adapter registry.
  • Same-name files in the selected provider folder require explicit overwrite confirmation. API checks for the existing provider file before creating the upload session; cancelling the confirmation leaves the provider, Upload, and LibraryJob state unchanged. Confirmed overwrite stores the provider file id being replaced, updates that file in place, and reuses the existing Library item when indexing reports the replacement content.
  • There is no separate Library indexing engine for provider-backed uploads. After the provider upload succeeds, the upload flow requests and queues connector sync before surfacing sync-requested; sync request or queue failure marks the Library job failed. The upload becomes ready when connector metadata reaches indexed state.
  • Upload readiness is shown through Library job state, not connector dashboard status alone. Canonical LibraryJob rows own provider-upload job status, and upload sessions store provider metadata such as destination folder, provider file id, and linked Library item id. Connector embedding ingestion reconciles the Library job to ready, actionable not-indexed, failed, or non-actionable terminal state after durable metadata/vector writes. Connector settings changes that turn indexed mode on or off also run provider-upload readiness reconciliation for that connector. If an existing upload landed in a connector without indexed ingestion enabled, the job resolves internally instead of staying pending, but Library readiness and inline Library contents status rows do not ask the user to fix indexing they intentionally left off. Indexed-mode toggles delete vector/indexed artifacts only; they preserve Library items, Upload records, and provider file metadata.
  • Inline Library upload readiness updates through library-job-updated realtime events and HTTP job snapshots. The snapshot route returns job rows plus compact Library readiness so reconnect recovery updates counts/status. Ready upload jobs collapse into the durable Library item row they created, and routine upload progress does not create durable notifications.
  • Direct chat-composer uploads are deferred; users add files through Library-owned content management.
  • Uploaded originals live in the selected external provider account and folder, not in durable platform object storage.
  • For Google Drive, the original file is created in the selected Drive account/folder through the Google Drive API.
  • The platform stores app-owned upload metadata, pending upload state, provider resource identifiers needed for follow-up processing, and the extracted text/chunks/vectors produced after indexing.
  • Provider ownership remains visible to users: disconnecting or losing provider access can make the original unavailable even if platform metadata still exists.
  • Treat upload capability as connector scope and provider setup, not a generic platform storage toggle.
  • Treat indexed ingestion as part of Library upload eligibility. Upload access alone is not enough because Library upload is intended to produce searchable/focusable content.
  • Do not mark read-only file connectors as ready upload destinations in UI, API, docs, or tests. If the provider has an upload adapter, show the upload-access action from the shared contract instead of inferring configuration locally.
  • Do not offer upload configuration or reauthorization for unsupported upload providers. A connected unsupported provider may be shown for clarity, but it must stay passive and non-actionable for upload until upload support exists.
  • Do not reuse the read/list resource picker contract as proof of uploadability. Upload requires a separate provider write capability and provider write scopes.
  • Do not create duplicate provider files for same-name upload conflicts. Use the shared upload conflict-resolution contract and require explicit user confirmation before sending the provider overwrite request.
  • Reuse the connector drilldown browser and connector resource-list contract for provider file/folder navigation instead of creating provider-specific folder-list UI. Direct child count metadata must stay connector-agnostic and optional; unknown counts should not be treated as empty.
  • If another file provider adds upload support later, update the shared upload adapter registry, provider setup docs, Library docs, upload tests, and this page together.
  • OneDrive upload support specifically needs a Microsoft Graph write-scope upload adapter, scope truth in the connector registry/auth flow, upload folder/file API implementation, and tests proving OneDrive remains hidden until that adapter exists.
  • docs/features/library/spec.md
  • docs/features/connectors/spec.md
  • docs/features/ingestion/spec.md
  • packages/domain/src/connectors/connectorRegistry.ts
  • packages/domain/src/connectors/providerBackedUploadCapability.ts
  • apps/web/app/pages/library
  • apps/web/app/stores/authenticated/storeLibraries.ts
  • apps/api/src/library/libraryJobService.ts
  • apps/api/src/uploads/providerUploadService.ts
  • apps/api/src/ingestion/connectorEmbeddingIngestionService.ts