Skip to content

Conversation

@antoninmasek
Copy link
Contributor

Description

This PR is an exploration of a new approach to handling provider-specific options through a ProviderOption value object. For now, I've implemented it just for OpenAI's Text handler as a proof of concept to see whether there would be interest in this approach before extending it to other providers.

Motivation

I'm working on a project where I need to set OpenAI's store parameter to false. Since this isn't currently supported, I created #766. Today I discovered I also need the include option, which isn't available yet either.

This made me think whether there could be a way to make this a bit more open for developers.

Additions

To accomplish this, I've introduced a new value object, ProviderOption, which is just a simple wrapper where you can specify the key, value, and optionally a provider.

Changes

The main change is in the HasProviderOptions.php trait, where $providerOptions now stores <int, ProviderOption> instead of <string, mixed>.

The main change in behavior is that developers would be able to supply provider options even without them being explicitly supported by Prism. Though, if the guarding is by design, I can still imagine a version where, for example, the ProviderOption would have a force parameter, and the developer would have to set it to true when not explicitly supported.

I think it could save a lot of time when you stumble upon an unsupported custom option and you just need to use it to move forward.

Examples

Below are a couple of examples of what this approach would enable.

Ensuring options are used only for a specified provider

Prism::text()
    ->using(Provider::OpenAI, 'gpt-4o')
    ->withPrompt('Who are you?')
    ->withProviderOptions([
        new \Prism\Prism\ValueObjects\ProviderOption(
            'cacheType', 
            'ephemeral',
            Provider::Anthropic,
        ), 
    ])
    ->asText();

In this example, since OpenAI is used as the provider, the cacheType option is automatically skipped.

Reusing options

In case you find yourself repeating options, or you have some custom logic to determine the value, you can extend the ProviderOption.

class AnthropicCacheType extends ProviderOption
{
    public function __construct(string $value)
    {
        // Your logic...

        parent::__construct('cacheType', $value, Provider::Anthropic);
    }
}

Prism::text()
    ->using(Provider::Anthropic, 'claude-opus-4-5')
    ->withPrompt('Who are you?')
    ->withProviderOptions([
        new AnthropicCacheType('ephemeral'),
    ])
    ->asText();

Current syntax

Or you can use the same syntax as you're used to. This is equivalent to using ProviderOption where provider is set to null.

Prism::text()
    ->using(Provider::OpenAI, 'gpt-4o')
    ->withPrompt('Who are you?')
    ->withProviderOptions([ 
      'strict' => true, 
    ])
    ->asText();

In closing

For demonstration purposes, I've changed only the Text handler for OpenAI. I would have to go through the rest if we decide to follow through. Also, the current implementation does not take into account the force parameter suggestion. For now, it assumes we'd let developers fully control the custom options.

Breaking Changes

The public interface remains the same, so there should be no breaking changes, but I would have to look into this a bit more should we decide to follow through.

@sixlive
Copy link
Contributor

sixlive commented Dec 6, 2025

Ohhhh this is interesting, let me sit with this for a minute

@antoninmasek
Copy link
Contributor Author

Sure thing 😎

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants