Repository: vercel/ai (TypeScript)

Issue:
Support textVerbosity option for openai-compatible
### Description

I've configured [opencode.ai](https://opencode.ai) to use @ai-sdk/openai-compatible to talk to our Azure gateway serving the OpenAI models. When the model name contains the string `gpt-5` opencode adds the [`textVerbosity` option](https://ai-sdk.dev/providers/ai-sdk-providers/openai#verbosity-control) and this cause failure as the provider returns `AI_APICallError: Unknown parameter: 'textVerbosity'.`.

It seems like this option is just passed as is to the underlying wire protocol.  If I read the [OpenAI chat completions protocol description](https://platform.openai.com/docs/api-reference/chat/create#chat-create-verbosity) correctly it should be turned into `verbosity` on the wire.

### AI SDK Version

@ai-sdk/openai-compatible 1.0.18

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct


Discussion:
I've now tried to figure out how to demonstrate this issue with a standalone program:

```javascript
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { generateText } from 'ai';

const provider = createOpenAICompatible({
  name: 'uib-gw',
  baseURL: "https://openai-gw.uib.no",
  apiKey: `grav-${process.env.OPENAI_GRAVITEE_KEY}`
});

const model = provider('gpt-5-mini');

const { text } = await generateText({
  model: model,
  prompt: 'hi there',
  providerOptions: {
    'uib-gw': {
        reasoningEffort: 'low',
        textVerbosity: 'low',
    },
  },
});

console.log(text)
```

When I run this it fails with this error message:

```
node hello.js
node:internal/modules/run_main:107
    triggerUncaughtException(
    ^

APICallError [AI_APICallError]: Unknown parameter: 'textVerbosity'.
    at file:///Users/gisle/u/ai-sdk/node_modules/@ai-sdk/provider-utils/dist/index.mjs:847:14
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async postToApi (file:///Users/gisle/u/ai-sdk/node_modules/@ai-sdk/provider-utils/dist/index.mjs:699:28)
    at async OpenAICompatibleChatLanguageModel.doGenerate (file:///Users/gisle/u/ai-sdk/node_modules/@ai-sdk/openai-compatible/dist/index.mjs:376:9)
    at async fn (file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:2277:34)
    at async file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:1551:22
    at async _retryWithExponentialBackoff (file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:1702:12)
    at async fn (file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:2235:34)
    at async file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:1551:22
    at async generateText (file:///Users/gisle/u/ai-sdk/node_modules/ai/dist/index.mjs:2180:12) {
  cause: undefined,
  url: 'https://openai-gw.uib.no/chat/completions',
  requestBodyValues: {
    model: 'gpt-5-mini',
    user: undefined,
    max_tokens: undefined,
    temperature: undefined,
    top_p: undefined,
    frequency_penalty: undefined,
    presence_penalty: undefined,
    response_format: undefined,
    stop: undefined,
    seed: undefined,
    textVerbosity: 'low',
    reasoning_effort: 'low',
    messages: [ { role: 'user', content: 'hi there' } ],
    tools: undefined,
    tool_choice: undefined
  },
  statusCode: 400,
  responseHeaders: {
    'apim-request-id': 'e074cfb8-b2da-4699-9298-8511aeda386f',
    'cache-control': 'private, max-age=0, no-cache, no-store',
    connection: 'keep-alive',
    'content-length': '173',
    'content-type': 'application/json',
    date: 'Tue, 23 Sep 2025 12:45:46 GMT',
    'strict-transport-security': 'max-age=31536000; includeSubDomains',
    'uio-cache-status': 'MISS',
    'x-gravitee-request-id': '4d138023-c9f9-4070-9380-23c9f99070f7',
    'x-gravitee-transaction-id': '4d138023-c9f9-4070-9380-23c9f99070f7',
    'x-ms-deployment-name': 'gpt-5-mini',
    'x-ms-rai-invoked': 'true',
    'x-ms-region': 'Sweden Central',
    'x-ratelimit-limit-requests': '250',
    'x-ratelimit-limit-tokens': '250000',
    'x-ratelimit-remaining-requests': '249',
    'x-ratelimit-remaining-tokens': '249997',
    'x-request-id': '37ba2e6d-5750-430e-ac8b-b42a966f43d4'
  },
  responseBody: '{\n' +
    '  "error": {\n' +
    `    "message": "Unknown parameter: 'textVerbosity'.",\n` +
    '    "type": "invalid_request_error",\n' +
    '    "param": "textVerbosity",\n' +
    '    "code": "unknown_parameter"\n' +
    '  }\n' +
    '}',
  isRetryable: false,
  data: {
    error: {
      message: "Unknown parameter: 'textVerbosity'.",
      type: 'invalid_request_error',
      param: 'textVerbosity',
      code: 'unknown_parameter'
    }
  },
  Symbol(vercel.ai.error): true,
  Symbol(vercel.ai.error.AI_APICallError): true
}

Node.js v24.8.0
```

As you can see the `reasoningEffort` is transformed into `reasoning_effort` but `textVerbosity` is not transformed into `verbosity` as I would expect.
thanks @gisle .

 Created PR for textVerbosity support @gr2m 



Patch:
diff --git a/.changeset/friendly-jobs-learn.md b/.changeset/friendly-jobs-learn.md
new file mode 100644
index 000000000000..b6a45f8641b5
--- /dev/null
+++ b/.changeset/friendly-jobs-learn.md
@@ -0,0 +1,5 @@
+---
+'@ai-sdk/openai-compatible': patch
+---
+
+Add textVerbosity provider option support
diff --git a/examples/ai-core/src/generate-text/openai-compatible-chat-provider-options.ts b/examples/ai-core/src/generate-text/openai-compatible-chat-provider-options.ts
new file mode 100644
index 000000000000..99760a45fea6
--- /dev/null
+++ b/examples/ai-core/src/generate-text/openai-compatible-chat-provider-options.ts
@@ -0,0 +1,30 @@
+import { generateText } from 'ai';
+import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
+import 'dotenv/config';
+
+async function main() {
+  const openai = createOpenAICompatible({
+    baseURL: 'https://api.openai.com/v1',
+    name: 'openai',
+    headers: {
+      Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
+    },
+  });
+
+  const model = openai.chatModel('gpt-5-mini');
+
+  const result = await generateText({
+    model: model,
+    prompt: 'Explain the theory of relativity in simple terms.',
+    providerOptions: {
+      openai: {
+        textVerbosity: 'low',
+        reasoningEffort: 'low',
+      },
+    },
+  });
+  console.log(result.text);
+  console.log(result.request.body);
+}
+
+main().catch(console.error);
diff --git a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.ts b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.ts
index 2dbd9bf2326e..8f54c9e1a6db 100644
--- a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.ts
+++ b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.ts
@@ -195,6 +195,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
         ),
 
         reasoning_effort: compatibleOptions.reasoningEffort,
+        verbosity: compatibleOptions.textVerbosity,
 
         // messages:
         messages: convertToOpenAICompatibleChatMessages(prompt),
diff --git a/packages/openai-compatible/src/chat/openai-compatible-chat-options.ts b/packages/openai-compatible/src/chat/openai-compatible-chat-options.ts
index 88b077470c20..4fd1877db0f0 100644
--- a/packages/openai-compatible/src/chat/openai-compatible-chat-options.ts
+++ b/packages/openai-compatible/src/chat/openai-compatible-chat-options.ts
@@ -13,6 +13,11 @@ export const openaiCompatibleProviderOptions = z.object({
    * Reasoning effort for reasoning models. Defaults to `medium`.
    */
   reasoningEffort: z.string().optional(),
+
+  /**
+   * Controls the verbosity of the generated text. Defaults to `medium`.
+   */
+  textVerbosity: z.string().optional(),
 });
 
 export type OpenAICompatibleProviderOptions = z.infer<


Test patch:
diff --git a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts
index 106be2ebe95f..4d85a0cfd3aa 100644
--- a/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts
+++ b/packages/openai-compatible/src/chat/openai-compatible-chat-language-model.test.ts
@@ -744,6 +744,55 @@ describe('doGenerate', () => {
       expect(body.customOption).toBe('should-be-included');
     });
 
+    it('should pass textVerbosity setting from providerOptions', async () => {
+      prepareJsonResponse({ content: '{"value":"test"}' });
+
+      const model = new OpenAICompatibleChatLanguageModel('gpt-5', {
+        provider: 'test-provider',
+        url: () => 'https://my.api.com/v1/chat/completions',
+        headers: () => ({}),
+      });
+
+      await model.doGenerate({
+        prompt: TEST_PROMPT,
+        providerOptions: {
+          'test-provider': { textVerbosity: 'low' },
+        },
+      });
+
+      expect(await server.calls[0].requestBodyJson).toStrictEqual({
+        model: 'gpt-5',
+        messages: [{ role: 'user', content: 'Hello' }],
+        verbosity: 'low',
+      });
+    });
+
+    it('should not duplicate textVerbosity in request body', async () => {
+      prepareJsonResponse({ content: '{"value":"test"}' });
+
+      const model = new OpenAICompatibleChatLanguageModel('gpt-5', {
+        provider: 'test-provider',
+        url: () => 'https://my.api.com/v1/chat/completions',
+        headers: () => ({}),
+      });
+
+      await model.doGenerate({
+        prompt: TEST_PROMPT,
+        providerOptions: {
+          'test-provider': {
+            textVerbosity: 'medium',
+            customOption: 'should-be-included',
+          },
+        },
+      });
+
+      const body = await server.calls[0].requestBodyJson;
+
+      expect(body.verbosity).toBe('medium');
+      expect(body.textVerbosity).toBeUndefined();
+      expect(body.customOption).toBe('should-be-included');
+    });
+
     it('should use json_schema & strict with responseFormat json when structuredOutputs are enabled', async () => {
       prepareJsonResponse({ content: '{"value":"Spark"}' });
 
@@ -2132,6 +2181,7 @@ describe('doStream', () => {
           "tools": undefined,
           "top_p": undefined,
           "user": undefined,
+          "verbosity": undefined,
         },
       }
     `);