Skip to content

AI_UnsupportedFunctionalityError: 'file part media type application/pdf' when using @ai-sdk/openai-compatible #16338

Description

@fengkiej

Description

When sending PDF file attachments to models configured with @ai-sdk/openai-compatible (e.g., via a custom LiteLLM provider), OpenCode throws:

AI_UnsupportedFunctionalityError: 'file part media type application/pdf' functionality not supported.

This occurs despite the model config declaring "pdf" in its input modalities.

Root Cause

The @ai-sdk/openai-compatible package is listed in BUNDLED_PROVIDERS in packages/opencode/src/provider/provider.ts:

const BUNDLED_PROVIDERS: Record<string, (options: any) => SDK> = {
  // ...
  "@ai-sdk/openai-compatible": createOpenAICompatible,
  // ...
}

When a model's api.npm matches a key in BUNDLED_PROVIDERS, OpenCode uses the bundled version rather than dynamically loading from npm:

const bundledFn = BUNDLED_PROVIDERS[model.api.npm]
if (bundledFn) {
  log.info("using bundled provider", { providerID: model.providerID, pkg: model.api.npm })
  const loaded = bundledFn({ name: model.providerID, ...options })
  s.sdk.set(key, loaded)
  return loaded as SDK
}

The bundled version of @ai-sdk/openai-compatible (currently 1.0.32 in package.json on the dev branch) contains a convertToOpenAICompatibleChatMessages function that only handles image/* media types for file parts. After the image check, it falls through directly to the error:

// Bundled version (simplified)
if (part.mediaType.startsWith("image/")) {
  // handles images...
} else {
  throw new UnsupportedFunctionalityError({
    functionality: `file part media type ${part.mediaType}`
  });
}

There is no handling for application/pdf, audio/*, or text/* file parts.

Meanwhile, the latest upstream @ai-sdk/openai-compatible from Vercel (source) does handle these media types correctly:

// Latest upstream version handles all these:
if (part.mediaType.startsWith("image/")) { /* ... */ }
if (part.mediaType.startsWith("audio/")) { /* ... */ }
if (part.mediaType === "application/pdf") {
  return {
    type: "file",
    file: {
      filename: part.filename ?? "document.pdf",
      file_data: `data:application/pdf;base64,${convertToBase64(part.data)}`,
    },
  };
}
if (part.mediaType.startsWith("text/")) { /* ... */ }

Note: Other bundled providers like @ai-sdk/openai use a different, newer conversion function (type: "input_image" / type: "input_file" style) that does support PDF. The issue is specific to the @ai-sdk/openai-compatible adapter.

Plugins

No response

OpenCode version

1.2.16 (also affects latest dev branch at v1.2.20)

Steps to reproduce

  1. Configure a custom provider in opencode.json using @ai-sdk/openai-compatible:
    {
      "provider": {
        "litellm": {
          "name": "LiteLLM",
          "npm": "@ai-sdk/openai-compatible",
          "models": {
            "some-model": {
              "attachment": true,
              "modalities": {
                "input": ["text", "image", "pdf"],
                "output": ["text"]
              }
              // ...
            }
          },
          "options": {
            "baseURL": "http://localhost:4000/v1"
          }
        }
      }
    }
  2. Attach a PDF file to a message
  3. Send the message

Expected: PDF is base64-encoded and sent to the model as a file part.
Actual: AI_UnsupportedFunctionalityError: 'file part media type application/pdf' functionality not supported.

Screenshot and/or share link

No response

Operating System

Ubuntu 24.04

Terminal

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions