Skip to content
6 changes: 5 additions & 1 deletion src/Contracts/Gateway/EmbeddingGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
namespace Laravel\Ai\Contracts\Gateway;

use Laravel\Ai\Contracts\Providers\EmbeddingProvider;
use Laravel\Ai\Files\Audio;
use Laravel\Ai\Files\Document;
use Laravel\Ai\Files\Image;
use Laravel\Ai\Files\Video;
use Laravel\Ai\Responses\EmbeddingsResponse;

interface EmbeddingGateway
{
/**
* Generate embedding vectors representing the given inputs.
*
* @param string[] $inputs
* @param array<int, string|Audio|Document|Image|Video> $inputs
*/
public function generateEmbeddings(EmbeddingProvider $provider, string $model, array $inputs, int $dimensions, int $timeout = 30): EmbeddingsResponse;
}
6 changes: 5 additions & 1 deletion src/Contracts/Providers/EmbeddingProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
namespace Laravel\Ai\Contracts\Providers;

use Laravel\Ai\Contracts\Gateway\EmbeddingGateway;
use Laravel\Ai\Files\Audio;
use Laravel\Ai\Files\Document;
use Laravel\Ai\Files\Image;
use Laravel\Ai\Files\Video;
use Laravel\Ai\Responses\EmbeddingsResponse;

interface EmbeddingProvider
{
/**
* Get embedding vectors representing the given inputs.
*
* @param string[] $inputs
* @param array<int, string|Audio|Document|Image|Video> $inputs
*/
public function embeddings(array $inputs, ?int $dimensions = null, ?string $model = null, int $timeout = 30): EmbeddingsResponse;

Expand Down
6 changes: 5 additions & 1 deletion src/Embeddings.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
namespace Laravel\Ai;

use Closure;
use Laravel\Ai\Files\Audio;
use Laravel\Ai\Files\Document;
use Laravel\Ai\Files\Image;
use Laravel\Ai\Files\Video;
use Laravel\Ai\Gateway\FakeEmbeddingGateway;
use Laravel\Ai\PendingResponses\PendingEmbeddingsGeneration;

Expand All @@ -11,7 +15,7 @@ class Embeddings
/**
* Get embedding vectors representing the given inputs.
*
* @param string[] $inputs
* @param array<int, string|Audio|Document|Image|Video> $inputs
*/
public static function for(array $inputs): PendingEmbeddingsGeneration
{
Expand Down
60 changes: 60 additions & 0 deletions src/Files/Base64Video.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Laravel\Ai\Files;

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;
use Laravel\Ai\Contracts\Files\StorableFile;
use Laravel\Ai\Files\Concerns\CanBeUploadedToProvider;

class Base64Video extends Video implements Arrayable, JsonSerializable, StorableFile
{
use CanBeUploadedToProvider;

public function __construct(public string $base64, ?string $mimeType = null)
{
$this->mime = $mimeType;
}

/**
* Get the raw representation of the file.
*/
public function content(): string
{
return base64_decode($this->base64);
}

/**
* Get the file's MIME type.
*/
public function mimeType(): ?string
{
return $this->mime;
}

/**
* Get the instance as an array.
*/
public function toArray(): array
{
return [
'type' => 'base64-video',
'name' => $this->name(),
'base64' => $this->base64,
'mime' => $this->mime,
];
}

/**
* Get the JSON serializable representation of the instance.
*/
public function jsonSerialize(): mixed
{
return $this->toArray();
}

public function __toString(): string
{
return $this->content();
}
}
20 changes: 20 additions & 0 deletions src/Files/Concerns/HasRemoteContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ public function mimeType(): ?string
return $this->mime ?? (new Stringable($this->response()->header('Content-Type')))->before(';')->trim()->toString();
}

/**
* Get the declared MIME type without fetching the remote resource.
*/
public function declaredMimeType(): ?string
{
return $this->mime;
}

/**
* Set the file's MIME type.
*
* @return $this
*/
public function withMimeType(string $mimeType): static
{
$this->mime = $mimeType;

return $this;
}

/**
* Get the HTTP response for the remote file.
*/
Expand Down
76 changes: 76 additions & 0 deletions src/Files/LocalVideo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Laravel\Ai\Files;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Filesystem\Filesystem;
use JsonSerializable;
use Laravel\Ai\Contracts\Files\StorableFile;
use Laravel\Ai\Files\Concerns\CanBeUploadedToProvider;
use RuntimeException;

class LocalVideo extends Video implements Arrayable, JsonSerializable, StorableFile
{
use CanBeUploadedToProvider;

public function __construct(public string $path, ?string $mimeType = null)
{
$this->mime = $mimeType;
}

/**
* Get the raw representation of the file.
*/
public function content(): string
{
$content = file_get_contents($this->path);

if ($content === false) {
throw new RuntimeException("File does not exist at path [{$this->path}]");
}

return $content;
}

/**
* Get the displayable name of the file.
*/
public function name(): ?string
{
return $this->name ?? basename($this->path);
}

/**
* Get the file's MIME type.
*/
public function mimeType(): ?string
{
return $this->mime ?? ((new Filesystem)->mimeType($this->path) ?: null);
}

/**
* Get the instance as an array.
*/
public function toArray(): array
{
return [
'type' => 'local-video',
'name' => $this->name(),
'path' => $this->path,
'mime' => $this->mime,
];
}

/**
* Get the JSON serializable representation of the instance.
*/
public function jsonSerialize(): mixed
{
return $this->toArray();
}

public function __toString(): string
{
return $this->content();
}
}
40 changes: 40 additions & 0 deletions src/Files/RemoteVideo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Laravel\Ai\Files;

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;
use Laravel\Ai\Contracts\Files\StorableFile;
use Laravel\Ai\Files\Concerns\CanBeUploadedToProvider;
use Laravel\Ai\Files\Concerns\HasRemoteContent;

class RemoteVideo extends Video implements Arrayable, JsonSerializable, StorableFile
{
use CanBeUploadedToProvider, HasRemoteContent;

public function __construct(public string $url, ?string $mimeType = null)
{
$this->mime = $mimeType;
}

/**
* Get the instance as an array.
*/
public function toArray(): array
{
return [
'type' => 'remote-video',
'name' => $this->name(),
'url' => $this->url,
'mime' => $this->mime,
];
}

/**
* Get the JSON serializable representation of the instance.
*/
public function jsonSerialize(): mixed
{
return $this->toArray();
}
}
68 changes: 68 additions & 0 deletions src/Files/StoredVideo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Laravel\Ai\Files;

use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Facades\Storage;
use JsonSerializable;
use Laravel\Ai\Contracts\Files\StorableFile;
use Laravel\Ai\Files\Concerns\CanBeUploadedToProvider;
use RuntimeException;

class StoredVideo extends Video implements Arrayable, JsonSerializable, StorableFile
{
use CanBeUploadedToProvider;

public function __construct(public string $path, public ?string $disk = null) {}

/**
* Get the raw representation of the file.
*/
public function content(): string
{
return Storage::disk($this->disk)->get($this->path) ??
throw new RuntimeException('File ['.$this->path.'] does not exist on disk ['.$this->disk.'].');
}

/**
* Get the displayable name of the file.
*/
public function name(): ?string
{
return $this->name ?? basename($this->path);
}

/**
* Get the file's MIME type.
*/
public function mimeType(): ?string
{
return $this->mime ?? (Storage::disk($this->disk)->mimeType($this->path) ?: null);
}

/**
* Get the instance as an array.
*/
public function toArray(): array
{
return [
'type' => 'stored-video',
'name' => $this->name(),
'path' => $this->path,
'disk' => $this->disk ?? config('filesystems.default'),
];
}

/**
* Get the JSON serializable representation of the instance.
*/
public function jsonSerialize(): mixed
{
return $this->toArray();
}

public function __toString(): string
{
return $this->content();
}
}
51 changes: 51 additions & 0 deletions src/Files/Video.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Laravel\Ai\Files;

use Illuminate\Http\UploadedFile;

abstract class Video extends File
{
/**
* Create a new video from Base64 data.
*/
public static function fromBase64(string $base64, ?string $mimeType = null): Base64Video
{
return new Base64Video($base64, $mimeType);
}

/**
* Create a new video using the video at the given path.
*/
public static function fromPath(string $path, ?string $mimeType = null): LocalVideo
{
return new LocalVideo($path, $mimeType);
}

/**
* Create a new remote video using the video at the given URL.
*/
public static function fromUrl(string $url, ?string $mimeType = null): RemoteVideo
{
return new RemoteVideo($url, $mimeType);
}

/**
* Create a new stored video using the video at the given path on the given disk.
*/
public static function fromStorage(string $path, ?string $disk = null): StoredVideo
{
return new StoredVideo($path, $disk);
}

/**
* Create a new Base64 video using the given file upload.
*/
public static function fromUpload(UploadedFile $file, ?string $mimeType = null): Base64Video
{
return (new Base64Video(
base64_encode($file->getContent()),
$mimeType ?? $file->getClientMimeType(),
))->as($file->getClientOriginalName());
}
}
Loading