Skip to content

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

@fengkiej

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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions