{"id":44790708,"url":"https://github.com/aimeos/prisma","last_synced_at":"2026-02-16T11:01:53.753Z","repository":{"id":321452887,"uuid":"1084906506","full_name":"aimeos/prisma","owner":"aimeos","description":"Light-weight PHP package for integrating multi-media related Large Language Models (LLMs) using a unified interface","archived":false,"fork":false,"pushed_at":"2026-02-11T17:42:18.000Z","size":1264,"stargazers_count":61,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-11T22:05:23.438Z","etag":null,"topics":["api","llm","media","multimedia"],"latest_commit_sha":null,"homepage":"https://php-prisma.org","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aimeos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-28T10:25:24.000Z","updated_at":"2026-02-11T17:42:21.000Z","dependencies_parsed_at":"2025-10-29T19:31:20.759Z","dependency_job_id":"4e259b96-5123-4fd8-9abc-2ea98a6d5bec","html_url":"https://github.com/aimeos/prisma","commit_stats":null,"previous_names":["aimeos/prisma"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/aimeos/prisma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimeos%2Fprisma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimeos%2Fprisma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimeos%2Fprisma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimeos%2Fprisma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aimeos","download_url":"https://codeload.github.com/aimeos/prisma/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aimeos%2Fprisma/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29506318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T09:05:14.864Z","status":"ssl_error","status_checked_at":"2026-02-16T08:55:59.364Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","llm","media","multimedia"],"created_at":"2026-02-16T11:00:33.298Z","updated_at":"2026-02-16T11:01:53.748Z","avatar_url":"https://github.com/aimeos.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP Prisma\n\nLight-weight PHP package for integrating multi-media related Large Language Models (LLMs) into your applications using a unified interface.\n\n\u003cnav\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#supported-providers\"\u003eSupported providers\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#audio\"\u003eAudio\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#image\"\u003eImage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#video\"\u003eVideo\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#api-usage\"\u003eAPI usage\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#ensure\"\u003eensure\u003c/a\u003e\u003cspan\u003e: Ensures that the provider has implemented the method\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#has\"\u003ehas\u003c/a\u003e\u003cspan\u003e: Tests if the provider has implemented the method\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#model\"\u003emodel\u003c/a\u003e\u003cspan\u003e: Use the model passed by its name\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#withClientOptions\"\u003ewithClientOptions\u003c/a\u003e\u003cspan\u003e: Add options for the Guzzle HTTP client\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#withSystemPrompt\"\u003ewithSystemPrompt\u003c/a\u003e\u003cspan\u003e: Add a system prompt for the LLM\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#response-objects\"\u003eResponse objects\u003c/a\u003e\u003cspan\u003e: How data is returned by the API\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#audio-api\"\u003eAudio API\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#demix\"\u003edemix\u003c/a\u003e\u003cspan\u003e: Separate an audio file into its individual tracks\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#denoise\"\u003edenoise\u003c/a\u003e\u003cspan\u003e: Remove noise from an audio file\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#describe\"\u003edescribe\u003c/a\u003e\u003cspan\u003e: Describe the content of an audio file\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#revoice\"\u003erevoice\u003c/a\u003e\u003cspan\u003e: Exchange the voice in an audio file\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#speak\"\u003espeak\u003c/a\u003e\u003cspan\u003e: Convert text to speech in an audio file\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#transcribe\"\u003etranscribe\u003c/a\u003e\u003cspan\u003e: Converts speech of an audio file to text\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#image-api\"\u003eImage API\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#background\"\u003ebackground\u003c/a\u003e\u003cspan\u003e: Replace background according to the prompt\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#describe\"\u003edescribe\u003c/a\u003e\u003cspan\u003e: Describe the content of an image\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#detext\"\u003edetext\u003c/a\u003e\u003cspan\u003e: Remove all text from the image\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#erase\"\u003eerase\u003c/a\u003e\u003cspan\u003e: Erase parts of the image\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#imagine\"\u003eimagine\u003c/a\u003e\u003cspan\u003e: Generate an image from the prompt\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#inpaint\"\u003einpaint\u003c/a\u003e\u003cspan\u003e: Edit an image area according to a prompt\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#isolate\"\u003eisolate\u003c/a\u003e\u003cspan\u003e: Remove the image background\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#relocate\"\u003erelocate\u003c/a\u003e\u003cspan\u003e: Place the foreground object on a new background\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#repaint\"\u003erepaint\u003c/a\u003e\u003cspan\u003e: Repaint an image according to the prompt\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#uncrop\"\u003euncrop\u003c/a\u003e\u003cspan\u003e: Extend/outpaint the image\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#upscale\"\u003eupscale\u003c/a\u003e\u003cspan\u003e: Scale up the image\u003c/span\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#vectorize\"\u003evectorize\u003c/a\u003e\u003cspan\u003e: Creates embedding vectors from images\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#video-api\"\u003eVideo API\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#describe\"\u003edescribe\u003c/a\u003e\u003cspan\u003e: Describe the content of a video\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"method-header\"\u003e\u003ca href=\"#custom-providers\"\u003eCustom providers\u003c/a\u003e\u003c/div\u003e\n\u003cul class=\"method-list\"\u003e\n    \u003cli\u003e\u003ca href=\"#base-skeleton\"\u003eBase skeleton\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#requests\"\u003eRequests\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#responses\"\u003eResponses\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#examples\"\u003eExamples\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/nav\u003e\n\n## Supported providers\n\n- [AudioPod AI](https://audiopod.ai/)\n- [Bedrock Titan (AWS)](https://docs.aws.amazon.com/bedrock/latest/userguide/titan-models.html)\n- [Black Forest Labs](https://docs.bfl.ai/quick_start/introduction)\n- [Clipdrop](https://clipdrop.co/apis)\n- [Cohere](https://docs.cohere.com/docs/the-cohere-platform)\n- [Deepgram](https://deepgram.com/)\n- [ElevenLabs](https://elevenlabs.io/docs/overview/intro)\n- [Gemini (Google)](https://aistudio.google.com/models/gemini-2-5-flash-image)\n- [Groq](https://groq.com/)\n- [Ideogram](https://ideogram.ai/api)\n- [Mistral](https://docs.mistral.ai/api)\n- [Murf](https://murf.ai/api)\n- [OpenAI](https://openai.com/api/)\n- [RemoveBG](https://www.remove.bg/api)\n- [StabilityAI](https://platform.stability.ai/)\n- [VertexAI (Google)](https://cloud.google.com/vertex-ai/generative-ai/docs)\n- [VoyageAI](https://docs.voyageai.com/)\n\n### Audio\n\n|                       | demix | denoise | describe | revoice | speak | transcribe |\n| :---                  | :---: | :---:   | :---:    | :---:   | :---: | :---:      |\n| **AudioPod**          | yes   | yes     | -        | yes     | yes   | yes        |\n| **Deepgram**          | -     | -       | -        | -       | yes   | yes        |\n| **ElevenLabs**        | -     | -       | -        | yes     | yes   | yes        |\n| **Gemini**            | -     | -       | yes      | -       | -     | -          |\n| **Groq**              | -     | -       | yes      | -       | yes   | yes        |\n| **Mistral**           | -     | -       | yes      | -       | -     | yes        |\n| **Murf**              | -     | -       | -        | yes     | yes   | -          |\n| **OpenAI**            | -     | -       | yes      | -       | yes   | yes        |\n\n### Image\n\n|                       | background | describe | detext | erase | imagine | inpaint | isolate | recognize | relocate | repaint | uncrop | upscale | vectorize |\n| :---                  | :---:      | :---:    | :---:  | :---: | :---:   | :---:   | :---:   | :---:     | :---:    | :---:   | :---:  | :---:   | :---:     |\n| **Bedrock Titan**     | -          | -        | -      | -     | yes     | yes     | yes     | -         | -        | -       | -      | -       | yes       |\n| **Black Forest Labs** | -          | -        | -      | -     | beta    | beta    | -       | -         | -        | -       | beta   | -       | -         |\n| **Clipdrop**          | yes        | -        | yes    | yes   | yes     | -       | yes     | -         | -        | -       | yes    | yes     | -         |\n| **Cohere**            | -          | -        | -      | -     | -       | -       | -       | -         | -        | -       | -      | -       | yes       |\n| **Gemini**            | -          | yes      | -      | -     | yes     | -       | -       | -         | -        | yes     | -      | -       | -         |\n| **Groq**              | -          | yes      | -      | -     | -       | -       | -       | -         | -        | -       | -      | -       | -         |\n| **Ideogram**          | beta       | beta     | -      | -     | beta    | beta    | -       | -         | -        | beta    | -      | beta    | -         |\n| **Mistral**           | -          | -        | -      | -     | -       | -       | -       | yes       | -        | -       | -      | -       | -         |\n| **OpenAI**            | -          | yes      | -      | -     | yes     | yes     | -       | -         | -        | -       | -      | -       | -         |\n| **RemoveBG**          | -          | -        | -      | -     | -       | -       | yes     | -         | yes      | -       | -      | -       | -         |\n| **StabilityAI**       | -          | -        | -      | yes   | yes     | yes     | yes     | -         | -        | -       | yes    | yes     | -         |\n| **VertexAI**          | -          | -        | -      | -     | yes     | yes     | -       | -         | -        | -       | -      | yes     | yes       |\n| **VoyageAI**          | -          | -        | -      | -     | -       | -       | -       | -         | -        | -       | -      | -       | yes       |\n\n### Video\n\n|                       | describe |\n| :---                  | :---:    |\n| **Gemini**            | yes      |\n\n## Installation\n\n```\ncomposer req aimeos/prisma\n```\n\n## API usage\n\nBasic usage:\n\n```php\nuse Aimeos\\Prisma\\Prisma;\n\n$image = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003emodel( '\u003cmodelname\u003e' ) // if model can be selected\n    -\u003eensure( 'imagine' ) // make sure interface is implemented\n    -\u003eimagine( 'a grumpy cat' )\n    -\u003ebinary();\n```\n\n### ensure\n\nEnsures that the provider has implemented the method.\n\n```php\npublic function ensure( string $method ) : self\n```\n\n* @param **string** `$method` Method name\n* @return **Provider**\n* @throws \\Aimeos\\Prisma\\Exceptions\\NotImplementedException\n\n**Example:**\n\n```php\n\\Aimeos\\Prisma\\Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003eensure( 'imagine' );\n```\n\n### has\n\nTests if the provider has implemented the method.\n\n```php\npublic function has( string $method ) : bool\n```\n\n* @param **string** `$method` Method name\n* @return **bool** TRUE if implemented, FALSE if absent\n\n**Example:**\n\n```php\n\\Aimeos\\Prisma\\Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003ehas( 'imagine' );\n```\n\n### model\n\nUse the model passed by its name.\n\nUsed if the provider supports more than one model and allows to select\nbetween the different models. Otherwise, it's ignored.\n\n```php\npublic function model( ?string $model ) : self\n```\n\n* @param **string\u0026#124;null** `$model` Model name\n* @return **self** Provider interface\n\n**Example:**\n\n```php\n\\Aimeos\\Prisma\\Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003emodel( 'dall-e-3' );\n```\n\n### withClientOptions\n\nAdd options for the Guzzle HTTP client.\n\n```php\npublic function withClientOptions( array `$options` ) : self\n```\n\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Associative list of name/value pairs\n* @return **self** Provider interface\n\n**Example:**\n\n```php\n\\Aimeos\\Prisma\\Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003ewithClientOptions( ['timeout' =\u003e 120] );\n```\n\n### withSystemPrompt\n\nAdd a system prompt for the LLM.\n\nIt may be used by providers supporting system prompts. Otherwise, it's\nignored.\n\n```php\npublic function withSystemPrompt( ?string $prompt ) : self\n```\n\n* @param **string\u0026#124;null** `$prompt` System prompt\n* @return **self** Provider interface\n\n**Example:**\n\n```php\n\\Aimeos\\Prisma\\Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003ewithSystemPrompt( 'You are a professional illustrator' );\n```\n\n### Response objects\n\nThe methods return a *FileResponse*, *TextResponse* or *VectorResponse* object that\ncontains the returned data with optional meta/usage/description information.\n\n**FileResponse** objects:\n\n```php\n$base64 = $response-\u003ebase64(); // first base64 data, from binary, base64 and URL, waits for async requests\n$file = $response-\u003ebinary(); // first binary data, from binary, base64 and URL, waits for async requests\n$url = $response-\u003eurl(); // first URL, only if URLs are returned, otherwise NULL\n$mime = $response-\u003emimetype(); // image mime type, waits for async requests\n$text = $response-\u003edescription(); // image description if returned by provider\n$bool = $response-\u003eready(); // FALSE for async APIs until file is available\n$file = $response-\u003efirst(); // first available file object\n$array = $response-\u003efiles(); // all available file objects\n\n// loop over all available files\nforeach( $response as $name =\u003e $file ) {\n    $file-\u003ebinary()\n}\n```\n\nURLs are automatically converted to binary and base64 data if requested and conversion between\nbinary and base64 data is done on request too.\n\n**TextResponse** objects:\n\n```php\n$text = $response-\u003etext(); // first text content (non-streaming)\n$text = $response-\u003efirst(); // first available text\n$texts = $response-\u003etexts(); // all texts (non-streaming)\n\n// loop over all available texts\nforeach( $response as $text ) {\n    echo $text;\n}\n```\n\n**VectorResponse** objects:\n\n```php\n$vector = $response-\u003efirst(); // first embedding vector if only one file has been passed\n$vectors = $response-\u003evectors(); // embedding vectors for the passed files in the same order\n\n// loop over all available vectors\nforeach( $response as $vector ) {\n    print_r( $vector );\n}\n```\n\nIncluded **meta data** (optional):\n\n```php\n$meta = $response-\u003emeta();\n```\n\nIt returns an associative array whose content totally depends on the provider.\n\nIncluded **usage data** (optional):\n\n```php\n$usage = $response-\u003eusage();\n```\n\nIt returns an associative array whose content depends on the provider. If the provider returns\nusage information, the `used` array key is available and contains a number. What the number\nrepresents depdends on the provider too.\n\n## Audio API\n\n### demix\n\nSeparate an audio file into its individual tracks.\n\n```php\npublic function demix( Audio $audio, int $stems, array $options = [] ) : FileResponse\n```\n\n* @param **Audio** `$audio` Input audio object\n* @param **int** `$stems` Number of stems to separate into (e.g. 2 for vocals and accompaniment)\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Audio file response\n\n**Supported options:**\n\n* AudioPod\n\n### denoise\n\nRemove noise from an audio file.\n\n```php\npublic function denoise( Audio $audio, array $options = [] ) : FileResponse\n```\n\n* @param **Audio** `$audio` Input audio object\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Audio file response\n\n**Supported options:**\n\n* [AudioPod](https://docs.audiopod.ai/api-reference/noise-reduction)\n\n### describe\n\nDescribe the content of an audio file.\n\n```php\npublic function describe( Audio $audio, ?string $lang = null, array $options = [] ) : TextResponse\n```\n\n* @param **Audio** `$audio` Input audio object\n* @param **string\u0026#124;null** `$lang` ISO language code the description should be generated in\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **TextResponse** Response text\n\n**Supported options:**\n\n* Gemini\n* Groq\n* [OpenAI](https://platform.openai.com/docs/api-reference/audio/createTranscription)\n\n### revoice\n\nExchange the voice in an audio file.\n\n```php\npublic function revoice( Audio $audio, string $voice, array $options = [] ) : FileResponse;\n```\n\n* @param **Audio** `$audio` Input audio object\n* @param **string** `$voice` Voice name or identifier\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Audio file response\n\n**Supported options:**\n\n* AudioPod\n* [ElevenLabs](https://elevenlabs.io/docs/api-reference/speech-to-speech/convert)\n* [Murf](https://murf.ai/api/docs/api-reference/voice-changer/convert)\n\n### speak\n\nConverts text to speech.\n\n```php\npublic function speak( string $text, string $voice = , array $options = [] ) : FileResponse;\n```\n\n* @param **string** `$text` Text to be converted to speech\n* @param **string\u0026#124;null** `$voice` Voice identifier for speech synthesis\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Audio file response\n\n**Supported options:**\n\n* [AudioPod](https://docs.audiopod.ai/api-reference/text-to-speech#generate-speech)\n* [Deepgram](https://developers.deepgram.com/reference/text-to-speech/speak-request)\n* [ElevenLabs](https://elevenlabs.io/docs/api-reference/text-to-speech/convert)\n* Groq\n* [Murf](https://murf.ai/api/docs/api-reference/text-to-speech/generate)\n* [OpenAI](https://platform.openai.com/docs/api-reference/audio/createSpeech)\n\n### transcribe\n\nConverts speech to text.\n\n```php\npublic function transcribe( Audio $audio, ?string $lang = null, array $options = [] ) : TextResponse\n```\n\n* @param **Audio** `$audio` Input audio object\n* @param **string\u0026#124;null** `$lang` ISO language code of the audio content\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **TextResponse** Transcription text response\n\n**Supported options:**\n\n* [AudioPod](https://docs.audiopod.ai/api-reference/speech-to-text)\n* [Deepgram](https://developers.deepgram.com/reference/text-to-speech/speak-request)\n* [ElevenLabs](https://elevenlabs.io/docs/api-reference/speech-to-text/convert)\n* Groq\n* [Mistral](https://docs.mistral.ai/api/endpoint/audio/transcriptions)\n* [OpenAI](https://platform.openai.com/docs/api-reference/audio/createTranscription)\n\n## Image API\n\nMost methods require an image object as input which contains a reference to the image that\nshould be processed. This object can be created by:\n\n```php\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.php', 'image/png' );\n$image = Image::fromLocalPath( 'path/to/image.png', 'image/png' );\n$image = Image::fromBinary( 'PNG...', 'image/png' );\n$image = Image::fromBase64( 'UE5H...', 'image/png' );\n\n// Laravel only:\n$image = Image::fromStoragePath( 'path/to/image.png', 'public', 'image/png' );\n```\n\nThe last parameter of all methods (mime type) is optional. If it's not passed, the file\ncontent will be retrieved to determine the mime type if reqested.\n\n**Note:** It's best to use **fromUrl()** if possible because all other formats (binary and\nbase64) can be derived from the URL content but URLs can't be created from binary/base64\ndata.\n\n### background\n\nReplace image background with a background described by the prompt.\n\n```php\npublic function background( Image $image, string $prompt, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **string** `$prompt` Prompt describing the new background\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* Clipdrop\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/replace-background-v3#request)\n* [VertexAI](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-product-recontext-api#parameters)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003ebackground( $image, 'Golden sunset on a caribbean beach' );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### describe\n\nDescribe the content of an image.\n\n```php\npublic function describe( Image $image, ?string $lang = null, array $options = [] ) : TextResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **string\u0026#124;null** `$lang` ISO language code the description should be generated in\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **TextResponse** Response text\n\n**Supported options:**\n\n* Gemini\n* Groq\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/describe#request)\n* OpenAI\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$textResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003edescribe( $image, 'de' );\n\n$text = $textResponse-\u003etext();\n```\n\n### detext\n\nRemove all text from the image.\n\n```php\npublic function detext( Image $image, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* Clipdrop\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003edetext( `$image` );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### erase\n\nErase parts of the image.\n\n```php\npublic function erase( Image $image, Image $mask, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **Image** `$mask` Mask image object\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\nThe mask must be an image with black parts (#000000) to keep and white parts (#FFFFFF)\nto remove.\n\n**Supported options:**\n\n* [Clipdrop](https://clipdrop.co/apis/docs/cleanup)\n* [StabilityAI](https://platform.stability.ai/docs/api-reference#tag/Edit/paths/~1v2beta~1stable-image~1edit~1erase/post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n$mask = Image::fromBinary( 'PNG...' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003eerase( $image, $mask );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### imagine\n\nGenerate an image from the prompt.\n\n```php\npublic function imagine( string $prompt, array $images = [], array $options = [] ) : FileResponse\n```\n\n* @param **string** `$prompt` Prompt describing the image\n* @param **array\u0026#60;int, \\Aimeos\\Prisma\\Files\\Image\u0026#62;** `$images` Associative list of file name/Image instances\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* [Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html)\n* [Black Forest Labs](https://docs.bfl.ai/api-reference/models/generate-or-edit-an-image-with-flux2-[pro])\n* Clipdrop\n* [Gemini](https://ai.google.dev/gemini-api/docs/image-generation#optional_configurations)\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/generate-v3#request)\n* [VertexAI](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#generate_images)\n* [OpenAI GPT image 1](https://platform.openai.com/docs/guides/image-generation?image-generation-model=gpt-image-1#customize-image-output)\n* [OpenAI Dall-e-3](https://platform.openai.com/docs/guides/image-generation?image-generation-model=dall-e-3#customize-image-output)\n* [OpenAI Dall-e-2](https://platform.openai.com/docs/guides/image-generation?image-generation-model=dall-e-2#customize-image-output)\n* [StabilityAI Core](https://platform.stability.ai/docs/api-reference#tag/Generate/paths/~1v2beta~1stable-image~1generate~1core/post)\n* [StabilityAI Ultra](https://platform.stability.ai/docs/api-reference#tag/Generate/paths/~1v2beta~1stable-image~1generate~1ultra/post)\n* [StabilityAI Stable Diffusion 3.5](https://platform.stability.ai/docs/api-reference#tag/Generate/paths/~1v2beta~1stable-image~1generate~1sd3/post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003eimagine( 'Futuristic robot looking at a dashboard' );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### inpaint\n\nEdit an image by inpainting an area defined by a mask according to a prompt.\n\n```php\npublic function inpaint( Image $image, Image $mask, string $prompt, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **Image** `$mask` Input mask image object\n* @param **string** `$prompt` Prompt describing the changes\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\nThe mask must be an image with black parts (#000000) to keep and white parts (#FFFFFF)\nto edit.\n\n**Supported options:**\n\n* [Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html)\n* [Black Forest Labs](https://docs.bfl.ai/api-reference/models/generate-an-image-with-flux1-fill-[pro]-using-an-input-image-and-mask)\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/edit-v3#request)\n* [VertexAI](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api-edit#parameters)\n* [OpenAI GPT image 1](https://platform.openai.com/docs/guides/image-generation?image-generation-model=gpt-image-1#customize-image-output)\n* [OpenAI Dall-e-3](https://platform.openai.com/docs/guides/image-generation?image-generation-model=dall-e-3#customize-image-output)\n* [OpenAI Dall-e-2](https://platform.openai.com/docs/guides/image-generation?image-generation-model=dall-e-2#customize-image-output)\n* [StabilityAI](https://platform.stability.ai/docs/api-reference#tag/Edit/paths/~1v2beta~1stable-image~1edit~1inpaint/post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n$mask = Image::fromBinary( 'PNG...' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003einpaint( $image, $mask, 'add a pink flamingo' );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### isolate\n\nRemove the image background.\n\n```php\npublic function isolate( Image $image, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* [Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-titan-image.html)\n* [Clipdrop](https://clipdrop.co/apis/docs/remove-background)\n* [RemoveBG](https://www.remove.bg/api#api-reference)\n* [StabilityAI](https://platform.stability.ai/docs/api-reference#tag/Edit/paths/~1v2beta~1stable-image~1edit~1remove-background/post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003eisolate( `$image` );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### recognize\n\nRecognizes the text in the given image (OCR).\n\n```php\npublic function recognize( Image $image, array $options = [] ) : TextResponse;\n```\n\n* @param **Image** `$image` Input image object\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **TextResponse** Response text object\n\n**Supported options:**\n\n* [Mistral](https://docs.mistral.ai/api/endpoint/ocr#operation-ocr_v1_ocr_post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$textTesponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003erecognize( `$image` );\n\n$text = $textResponse-\u003etext();\n```\n\n### relocate\n\nPlace the foreground object on a new background.\n\n```php\npublic function relocate( Image $image, Image $bgimage, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image with foreground object\n* @param **Image** `$bgimage` Background image\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* [RemoveBG](https://www.remove.bg/api#api-reference)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n$bgimage = Image::fromUrl( 'https://example.com/background.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003erelocate( $image, $bgimage );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### repaint\n\nRepaint an image according to the prompt.\n\n```php\npublic function repaint( Image $image, string $prompt, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **string** `$prompt` Prompt describing the changes\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* [Gemini](https://ai.google.dev/gemini-api/docs/image-generation#optional_configurations)\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/remix-v3#request)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003erepaint( $image, 'Use a van Goch style' );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### uncrop\n\nExtend/outpaint the image.\n\n```php\npublic function uncrop( Image $image,  int $top, int $right, int $bottom, int $left, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **int** `$top` Number of pixels to extend to the top\n* @param **int** `$right` Number of pixels to extend to the right\n* @param **int** `$bottom` Number of pixels to extend to the bottom\n* @param **int** `$left` Number of pixels to extend to the left\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* [Black Forest Labs](https://docs.bfl.ai/api-reference/models/expand-an-image-by-adding-pixels-on-any-side)\n* Clipdrop\n* [StabilityAI](https://platform.stability.ai/docs/api-reference#tag/Edit/paths/~1v2beta~1stable-image~1edit~1outpaint/post)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003euncrop( $image, 100, 200, 0, 50 );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### upscale\n\nScale up the image.\n\n```php\npublic function upscale( Image $image, int $factor, array $options = [] ) : FileResponse\n```\n\n* @param **Image** `$image` Input image object\n* @param **int** `$factor` Upscaling factor between 2 and the maximum value supported by the provider\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **FileResponse** Response file\n\n**Supported options:**\n\n* Clipdrop\n* [Ideogram](https://developer.ideogram.ai/api-reference/api-reference/upscale#request)\n* [VertexAI](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-upscale-api#parameters)\n* [StabilityAI](https://platform.stability.ai/docs/api-reference#tag/Upscale)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$image = Image::fromUrl( 'https://example.com/image.png' );\n\n$fileResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003eupscale( $image, 4 );\n\n$image = $fileResponse-\u003ebinary();\n```\n\n### vectorize\n\nCreates embedding vectors of the images' content.\n\n```php\npublic function vectorize( array $images, ?int $size = null, array $options = [] ) : VectorResponse\n```\n\n* @param **array\u0026#60;int, \\Aimeos\\Prisma\\Files\\Image\u0026#62;** `$images` List of input image objects\n* @param **int\u0026#124;null** `$size` Size of the resulting vector or null for provider default\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **VectorResponse** Response vector object\n\n**Supported options:**\n\n* Bedrock\n* [Cohere](https://docs.cohere.com/reference/embed#request)\n* VertexAI\n* [VoyageAI](https://docs.voyageai.com/reference/multimodal-embeddings-api)\n\n**Example:**\n\n```php\nuse Aimeos\\Prisma\\Prisma;\nuse \\Aimeos\\Prisma\\Files\\Image;\n\n$images = [\n    Image::fromUrl( 'https://example.com/image.png' ),\n    Image::fromUrl( 'https://example.com/image2.png' ),\n];\n\n$vectorResponse = Prisma::image()\n    -\u003eusing( '\u003cprovider\u003e', ['api_key' =\u003e 'xxx'])\n    -\u003evectorize( $images, 512 );\n\n$vectors = $vectorResponse-\u003evectors();\n```\n\n## Video API\n\n### describe\n\nDescribe the content of a video file.\n\n```php\npublic function describe( Video $video, ?string $lang = null, array $options = [] ) : TextResponse\n```\n\n* @param **Video** `$video` Input video object\n* @param **string\u0026#124;null** `$lang` ISO language code the description should be generated in\n* @param **array\u0026#60;string, mixed\u0026#62;** `$options` Provider specific options\n* @return **TextResponse** Response text\n\n**Supported options:**\n\n* Gemini\n\n## Custom providers\n\n### Base skeleton\n\n```php\n\u003c?php\n\n// for Audio providers\nnamespace Aimeos\\Prisma\\Providers\\Audio;\n// for Image providers\nnamespace Aimeos\\Prisma\\Providers\\Image;\n// for Video providers\nnamespace Aimeos\\Prisma\\Providers\\Video;\n\nuse Aimeos\\Prisma\\Exceptions\\PrismaException;\nuse Aimeos\\Prisma\\Providers\\Base;\n\n\nclass Myprovider extends Base implements ...\n{\n    public function __construct( array $config )\n    {\n        if( !isset( $config['api_key'] ) ) {\n            throw new PrismaException( sprintf( 'No API key' ) );\n        }\n\n        // if authentication is done via headers\n        $this-\u003eheader( '\u003capi key name\u003e', $config['api_key'] );\n        // base url for all requests (no paths)\n        $this-\u003ebaseUrl( '\u003cprovider URL\u003e' );\n    }\n```\n\nDepending on the provider type (Audio, Image or Video), you can implement one or\nmore of the available interfaces for that provider type:\n\n- [Audio](https://github.com/aimeos/prisma/tree/master/src/Contracts/Audio)\n- [Image](https://github.com/aimeos/prisma/tree/master/src/Contracts/Image)\n- [Video](https://github.com/aimeos/prisma/tree/master/src/Contracts/Video)\n\nFor example:\n\n```php\nnamespace Aimeos\\Prisma\\Providers\\Image;\n\nuse Aimeos\\Prisma\\Contracts\\Image\\Describe;\nuse Aimeos\\Prisma\\Exceptions\\PrismaException;\nuse Aimeos\\Prisma\\Files\\Image;\nuse Aimeos\\Prisma\\Providers\\Base;\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\n\nclass Myprovider extends Base implements Describe\n{\n    public function describe( Image $image, ?string $lang = null, array $options = [] ) : TextResponse\n    {\n        // ...\n    }\n}\n```\n\n### Requests\n\nThere are a few support methods available to simplify building requests which\nare sent by the Guzzle client to the server of the AI provider.\n\nFirst, you should validate and limit the passed options to the ones supported\nby the AI API. The *allow()* and *sanitze()* methods filter out unsupported\nvalues because different APIs have different parameters but users of the\nPrisma API should be able to pass parameters for several AI providers at once.\nTherefore, get only supported parameters and values using:\n\n```php\n// filter key/value pairs in $options and use the ones allowed by the API\n$allowed = $this-\u003eallow( $options, ['\u003ckey1\u003e', '\u003ckey2\u003e', /* ... */] );\n\n// filter values to pass only allowed option values (optional)\n$allowed = $this-\u003esanitize( $allowed, ['\u003ckey1\u003e' =\u003e ['\u003cval1\u003e', '\u003cval2\u003e', '\u003cval3\u003e']])\n```\n\nIf the user can choose between several LLM models when using the API, the\n*modelName()* method will return the users choice or the passed default value:\n\n```php\n$model = $this-\u003emodelName( 'gemini-2.5-flash' );\n```\n\nTo build the request in the correct format (form key/value pairs, multipart or\nJSON data), the *request()* method transforms parameters and files for form and\nmultipart requests. JSON data is specific to the API and you must create it\nyourself:\n\n```php\n// Form data request\n$data = $this-\u003erequest( params );\n// Multipart request\n$data = ['multipart' =\u003e $this-\u003erequest( params, ['image_key' = $image-\u003ebinary()] )];\n// JSON request\n$data = ['json' =\u003e ['image_key' = array_map( fn( $image ) =\u003e $image-\u003ebase64()] + params];\n```\n\nThen, you can send the request using the Guzzle client, validate the response\nand get the returned content:\n\n```php\n// use Guzzle to send the request and get the response from the server\n$response = $this-\u003eclient()-\u003epost( 'relative/api/path', $data );\n\n// validates HTTP status codes, overwrite if needed\n$this-\u003evalidate( $response );\n\n// get binary content or JSON content\n$content = $response-\u003egetBody()-\u003egetContents();\n```\n\nA full example would be:\n\n```php\nuse Aimeos\\Prisma\\Files\\Image;\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\npublic function describe( Image $image, ?string $lang = null, array $options = [] ) : TextResponse\n{\n    $model = $this-\u003emodelName( 'flash' );\n    $allowed = $this-\u003eallow( $options, ['version'] );\n\n    $params = ['language' =\u003e $lang] + $allowed;\n    $data = ['multipart' =\u003e $this-\u003erequest( params, ['file' = $image-\u003ebinary()] )];\n    $response = $this-\u003eclient()-\u003epost( 'relative/api/path', $data );\n\n    $this-\u003evalidate( $response );\n\n    $content = $response-\u003egetBody()-\u003egetContents();\n    // return a response\n}\n```\n\n### Responses\n\nThere are several response types available, which can be returned depending on\nthe implemented interfaces:\n\n* FileResponse\n* TextResponse\n* VectorResponse\n\n#### File response\n\nA FileResponse can contain one or more files, either as binary or base64 data,\nor as remote URL. Passing the mime type is optional but prevents guessing the\nfile type later:\n\n```php\nuse Aimeos\\Prisma\\Responses\\FileResponse;\n\n$response = FileResponse::fromBinary( '...', 'image/png' );\n$response = FileResponse::fromBase64( '...', 'image/png' );\n$response = FileResponse::fromUrl( '...', 'image/png' );\n```\n\nYou can also add more than one file by using the *add()* method:\n\n```php\nuse Aimeos\\Prisma\\Files\\File;\n\n$response-\u003eadd( File::fromBinary( '...', 'image/png' ) );\n```\n\nIf the API processes requests asynchronously, the *fromAsync()* method accepts\na closure function and the optional timeout between requests as second parameter:\n\n```php\n$client = $this-\u003eclient();\n$response = FileResponse::fromAsync( function( FileResponse $fr ) uses ( $client ) {\n    // download or add file(s) to file response object\n    $fr-\u003eadd( File::fromUrl( '...', 'image/png' ) );\n}, 3 );\n```\n\n#### Text response\n\nThe TextResponse can contain one or more texts and is created by using:\n\n```php\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\n$response = TextResponse::fromText( '...' );\n$response-\u003eadd( '...' ); // add more texts\n```\n\nTextResponse objects also support *fromAsync()* for asynchronous APIs using a\nclosure function and the optional timeout between requests as second parameter:\n\n```php\n$client = $this-\u003eclient();\n$response = TextResponse::fromAsync( function( FileResponse $fr ) uses ( $client ) {\n    // download and add texts to text response object\n    $fr-\u003eadd( '...' );\n}, 3 );\n```\n\n#### Vector response\n\nThe *vectorize()* method returns a *VectorResponse* object which contains the\nvector of float numbers representing the input:\n\n```php\nuse Aimeos\\Prisma\\Responses\\VectorResponse;\n\n$response = VectorResponse::fromVectors( [\n    [0.27629, 0.89271, 0.98265, /* ... */],\n    /* ... */\n] );\n```\n\n#### Meta data\n\nAll response objects support adding usage information and meta data if they are\nreturned by the provider API. Use the *withUsage() and *withMeta()* methods to\npass that information as part of the response object:\n\n```php\n$response-\u003ewithUsage( // optional\n    100, // used tokens, credits, etc. if available or NULL\n    [] // arbitrary key/value pairs for the rest of the usage information\n);\n$response-\u003ewithMeta( // optional\n    [] // arbitrary meta data as key/value pairs, can be nested\n);\n```\n\nTextResponse objects can store structured data e.g. returned when audio files\nare transcribed:\n\n```php\n$response-\u003ewithStructured( [\n    // for transcriptions\n    ['start' =\u003e 0.0, 'end' =\u003e 1.0, 'text' =\u003e 'This is a test.'],\n    // ...\n] );\n```\n\nTranscriptions must always contain the keys *start* and *end* in seconds as well\nas *text* for the content in each entry (but there can be more key/value pairs\nif available).\n\nThe FileResponse object also supports *withDescription()* to attach the file\ndescription as string to the response object:\n\n```php\n$response-\u003ewithDescription( '...' );\n```\n\n### Examples\n\n#### Audio provider\n\n```php\n\u003c?php\n\nnamespace Aimeos\\Prisma\\Providers\\Audio;\n\nuse Aimeos\\Prisma\\Contracts\\Audio\\Describe;\nuse Aimeos\\Prisma\\Exceptions\\PrismaException;\nuse Aimeos\\Prisma\\Files\\Audio;\nuse Aimeos\\Prisma\\Providers\\Base;\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\n\nclass Myprovider extends Base implements Describe\n{\n    public function __construct( array $config )\n    {\n        if( !isset( $config['api_key'] ) ) {\n            throw new PrismaException( sprintf( 'No API key' ) );\n        }\n\n        $this-\u003eheader( 'x-api-key', $config['api_key'] );\n        $this-\u003ebaseUrl( 'https://ai.com' );\n    }\n\n\n    public function describe( Audio $audio, ?string $lang = null, array $options = [] ) : TextResponse\n    {\n        $allowed = $this-\u003eallow( $options, ['version'] );\n        $model = $this-\u003emodelName( 'flash' );\n\n        $params = ['language' =\u003e $lang, 'model' =\u003e model] + $allowed;\n        $data = ['multipart' =\u003e $this-\u003erequest( params, ['file' = $audio-\u003ebinary()] )];\n        $response = $this-\u003eclient()-\u003epost( 'relative/api/path', $data );\n\n        $this-\u003evalidate( $response );\n\n        $data = $this-\u003efromJson( $response );\n\n        return TextResponse::fromText( @$data['text'] )\n            -\u003ewithStructured( // optional\n                $data['segments'] ?? []\n            )\n            -\u003ewithUsage( // optional\n                @$data['usage']['total'],\n                $data['usage'] ?? []\n            )\n            -\u003ewithMeta( // optional\n                $data['meta'] ?? []\n            );\n    }\n}\n```\n\n### Image provider\n\n```php\n\u003c?php\n\nnamespace Aimeos\\Prisma\\Providers\\Image;\n\nuse Aimeos\\Prisma\\Contracts\\Image\\Describe;\nuse Aimeos\\Prisma\\Exceptions\\PrismaException;\nuse Aimeos\\Prisma\\Files\\Image;\nuse Aimeos\\Prisma\\Providers\\Base;\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\n\nclass Myprovider extends Base implements Describe\n{\n    public function __construct( array $config )\n    {\n        if( !isset( $config['api_key'] ) ) {\n            throw new PrismaException( sprintf( 'No API key' ) );\n        }\n\n        $this-\u003eheader( 'x-api-key', $config['api_key'] );\n        $this-\u003ebaseUrl( 'https://ai.com' );\n    }\n\n\n    public function describe( Image $audio, ?string $lang = null, array $options = [] ) : TextResponse\n    {\n        $allowed = $this-\u003eallow( $options, ['version'] );\n        $model = $this-\u003emodelName( 'flash' );\n\n        $params = ['language' =\u003e $lang, 'model' =\u003e model] + $allowed;\n        $data = ['multipart' =\u003e $this-\u003erequest( params, ['file' = $audio-\u003ebinary()] )];\n        $response = $this-\u003eclient()-\u003epost( 'relative/api/path', $data );\n\n        $this-\u003evalidate( $response );\n\n        $data = $this-\u003efromJson( $response );\n\n        return TextResponse::fromText( @$data['text'] )\n            -\u003ewithStructured( // optional\n                $data['segments'] ?? []\n            )\n            -\u003ewithUsage( // optional\n                @$data['usage']['total'],\n                $data['usage'] ?? []\n            )\n            -\u003ewithMeta( // optional\n                $data['meta'] ?? []\n            );\n    }\n}\n```\n\n### Video provider\n\n```php\n\u003c?php\n\nnamespace Aimeos\\Prisma\\Providers\\Video;\n\nuse Aimeos\\Prisma\\Contracts\\Video\\Describe;\nuse Aimeos\\Prisma\\Exceptions\\PrismaException;\nuse Aimeos\\Prisma\\Files\\Video;\nuse Aimeos\\Prisma\\Providers\\Base;\nuse Aimeos\\Prisma\\Responses\\TextResponse;\n\n\nclass Myprovider extends Base implements Describe\n{\n    public function __construct( array $config )\n    {\n        if( !isset( $config['api_key'] ) ) {\n            throw new PrismaException( sprintf( 'No API key' ) );\n        }\n\n        $this-\u003eheader( 'x-api-key', $config['api_key'] );\n        $this-\u003ebaseUrl( 'https://ai.com' );\n    }\n\n\n    public function describe( Video $video, ?string $lang = null, array $options = [] ) : TextResponse\n    {\n        $allowed = $this-\u003eallow( $options, ['version'] );\n        $model = $this-\u003emodelName( 'flash' );\n\n        $params = ['language' =\u003e $lang, 'model' =\u003e model] + $allowed;\n        $data = ['multipart' =\u003e $this-\u003erequest( params, ['file' = $video-\u003ebinary()] )];\n        $response = $this-\u003eclient()-\u003epost( 'relative/api/path', $data );\n\n        $this-\u003evalidate( $response );\n\n        $data = $this-\u003efromJson( $response );\n\n        return TextResponse::fromText( @$data['text'] )\n            -\u003ewithStructured( // optional\n                $data['segments'] ?? []\n            )\n            -\u003ewithUsage( // optional\n                @$data['usage']['total'],\n                $data['usage'] ?? []\n            )\n            -\u003ewithMeta( // optional\n                $data['meta'] ?? []\n            );\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimeos%2Fprisma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faimeos%2Fprisma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faimeos%2Fprisma/lists"}