Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/Exceptions/ContentBlocksException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace NeuronAI\Exceptions;

class ContentBlocksException extends NeuronException
{
}
72 changes: 72 additions & 0 deletions src/Providers/OpenAI/OpenAITranscribeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace NeuronAI\Providers\OpenAI;

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use NeuronAI\Exceptions\ProviderException;
use NeuronAI\Transcribe\TranscribeProviderInterface;

class OpenAITranscribeProvider implements TranscribeProviderInterface
{
protected Client $client;

protected string $baseUri = 'https://api.openai.com/v1/audio/transcriptions';

public function __construct(
protected string $key,
protected string $model,
protected string $language = 'en',
) {
$this->client = new Client([
'base_uri' => $this->baseUri,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->key,
]
]);
}

public function trascribe(string $filePath): string
{
// Preparar los datos del formulario
$multipart = [
[
'name' => 'file',
'contents' => fopen($filePath, 'r'),
'filename' => basename($filePath)
],
[
'name' => 'model',
'contents' => $this->model
],
[
'name' => 'language',
'contents' => $this->language
],
[
'name' => 'response_format',
'contents' => 'json'
]
];
$response = $this->client->post('', [
'multipart' => $multipart,
RequestOptions::TIMEOUT => 60,
RequestOptions::CONNECT_TIMEOUT => 30
]);

// Procesar la respuesta
$statusCode = $response->getStatusCode();
$body = $response->getBody()->getContents();
$result = json_decode($body, true);

if ($statusCode !== 200) {
throw new ProviderException('Whisper API error: ' . $body);
}

return $result['text'] ?? '';
}
}
23 changes: 23 additions & 0 deletions src/Transcribe/ResolveTranscribeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace NeuronAI\Transcribe;

trait ResolveTranscribeProvider
{
protected TranscribeProviderInterface $transcribeProvider;

protected function transcribe(): TranscribeProviderInterface
{
return $this->transcribeProvider;
}

public function resolveTranscribeProvider(): TranscribeProviderInterface
{
if (!isset($this->embeddingsProvider)) {
$this->transcribeProvider = $this->transcribe();
}
return $this->transcribeProvider;
}
}
30 changes: 30 additions & 0 deletions src/Transcribe/Transcribe.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace NeuronAI\Transcribe;

use NeuronAI\Agent\Agent;
use NeuronAI\Chat\Enums\SourceType;
use NeuronAI\Chat\Messages\ContentBlocks\AudioContent;
use NeuronAI\Exceptions\ContentBlocksException;

class Transcribe extends Agent
{
use ResolveTranscribeProvider;

/**
* [Source audio] Speech to text.
*
* @param AudioContent $audio
* @return string
* @throws ContentBlocksException
*/
public function transcribeAudio(AudioContent $audio): string
{
if ($audio->sourceType->value === SourceType::URL) {
return $this->resolveTranscribeProvider()->trascribe($audio->source);
}
throw new ContentBlocksException('Unsupported audio source');
}
}
10 changes: 10 additions & 0 deletions src/Transcribe/TranscribeProviderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace NeuronAI\Transcribe;

interface TranscribeProviderInterface
{
public function trascribe(string $filePath): string;
}
Loading