improve interacting with ollama api and models
This commit is contained in:
@@ -8,16 +8,8 @@ use Laravel\Ai\Embeddings;
|
||||
use Laravel\Ai\Prompts\EmbeddingsPrompt;
|
||||
use Livewire\Livewire;
|
||||
|
||||
beforeEach(function () {
|
||||
config([
|
||||
'ai.default_for_embeddings' => 'ollama',
|
||||
'ai.providers.ollama.url' => 'http://ollama.test',
|
||||
'ai.providers.ollama.models.embeddings.default' => 'test-embed',
|
||||
'ai.providers.ollama.models.embeddings.available' => ['test-embed'],
|
||||
'ai.providers.ollama.models.embeddings.dimensions' => 3,
|
||||
]);
|
||||
|
||||
Http::preventStrayRequests();
|
||||
function fakeEmbeddingToolOllamaModels(): void
|
||||
{
|
||||
Http::fake([
|
||||
'http://ollama.test/api/tags' => Http::response([
|
||||
'models' => [
|
||||
@@ -26,6 +18,23 @@ beforeEach(function () {
|
||||
],
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
function fakeUnavailableEmbeddingToolOllama(): void
|
||||
{
|
||||
Http::fake([
|
||||
'http://ollama.test/api/tags' => Http::response(['error' => 'offline'], 500),
|
||||
]);
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
config([
|
||||
'ai.default_for_embeddings' => 'ollama',
|
||||
'ai.providers.ollama.url' => 'http://ollama.test',
|
||||
'ai.providers.ollama.models.embeddings.dimensions' => 3,
|
||||
]);
|
||||
|
||||
Http::preventStrayRequests();
|
||||
});
|
||||
|
||||
test('guests are redirected from embedding pages', function (string $route) {
|
||||
@@ -44,6 +53,8 @@ test('embeddings index redirects to embed page', function () {
|
||||
});
|
||||
|
||||
test('authenticated users can open embedding pages', function (string $route, string $text) {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$this->get(route($route))
|
||||
@@ -56,6 +67,8 @@ test('authenticated users can open embedding pages', function (string $route, st
|
||||
]);
|
||||
|
||||
test('comparison page renders separate phrase inputs', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$this->get(route('embeddings.compare'))
|
||||
@@ -67,6 +80,8 @@ test('comparison page renders separate phrase inputs', function () {
|
||||
});
|
||||
|
||||
test('comparison phrase inputs can be added and removed', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
Livewire::test('pages::embeddings.compare')
|
||||
@@ -90,6 +105,8 @@ test('app header has a menu item for each embedding tool', function () {
|
||||
});
|
||||
|
||||
test('embedding pages do not duplicate tool navigation below the header', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$response = $this->get(route('embeddings.embed'))->assertOk();
|
||||
@@ -100,6 +117,8 @@ test('embedding pages do not duplicate tool navigation below the header', functi
|
||||
});
|
||||
|
||||
test('embedding model options are fetched from ollama', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$component = Livewire::test('pages::embeddings.embed');
|
||||
@@ -110,16 +129,48 @@ test('embedding model options are fetched from ollama', function () {
|
||||
Http::assertSent(fn ($request): bool => $request->url() === 'http://ollama.test/api/tags');
|
||||
});
|
||||
|
||||
test('first ollama model is selected when configured default is unavailable', function () {
|
||||
config(['ai.providers.ollama.models.embeddings.default' => 'missing-default']);
|
||||
test('first ollama model is selected from the api model list', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
Livewire::test('pages::embeddings.embed')
|
||||
->assertSet('ollamaAvailable', true)
|
||||
->assertSet('embeddingModel', 'test-embed');
|
||||
});
|
||||
|
||||
test('embedding pages show when ollama is unavailable', function () {
|
||||
fakeUnavailableEmbeddingToolOllama();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
Livewire::test('pages::embeddings.embed')
|
||||
->assertSet('ollamaAvailable', false)
|
||||
->assertSet('embeddingModel', '')
|
||||
->assertSee(__('Ollama is unavailable'))
|
||||
->assertSee(__('Ollama offline'));
|
||||
});
|
||||
|
||||
test('embedding actions stop when ollama model list is unavailable', function () {
|
||||
fakeUnavailableEmbeddingToolOllama();
|
||||
|
||||
Embeddings::fake();
|
||||
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
Livewire::test('pages::embeddings.embed')
|
||||
->set('embeddingInput', 'apple')
|
||||
->call('generateEmbeddings')
|
||||
->assertHasErrors('embeddingModel');
|
||||
|
||||
expect(EmbeddingEntry::query()->count())->toBe(0);
|
||||
|
||||
Embeddings::assertNothingGenerated();
|
||||
});
|
||||
|
||||
test('phrases can be embedded and stored', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
Embeddings::fake([
|
||||
[
|
||||
[1, 0, 0],
|
||||
@@ -155,6 +206,8 @@ test('phrases can be embedded and stored', function () {
|
||||
});
|
||||
|
||||
test('similarity search ranks stored embeddings', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
Embeddings::fake([
|
||||
[
|
||||
[1, 0, 0],
|
||||
@@ -196,6 +249,8 @@ test('similarity search ranks stored embeddings', function () {
|
||||
});
|
||||
|
||||
test('comparison builds a pairwise similarity matrix', function () {
|
||||
fakeEmbeddingToolOllamaModels();
|
||||
|
||||
Embeddings::fake([
|
||||
[
|
||||
[1, 0, 0],
|
||||
|
||||
Reference in New Issue
Block a user