Skip to content

[FEATURE] Proxy Anthropic Files through hybrid Otari #984

Description

@HareeshBahuleyan

Problem or use case

Octonous points the official Anthropic SDK at Otari, so Files API calls reach Otari first. Hybrid Otari does not mount /v1/files; uploads return 404 and never reach Anthropic. This blocks Anthropic native code execution from receiving CSV and other data files, and prevents generated files from being downloaded through the same Otari endpoint.

#976 adds Anthropic response shapes and file transfer for standalone Otari's own sandbox, but explicitly excludes hybrid mode. The hosted Anthropic path needs provider-native file forwarding instead.

Proposed solution

Expose the Anthropic-compatible Files API on hybrid gateways and forward it with the authenticated workspace's resolved Anthropic credential. Keep file bytes in Anthropic and return Anthropic file IDs unchanged.

The hosted control plane owns the binding records. Hybrid gateways remain stateless; bindings persist only stable credential and account identifiers, while provider secrets are resolved transiently for authorized requests and are never stored by the gateway.

Proxy POST /v1/files, GET /v1/files, GET /v1/files/{id}, GET /v1/files/{id}/content, and DELETE /v1/files/{id} while preserving the Anthropic SDK response and binary-download contracts. Because Files requests carry no model, extend the hybrid protocol to resolve one Anthropic provider account for the authenticated workspace. Reject a missing or ambiguous account. Pin inference requests containing files to that account and do not fall back to another provider or provider account.

The implementation must include these decisions:

  1. Binding ownership and visibility: Store file bindings in the hosted control-plane database. A binding is accessible only to its uploader within its workspace; workspace membership alone does not grant access. Each binding records that owner, the Anthropic file ID, stable provider credential/account identity, file metadata, expiry, and lifecycle state. Hybrid gateways only resolve and mutate bindings through the protocol.
  2. Credential identity: Bind a file to a stable provider-credential record and upstream account identity, never an API-key value. Credential replacement invalidates existing bindings unless Otari can verify a stable upstream account identity. Matching provider type or credential-record ID alone is insufficient. Cleanup or explicitly orphan affected upstream files before the old credential becomes unavailable.
  3. Listing: Build and paginate listings from uploader-and-workspace-scoped binding records, then hydrate provider metadata as needed. Do not list a shared Anthropic account and filter afterward, because provider pagination can leak, skip, or duplicate files across tenants. Preserve the pagination shape required by the caller's Anthropic SDK and beta headers.
  4. Upload and output atomicity: Do not return an uploaded Anthropic file ID until its tenant binding is committed. If binding persistence fails after the provider upload succeeds, attempt immediate upstream deletion and persist cleanup work for retry. Apply the same rule to generated code-execution outputs: commit an idempotent binding before exposing the provider file ID, and hold streamed file-reference blocks until registration succeeds.
  5. Deletion, expiry, and privacy: Revoke local access immediately. If upstream deletion fails, record an explicit pending_cleanup state and return an upstream deletion failure rather than reporting complete deletion while the provider copy remains. Cover user, workspace, and account deletion; provider expiry; credential removal; and cleanup retries. Encrypt sensitive file metadata at rest, never log filenames or file contents, and bound upload and download size, duration, and rate.

Before sending anything to Anthropic, collect and validate every file reference across the complete Messages history, not only the latest user message. Resolve all references against the authenticated uploader and workspace, require them to belong to the selected Anthropic account, and reject missing, foreign, expired, deleted, or mixed-account references before the provider call.

The hosted contract should exercise upload, container_upload, native code execution, generated-file download, and deletion through an official Anthropic SDK pointed at Otari. It should also cover cross-user and cross-workspace access, ambiguous provider selection, provider-account mismatch, credential rotation or removal, expiry, upstream failures, upload compensation, binding persistence before streamed output exposure, and file references in earlier Messages history.

Alternatives considered

Octonous could call Anthropic's Files API directly, but that requires access to the same Anthropic credential Otari later uses and does not work with Otari-managed credentials. Returning new Otari-specific file IDs is unnecessary for the initial Anthropic-only path; preserving Anthropic IDs plus a tenant ownership binding keeps the first implementation smaller.

This first implementation is a foundation for Octonous → hosted Otari → managed Anthropic Files API, not for provider-neutral Anthropic, OpenAI, and Gemini fallback. Anthropic marks user-uploaded files as non-downloadable; only files generated by code execution or skills can be downloaded. If Otari keeps uploaded bytes only in Anthropic, it cannot later copy those inputs to another provider. Pinning file-bearing inference to the owning Anthropic account makes that limitation acceptable for this scope. Provider-neutral fallback would require retaining the original bytes during upload or uploading them to every eligible provider, which is separate work.

Ref: mozilla-ai/octonous#4903; #976

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions